I'm often working with tunneled ports where I'll SSH forward a remote port 80 to a local port 8080.
One of the interesting problems I run into is that when I have a rule like this in NGINX:
rewrite ^/(.+)/$ /$1 permanent;
The rewrite will take a request that looks like this:
curl -is -X GET http://localhost:8080/one/two/three/
And redirect it to a URL like this:
http://localhost/one/two/three
It strips the port from the host header and I get redirected to port 80, which is unbound and breaks things.
Can I configure NGINX to respect the host port (as present in the Host header) when doing redirects?
As can be seen in the request headers, the Host header includes the port and I'd like NGINX to use this value for all redirects to maintain the original port the client used to access the server.
My NGINX site config looks like this:
server {
listen *:80;
server_name _;
index index.html index.htm;
access_log /var/log/nginx/default.access.log combined;
error_log /var/log/nginx/default.error.log;
location / {
root /vagrant/_site;
index index.html index.htm index.php;
try_files $uri $uri.html $uri/ =404;
}
port_in_redirect on;
server_name_in_redirect off;
}
The exact steps to reproduce look like this:
$ curl -is http://localhost:8080/2015/08/from-hell-flying-united-airlines
HTTP/1.1 301 Moved Permanently
Server: nginx/1.8.0
Date: Wed, 02 Sep 2015 19:43:10 GMT
Content-Type: text/html
Content-Length: 184
Location: http://localhost/2015/08/from-hell-flying-united-airlines/
Connection: keep-alive
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.8.0</center>
</body>
</html>
I'm not sure why it's redirecting to append a slash in the first place, but the redirect is breaking everything.
I fixed the issue in an interesting way that doesn't immediately make sense to me. It seems that
try_files
is messing things up, so I did the following to my config to make everything work:My goal, if not immediately clear, is to have posts not end in a slash.
My actual served directory structure looks like this:
Therefore, I tell NGINX that for every request, I want it to try locating a file at
$uri
,$uri/index.html
, and$uri/
. If none of these things work, return a 404.