I need to write an nginx location directive to proxy requests to subdirectory to another server preserving urlencoding and removing subdirectory pre
But there is no easy way to fix this nginx behaviour. There are some bugs in nginx trac, you could add yours. trac.nginx.org/nginx/…. So, I think that the simplest way is to have subdomain. – Alexey Ten Feb 24 '15 at 14:49
https://trac.nginx.org/nginx/ticket/727
If you want nginx to do something custom, you can do so using proxy_pass with variables (and the $request_uri variable, which contains original unescaped request URI as sent by a client). In this case it will be your responsibility to do correct URI transformations. Note though that this can easily cause security issues and should be done with care.
Challenge accepted!
location /api/ {
rewrite ^ $request_uri;
rewrite ^/api/(.*) $1 break;
return 400;
proxy_pass http://127.0.0.1:82/$uri;
}
That's it, folks!
Here's for the full proof.
The config file for nginx/1.2.1
:
server {
listen 81;
#first, the solution
location /api/ {
rewrite ^ $request_uri;
rewrite ^/api/(.*) $1 break;
return 400; #if the second rewrite won't match
proxy_pass http://127.0.0.1:82/$uri;
}
#next, a few control groups
location /dec/ {
proxy_pass http://127.0.0.1:82/;
}
location /mec/ {
rewrite ^/mec(/.*) $1 break;
proxy_pass http://127.0.0.1:82;
}
location /nod/ {
proxy_pass http://127.0.0.1:82;
}
}
server {
listen 82;
return 200 $request_uri\n;
}
Here are the results of running the queries for each location:
% echo localhost:81/{api,dec,mec,nod}/save/http%3A%2F%2Fexample.com | xargs -n1 curl
/save/http%3A%2F%2Fexample.com
/save/http:/example.com
/save/http:/example.com
/nod/save/http%3A%2F%2Fexample.com
%
Note that having that extra return 400;
is quite important — otherwise, you risk having a security issue (file access through //api
etc), as Maxim has briefly mentioned in your trac ticket.
P.S. If you think using the rewrite engine as a finite-state automaton is super cool, you might also want check out my http://mdoc.su/ project, or fork it github.