Я часто работаю с туннелированными портами, где я SSH перенаправляю удаленный порт 80 на локальный порт 8080.
Одна из интересных проблем, с которыми я сталкиваюсь, заключается в том, что когда у меня есть такое правило в NGINX:
rewrite ^/(.+)/$ /$1 permanent;
Перезапись примет запрос, который выглядит следующим образом:
curl -is -X GET http://localhost:8080/one/two/three/
И перенаправьте его на такой URL:
http://localhost/one/two/three
Он удаляет порт из заголовка хоста, и меня перенаправляют на порт 80, который не связан и что-то ломает.
Могу ли я настроить NGINX на уважение порта хоста (как указано в заголовке хоста) при перенаправлении?
Как видно из заголовков запроса, заголовок Host включает порт, и я бы хотел, чтобы NGINX использовал это значение для всех перенаправлений, чтобы сохранить исходный порт, который клиент использовал для доступа к серверу.
Конфигурация моего сайта NGINX выглядит так:
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;
}
Точные шаги по воспроизведению выглядят так:
$ 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>
Я не уверен, почему он перенаправляет, чтобы добавить косую черту в первую очередь, но перенаправление ломает все.
Я исправил проблему интересным способом, который сразу не имеет для меня смысла. Кажется, что try_files
все портит, поэтому я сделал следующее в своей конфигурации, чтобы все работало:
server {
listen *:80;
server_name _;
port_in_redirect on;
server_name_in_redirect off;
index index.html index.htm index.php;
access_log /var/log/nginx/default.access.log combined;
error_log /var/log/nginx/default.error.log;
location / {
rewrite ^/(.+)/+$ $scheme://$http_host/$1 permanent;
root /vagrant/_site;
index index.html index.htm index.php;
try_files $uri $uri/index.html $uri/ =404;
}
}
Моя цель, если не сразу ясно, - чтобы сообщения не заканчивались косой чертой.
Моя фактическая структура обслуживаемых каталогов выглядит так:
/vagrant/_site/2015/
`-- 08
`-- from-hell-flying-united-airlines
`-- index.html
Поэтому я говорю NGINX, что для каждого запроса я хочу, чтобы он пытался найти файл в $uri
, $uri/index.html
, и $uri/
. Если ничего из этого не работает, верните 404.