요청 방법에 의한 Nginx 프록시


17

요청 방법 (예 : GET / POST)에 따라 다른 백엔드로 프록시하도록 Nginx 위치 블록을 구성하는 방법은 무엇입니까?

그 이유는 현재 2 개의 다른 URL (하나는 http 프록시를 통해 다른 하나는 fcgi를 통해)에서 2 가지 방법을 처리하고 있으며 더 "REST"풀리게하려고 노력하고 있기 때문에 리소스를 가져 와서 목록을 반환하는 것이 이상적입니다 동일한 리소스에 POST하는 동안 목록에 추가되어야합니다.

답변:


27

이 구성을 사용하지 않지만 여기 예제를 기반으로합니다 .

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

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

자신의 응용 프로그램을 작성하는 경우 GET / POST를 확인 하고 파일 전송을 nginx로 전달하기 위해 X-Accel-Redirect 헤더를 보내는 것을 고려할 수도 있습니다 .


GET 블록은 필자의 경우 proxy_pass이지만 그렇지 않으면 작동합니다. 두 번째 if 블록을 사용하지 않는 순간 , fastcgi_pass 지시문에 도달하면 (즉, 프록시 패스를 통과하지 않고 프록시 패스도 실행하지 않음) POST 이외의 다른 항목을 되돌리기를 원하기 때문에 nginx "프로세싱"을 중지하는 것처럼 보입니다 . 프록시에.
Brenton Alker

2
참고 if일반적으로 Nginx의 문서에 의해 권장하지 않습니다 : nginx.com/resources/wiki/start/topics/depth/ifisevil
VOG

1
그렇다면 대안은 무엇입니까?
WM

1

@vog, 흥미 롭습니다. 똑똑한 방법입니다. 공유해 주셔서 감사합니다.
WM

23

으로이 작업을 수행 할 수 있지만 if일반적으로 Nginx 설명서 에서는 권장if 하지 않습니다. 다른 지시어와 잘 작동하지 않기 때문 입니다. 예를 들어, 모든 사람이 GET을 열어야하고 POST는 HTTP 기본 인증을 사용하는 인증 된 사용자만을위한 것이라고 가정하십시오. 제대로 작동하지 if않는와 결합 해야 합니다 auth_basic.

없이 작동하는 대안이 있습니다 if. 트릭은 업스트림 이름의 일부로 "GET"및 "POST"를 사용하는 것이므로 변수 대체를 통해이를 해결할 수 있습니다.

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

GET 이외의 모든 것에 대해 이것을 HTTP 기본 인증과 결합하려면 limit_except블록을 추가하십시오 .

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

이 접근 방식의 문제점은 이제 (또는 누락 된 업스트림이 무엇이든) 502 gateway error인해 돌아올 것 no resolver defined to resolve other_HEAD입니다. 와 같은 것을 반환하는 것이 더 의미가 있습니다 405 method not allowed. 이것을 달성 할 수있는 방법이 있습니까?
제임스

1
@ 제임스 : 이것은 아마도 이것을 새로운 질문으로 표현할 수도 있습니다. 나는이 세부 사항에 대한 대답이 없지만 다른 사람들에게는 대답 할 수 없습니다.
vog

0

이것이 내가 일을하기 위해 내가 한 일입니다.

add_header Allow "GET, POST, HEAD" always;
if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
    proxy_pass http://back-end;
}

Hoe는 정확히 요청 방법에 따라 두 끝점 사이를 전환합니까?
기본

0

OPTIONS, PUT 등과 같은 다른 메소드에 대한 기본 핸들러를 포함하도록 vog의 답변으로 약간 변경되었습니다.

    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;
            }
    }

0

@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;
   }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.