Quantcast
Channel: Nginx Forum - Nginx Mailing List - Russian
Viewing all articles
Browse latest Browse all 3102

Зацикливание на редиректе (no replies)

$
0
0
Доброго дня сообществу! Прошу совета по проблеме.
Собственно, редирект с www на https без-www

server {
    #1 http to https without www
    listen 1.2.3.4:80;
    server_name www.test.com test.com;
    rewrite ^ https://test.com$request_uri? permanent;
}

server {
    #2 https with www to https without www
    listen 1.2.3.4:443 ssl;
    server_name www.test.com;
    rewrite ^ https://test.com$request_uri? permanent;
}

server {
    #3 https without www
    listen 1.2.3.4:443 ssl;
    server_name test.com;
    ...
}

Насколько я понял из документации (http://nginx.org/ru/docs/http/ngx_http_core_module.html#var_host), переменная $host принимает значения "в порядке приоритета: имя хоста из строки запроса, или имя хоста из поля Host заголовка запроса, или имя сервера, соответствующего запросу"

Судя по логам, это не совсем так.
По крайней мере, в моем случае (nginx/1.10.2), переменная $host получает имя хоста из строки запроса только если не указано поле host заголовка. Т.е. обрабатывается ситуация с HTTP/1.0, без $http_host в заголовке. Но если в заголовке задать какое-то (любое) значение $http_host, это же значение получает и $host.

Далее (http://nginx.org/ru/docs/http/request_processing.html): nginx "сопоставляет значение поля Host заголовка запроса с директивами server_name в блоках server, которые соответствуют IP-адресу и порту". Т.е. все-таки $http_host. А туда можно прописать что угодно.
Я не рассматриваю сейчас ситуацию, когда в $http_host прописано имя, не совпадающее с перечисленными в server_name. Это все благополучно фильтруется и отправляется на 444. Также, я не рассматриваю браузеры, которые отправляют правильный $http_host и получают правильные редиректы.

Вот такой случай:
curl -ILH 'Host: www.test.com' https://test.com

Если бы переменная $host получила значение в порядке приоритета, оно было бы test.com (имя хоста из строки запроса). Тогда можно было бы реализовать такой костыль, как фильтрация по условию "$host не равно $http_host". Но в запросе присутствует заголовок host, и обе переменные $host и $http_host получают одно и то же значение www.test.com , отфильтровать невозможно.
Имя www.test.com перечислено в server_name, в итоге такой запрос успешно проходит фильтрацию. После сопоставления значения $http_host с server_name, nginx отправляет запрос в секцию 2, откуда возвращается 301 и новый location https://test.com , т.е. на выходе получаем тот же самый запрос (curl -ILH 'Host: www.test.com' https://test.com) и, естесвенно, зацикливание на второй секции:

curl -ILH 'Host: www.test.com' https://test.com
HTTP/1.1 301 Moved Permanently
..........
Location: https://test.com/

HTTP/1.1 301 Moved Permanently
..........
Location: https://test.com/

..........

Это баг или фича? Или я что-то делаю не так? Как это побороть?
Спасибо.
--_______________________________________________
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Viewing all articles
Browse latest Browse all 3102

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>