NginX trailing slash in proxy pass url

Pratyay Modi picture Pratyay Modi · Mar 31, 2014 · Viewed 49k times · Source

I know that this question has been asked multiple times but after a trying a lot of solutions I am still stuck.

I am using NginX to proxy pass to a NodeJs application. I'm trying to make url https://example.com proxy pass the request to http://example.com:8080/?

Requests (from a mobile app) are requesting https://example.com// which nginx is making http://example.com:8080//? which is not working.

Things I have tried which haven't worked:

  • merge_slashes on; (which is on by default)
  • rewrite ^/(.*)/$ /$1 permanent;
  • port_in_redirect off;

My nginx config:

location = /a {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_read_timeout 300;
}

location ^~ /a/ {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_read_timeout 300;
}

Answer

Alexey Ten picture Alexey Ten · Mar 31, 2014

I guess you use proxy_pass without URI. In that case nginx pass original URI as it was, not normalized one. So you should use proxy_pass http://backend/;

UPDATE

So I was right. Just add URI part to proxy_pass like this:

location = /a {
    proxy_pass http://127.0.0.1:8080/a;
    ...
}

location ^~ /a/ {
    proxy_pass http://127.0.0.1:8080/a/;
    ...
}

As stated in nginx documentation if proxy_pass used without URI (i.e. without path after server:port) nginx will put URI from original request exactly as it was with all double slashes, ../ and so on.

On the other side, URI in proxy_pass acts like alias directive, means nginx will replace part that matches location prefix (in out case it's /a in first location and /a/ is second) with URI in proxy_pass directive (which I intentionally made the same as location prefix) so URI will be the same as requested but normalized (without doule slashes and all that staff). Be careful with trailing slashes. Nginx replaces part literally and you could end up with some strange url.

Here is an example with trailing slash in location, but no trailig slash in proxy_pass.

location /one/ {
    proxy_pass http://127.0.0.1:8080/two;
    ...
}

if one go to address http://yourserver.com/one/path/here?param=1 nginx will proxy request to http://127.0.0.1/twopath/here?param=1. See how two and path concatenates.