Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NginX trailing slash in proxy pass url

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; } 
like image 687
Pratyay Modi Avatar asked Mar 31 '14 10:03

Pratyay Modi


Video Answer


2 Answers

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.

like image 86
Alexey Ten Avatar answered Sep 30 '22 15:09

Alexey Ten


You might add these lines:

proxy_redirect off; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 

Example, I proxy public port 80 to local port 880

location / {             proxy_redirect off;             proxy_set_header Host $http_host;             proxy_set_header X-Forwarded-Host $http_host;             proxy_set_header X-Real-IP $remote_addr;             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;             proxy_connect_timeout 90;             proxy_send_timeout 90;             proxy_read_timeout 90;             proxy_buffer_size 16k;             proxy_buffers 32 8k;             proxy_busy_buffers_size 64k;              proxy_pass   http://127.0.0.1:880/;     } 

Note: Make sure to restart nginx. You might need to use another browser to test the new configuration (avoid cache)

like image 42
Dylan B Avatar answered Sep 30 '22 15:09

Dylan B