nginx 프록시에서 URL 디코딩 비활성화 응용 프로그램을 프록시 할

이 URL을 탐색하면 http://localhost:8080/foo/%5B-%5Dserver ( nc -l 8080)는 그대로 수신합니다.

GET /foo/%5B-%5D HTTP/1.1

그러나 nginx (1.1.19)를 통해이 응용 프로그램을 프록시 할 때 :

location /foo {
        proxy_pass    http://localhost:8080/foo;
}

nginx 포트를 통해 라우팅 된 동일한 요청이 경로 디코딩 된 상태로 전달됩니다.

GET /foo/[-] HTTP/1.1

GET 경로의 디코드 된 대괄호는 이스케이프되지 않은 도착시 대상 서버 ( HTTP 상태 400-경로의 잘못된 문자 … ) 에서 오류를 발생시킵니다 .

URL 디코딩을 비활성화하거나 다시 인코딩하여 대상 서버가 nginx를 통해 라우팅 될 때 정확히 동일한 경로를 얻도록하는 방법이 있습니까? 영리한 URL 다시 쓰기 규칙?



답변

Valentin V. Bartenev 인용 (이 답변에 대한 전체 크레딧을 받아야하는 사람) :

문서 에서 인용 :

  • proxy_pass 를 URI 로 지정 하면 요청을 서버에 전달할 때 위치와 일치 하는 정규화 된 요청 URI의 일부가 지시문에 지정된 URI로 바뀝니다.

  • 경우에 proxy_pass지정된 URI 않고 원래의 요청을 처리 할 때, 클라이언트에 의해 전송 된 바와 같이, 요청 URI는 동일한 형태로 서버에 전달

귀하의 경우 올바른 구성은 다음과 같습니다.

location /foo {
   proxy_pass http://localhost:8080;
}

답변

nginx 문서에서 일반적으로 $uri“정규화” 라고 알려진 URL 디코딩 은 백엔드 IFF 전에 발생합니다.

  • proxy_pass후행 슬래시만으로도 모든 URI가 자체적 으로 지정 됩니다.

  • 또는, 처리 동안, 예를 들어를 통해 URI가 변경된다 rewrite.


두 조건은 http://nginx.org/r/proxy_pass (강조 광산)에 명시 적으로 문서화되어 있습니다 .

  • 는 IF proxy_pass지시자가 지정된 URI를 가진 후, 요청을 서버에 전달 될 때, 부분 정규화 URI가 위치 일치 요구가 URI로 대체 지시어에 지정된

  • 경우에 proxy_pass지정된 URI에없는 요청은 URI에서 서버로 전달되고 , 클라이언트에 의해 전송 된 바와 같이 동일한 형태의 원래의 요청을 처리 할 때, 또는 전체 정규화 요청 URI가 전달되는 경우 가공하는 변경 URI를


해결책은 OP의 경우와 같이 URI를 생략하거나 실제로 영리한 rewrite규칙을 사용하는 것입니다.

# map `/foo` to `/foo`:
location /foo {
    proxy_pass  http://localhost:8080;  # no URI -- not even just a slash
}

# map `/foo` to `/bar`:
location /foo {
    rewrite  ^  $request_uri;            # get original URI
    rewrite  ^/foo(/.*)  /bar$1  break;  # drop /foo, put /bar
    return 400;   # if the second rewrite won't match
    proxy_pass    http://localhost:8080$uri;
}

컨트롤 그룹을 포함하여 관련 스택 오버플로 응답에서 실시간으로 볼 수 있습니다 .