I am using the following configuration for nginx 1.4.1:
server { listen 8000; server_name correct.name.gr; location /test/register { proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1; } }
What I want to do is when the users vist http://correct.name.gr:8000/test/register/
they should be proxied to the apache which runs on port 80.
When I visit http://correct.name.gr:8000/test/register/
I get correct results (index.php).
When I visit http://correct.name.gr:8000/test/register/asd
I get correct results (404 from apache).
When I visit http://correct.name.gr:8000/test/asd
I get correct results (404 from nginx).
When I visit http://correct.name.gr:8000/test/register123
I get correct results (404 from apache).
The problem is when I visit http://correct.name.gr:8000/test/register
. I get a 301 response and I am redirected to http://localhost/test/register/
(notice the trailing slash and of course the 'localhost')!!!
I haven't done any other configurations to nginx to put trailing slashes or something similar. Do you know what is the problem ? I want http://correct.name.gr:8000/test/register
to work correctly by proxying to apache (or if not possible at least to issue a 404 error and not a redirect to the localhost of the user).
Update 1: I tried http://correct.name.gr:8000/test/register
from a different computer than the one with which I had the bad behavior yesterday.. Well, it worked: I just got a 301 response that pointed me to the correct http://correct.name.gr:8000/test/register/
! How is it possible to work from one computer but not from the other (I'm using the same browser-Chrome in both computers)? I will try again tomorrow to test from a third one to see the behavior.
Thank you !
My guess is that your upstream server (either apache or your script) triggered a redirect to the absolute url http://localhost/test/register/
. Because you use http://127.0.0.1
in your proxy_pass
directive, nginx doesn't find a match of the domain name and returns the Location
header as is.
I think the right solution is to NOT use absolute redirect if the redirect is to an internal url. This is always a good practice.
However, without changing upstream server, there are two quick solutions.
you can use
proxy_pass http://localhost;
This will tell nginx the domain name of upstream is localhost
. Then nginx will know to replace http://localhost
by http://correct.name.gr:8000
when it finds that part in the Location
header from upstream.
Another one is to add a proxy_redirect
line to force nginx to rewrite any location header with http://localhost/
in it.
proxy_pass http://127.0.0.1;
proxy_redirect http://localhost/ /;
I prefer to the first solution because it's simpler. There is no DNS lookup overhead of using proxy_pass http://localhost;
because nginx does the lookup in advance when it starts the web server.
reference: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect