【问题标题】:How to route to content_by_lua nginx directive depending on both HTTP Action and URL prefix?如何根据 HTTP 操作和 URL 前缀路由到 content_by_lua nginx 指令?
【发布时间】:2017-10-09 13:41:49
【问题描述】:

我想默认将发送到我的 nginx 服务器的所有请求路由到我的后端应用程序,但有选择地将带有 GET HTTP 动词的 API 请求发送到由 content_by_lua nginx 指令支持的基于 OpenResty Lua 的 REST API。

我能够使用以下配置成功地将所有 API 请求基于其 URL 前缀路由到 Lua API(请注意,这不考虑 HTTP 动词):

http {
  upstream backend {
    server localhost:8080;
  }
  server {
    listen 80;

    location / {
      # Send all requests to the backend application
      proxy_pass http://backend;
      proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
      proxy_set_header   Host             $http_host;
      proxy_set_header   X-Real-IP        $remote_addr;
      proxy_set_header   CLIENT_IP $remote_addr;
      proxy_set_header   HTTP_CLIENT_IP $remote_addr;
      proxy_redirect off;
    }

    location /api {
      # Send any URL with the /api prefix to the nginx Lua API application
      content_by_lua '
        require("lapis").serve("app")
      ';
    }
  }
}

但是,如上所述,我想进一步限制 API 请求,以便使用除 GET 之外的 HTTP 动词的任何请求(如 POST、PUT、DELETE 等)仍被路由到后端,而 GET 请求单独路由到 Lua API 位置。

根据其他一些帖子、博客和文档(并听说 the if directive is frowned upon),我尝试使用 limit_except 指令,但随后 nginx 服务器在启动时崩溃,因为似乎 content_by_lua 指令不是设计的对于limit_except 块。这是我的尝试:

http {
  upstream backend {
    server localhost:8080;
  }
  server {
    listen 80;

    location / {
      proxy_pass http://backend;
      proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
      proxy_set_header   Host             $http_host;
      proxy_set_header   X-Real-IP        $remote_addr;
      proxy_set_header   CLIENT_IP $remote_addr;
      proxy_set_header   HTTP_CLIENT_IP $remote_addr;
      proxy_redirect off;
    }

    location /api {
      # Default the non-get API requests back to the backend server
      proxy_pass http://backend;
      proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
      proxy_set_header   Host             $http_host;
      proxy_set_header   X-Real-IP        $remote_addr;
      proxy_set_header   CLIENT_IP $remote_addr;
      proxy_set_header   HTTP_CLIENT_IP $remote_addr;
      proxy_redirect off;

      # Select requests that *aren't* a PUT, POST, or DELETE, and pass those to the Lapis REST API
      limit_except PUT POST DELETE {
        content_by_lua '
          require("lapis").serve("app")
        ';
      }
    }
  }
}

它立即与

崩溃
nginx: [emerg] "content_by_lua" directive is not allowed here in nginx.conf:46

在委派content_by_lua 指令时,基于 URL 前缀 HTTP 动词在 nginx 中选择性路由的最佳方法是什么?

【问题讨论】:

    标签: nginx lua openresty lapis


    【解决方案1】:

    我使用 if 指令实现了特定 URL GET 操作的条件路由,尽管根据 nginx 开发人员的说法它是邪恶的。看起来这可能是 if 指令为数不多的理想用例之一,但如果不是或有人有更好的方法,请告诉我(这就是为什么我没有接受自己的答案)。

    这里是当前实现方案的nginx配置文件:

    http {
    
      upstream backend {
        server localhost:3000;
      }
    
      server {
        listen 80;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header   Host             $http_host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   CLIENT_IP $remote_addr;
        proxy_set_header   HTTP_CLIENT_IP $remote_addr;
        proxy_redirect off;
    
        # By default pass all the requests to the Rails app backend
        location / {
          proxy_pass http://backend;
        }
    
        # Delegate certain API calls to our special OpenResty Endpoints
        location /api {
          # Makes sure all POSTs, PUTs, and DELETE actions still get handed off to the backend
          if ($request_method ~ POST|PUT|DELETE) {
            proxy_pass http://backend;
          }
          # All that should remain are the GET and OPTIONS endpoints so send them to the OpenResty Lua backend!)
          content_by_lua 'require("lapis").serve("app")';
        }
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-13
      • 2013-02-07
      • 2016-06-19
      • 1970-01-01
      • 2017-06-12
      • 2021-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多