2

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

我成功地能够使用以下配置根据 URL 前缀将所有 API 请求路由到 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 位置。

根据其他一些帖子、博客和文档(并且听说if指令不受欢迎),我尝试使用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

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

4

1 回答 1

2

我使用该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")';
    }
  }

}
于 2017-05-11T18:47:12.413 回答