Com nginx/1.2.1
, não consegui reproduzir seu problema de %20
, uma vez decodificado em um espaço, de causar qualquer 400 Bad Request
dentro do nginx; talvez seja proveniente do upstream?
Independentemente disso, na verdade não é tão difícil usar o autômato de estado finito fornecido pela diretiva rewrite
para Pare de $uri
de conter a solicitação decodificada, mas ainda assim execute todos os tipos de transformações da solicitação.
link
A ideia é que quando você altera $uri
no lugar, ele não é re-decodificado. E, como você sabe, já temos o código não codificado em $request_uri
. O que resta é simplesmente definir um para o outro e chamá-lo por um dia.
server {
listen 2012;
location /a {
rewrite ^/a(.*) /f$1 last;
}
location /i {
rewrite ^ $request_uri;
rewrite ^/i(.*) /f$1 last;
return 400; #if the second rewrite won't match
}
location /f {
set $url http://127.0.0.1:2016/s?v=h&a=$scheme://$host$uri;
proxy_pass $url;
}
}
server {
listen 2016;
return 200 $request_uri\n;
}
E, sim, a parte rewrite ^ $request_uri;
acima faz o truque:
% echo localhost:2012/{a,i,f}/h%20w | xargs -n1 curl
/s?v=h&a=http://localhost/f/h w
/s?v=h&a=http://localhost/f/h%20w
/s?v=h&a=http://localhost/f/h w
%
(Se você quiser que a coisa "direta" não seja decodificada, então provavelmente será mais fácil apenas torná-la "indireta" também.)