Desabilitando a decodificação de URL no proxy nginx

19

Quando navego para este URL: http://localhost:8080/foo/%5B-%5D server ( nc -l 8080 ) recebe como está:

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

No entanto, quando eu proxy este aplicativo via nginx (1.1.19):

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

A mesma solicitação roteada pela porta nginx é encaminhada com o caminho decodificado:

GET /foo/[-] HTTP/1.1

Os colchetes decodificados no caminho GET estão causando os erros no servidor de destino ( HTTP Status 400 - Caractere ilegal no caminho ... ) à medida que eles chegam sem escape.

Existe uma maneira de desativar a decodificação de URL ou codificá-la de volta para que o servidor de destino obtenha o mesmo caminho exato quando roteado pelo nginx? Alguma regra inteligente de reescrita de URLs?

    
por Tomasz Nurkiewicz 19.12.2012 / 16:56

2 respostas

15

Citando Valentin V. Bartenev (quem deve receber todo o crédito por isso resposta):

A quote from documentation:

  • If proxy_pass is specified with URI, when passing a request to the server, part of a normalized request URI matching the location is replaced by a URI specified in the directive

  • If proxy_pass is specified without URI, a request URI is passed to the server in the same form as sent by a client when processing an original request

     

A configuração correta no seu caso seria:

location /foo {
   proxy_pass http://localhost:8080;
}
    
por 08.01.2013 / 09:22
0

Observe que a decodificação de URL, comumente conhecida como $uri "normalização" na documentação de nginx, acontece antes do IFF backend:

  • qualquer URI é especificado dentro de proxy_pass em si, mesmo que apenas a barra final por si só,

  • ou, o URI é alterado durante o processamento, por exemplo, através de rewrite .

Ambas as condições são explicitamente documentadas no link (grifo meu):

  • If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive

  • If proxy_pass is specified without a URI, the request URI is passed to the server in the same form as sent by a client when the original request is processed, or the full normalized request URI is passed when processing the changed URI

A solução é omitir o URI como no caso dos OPs ou, de fato, usar uma regra rewrite inteligente:

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

Você pode vê-la ao vivo em uma resposta relacionada ao Stack Overflow , incluindo o grupo de controle.

    
por 07.04.2018 / 00:31