根据请求方法进行 Nginx 代理

根据请求方法进行 Nginx 代理

是否有可能/如何配置 Nginx 位置块以根据请求方法(即 GET/POST)代理到不同的后端?

原因是,我目前正在 2 个不同的 URL 上处理这 2 种方法(一个通过 http 代理,另一个通过 fcgi),并试图使其更加“REST”,因此,理想情况下希望 GET 资源返回列表,而 POST 到同一资源应该添加到列表中。

答案1

我没有使用这个配置,但是基于这里的例子

location /service  {
  if ($request_method = POST ) {
    fastcgi_pass 127.0.0.1:1234;
  }

  if ($request_method = GET ) {
     alias /path/to/files;
  }
}

如果你编写自己的应用程序,你也可以考虑检查其中的 GET/POST,然后发送X-Accel-重定向标头将文件传输交给 nginx。

答案2

虽然你可以用来实现这一点if,但这通常是Nginx 文档令人沮丧,因为if与其他指令配合不好。例如,假设 GET 应该对所有人开放,而 POST 仅对使用 HTTP Basic Auth 的经过身份验证的用户开放。这需要if与 结合使用auth_basic,但无法正常工作。

这是一个不使用 的替代方法if。诀窍是使用“GET”和“POST”作为上游名称的一部分,因此可以通过变量替换来解决这些问题:

http {
  upstream other_GET {
    server ...;
  }
  upstream other_POST {
    server ...;
  }
  server {
    location /service {
      proxy_pass http://other_$request_method;
    }
  }
}

要将其与 HTTP Basic Auth 结合使用(GET 除外),只需添加limit_except堵塞:

  ...
    location /service {
      proxy_pass http://other_$request_method;
      limit_except GET {
        auth_basic ...;
      }
    }
  ...

答案3

我无法让@timmmmmy 的答案起作用,但它指引我找到地图文档这对我有用:

map $request_method $upstream_location {
   PUT     example.com:8081;
   POST    example.com:8081;
   PATCH   example.com:8081;
   default example.com:8082;
}
server {
   location / {
      proxy_pass https://$upstream_location;
   }
}

答案4

对 vog 的答案进行轻微修改,以包含其他方法(如 OPTIONS、PUT 等)的默认处理程序。

    upstream webdav_default {
            server example.com;
    }
    upstream webdav_upload {
            server example.com:8081;
    }
    upstream webdav_download {
            server example.com:8082;
    }
    server {
            map upstream_location $request_method {
                    GET     webdav_download;
                    HEAD    webdav_download;
                    PUT     webdav_upload;
                    LOCK    webdav_upload;
                    default webdav_default;
            }
            location / {
                    proxy_pass https://$upstream_location;
            }
    }

相关内容