Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: strange redirect
On Mon, Feb 25, 2008 at 03:40:20PM -0800, Konstantin Svist wrote:
> Igor Sysoev wrote:
> >On Thu, Feb 21, 2008 at 03:05:26PM -0800, Konstantin Svist wrote:
> >
> >
> >>Прошу прощения что продолжаю Вас отвлекать на эту тему, но хочется в
> >>голове всё уложить по порядку :)
> >>
> >>
> >>http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23
> >>говорит что "Host" - это domain/port сервера который запрашивается (что
> >>необходимо если сервер виртуальный)
> >>
> >>Почему, тогда, этот заголовок изменяется по умолчанию -- и почему только
> >>после этого его всё работает?
> >>
> >
> >По умолчанию он изменяется на $proxy_host, потому что это именно то, что
> >удалённый сервер обычно ожидает увидеть.
>
> Но всегда-ли "удалённый" сервер ожидает $proxy_host? Какие по этому делу
> правила?
Удалённый сервер, находящийся вне контроля, не подозревает, что кто-то
может его реверсивно проксировать под каким-то другим именем. Поэтому
стоит обращаться к нему так, как если бы к нему ходили напрямую.
> У меня стоит Cherrypy (cherrypy.org) и если я оставляю HOST как
> $proxy_host, он не может правильно сделать редирект. Он ожидает '/' на
> конце URL-а, и если того не указать, он посылает редирект на себя+'/'
Это регулируется директивой
http://sysoev.ru/nginx/docs/http/ngx_http_proxy_module.html#proxy_redirect
> Пример #1:
> Интернет --> порт 80 (брандмауэр) --> 1080 (nginx) --> 8080 (cherrypy,
> внутренний сервер)
> Страница http://example.com/foo/
> Запрос http://example.com/foo -- без '/'
>
> - proxy_set_header HOST $proxy_host;
> ответ: 302 http://example.com:1080/foo/
> ... страница, естественно, не доступна (т.к. 1080 за брандмауэром)
>
> - proxy_set_header HOST $http_host;
> ответ: 302 http://example.com/foo/
> ... вроде работает
>
> - proxy_set_header HOST $host;
> ответ: 302 http://example.com/foo/
> ... вроде работает
>
Потому что cherrypy подконтроллен, и настроен на обслуживание example.com.
> Если бы всё работало, хрен бы с ним.. но вот дальше проблемы:
>
>
>
>
> Пример #2:
> Интернет --> порт 80 (брандмауэр) --> 1081 (nginx) -->
> rsportscars.com:80 (удалённый сервер, через интернет)
> Страница/запрос: http://rsportscars.example.com/
>
> - proxy_set_header HOST $proxy_host;
> ответ: 200
> ... работает
>
> - proxy_set_header HOST $http_host;
> 301 http://rsportscars.example.com:1081/
> ... страница не доступна (1081 за брандмауэром)
>
> - proxy_set_header HOST $host;
> 301 http://rsportscars.example.com:1081/
> ... страница не доступна (1081 за брандмауэром)
>
>
>
> Почему это происходит?
Потому что www.rsportscars.com не любит, что бы к нему ходили под
чужими именами (см. выше):
>nc www.rsportscars.com 80
GET / HTTP/1.0
Host: rsportscars.example.com
HTTP/1.1 301 Moved Permanently
Connection: close
Date: Tue, 26 Feb 2008 06:14:02 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Location: http://www.rsportscars.com/
Cache-Control: private
Content-Type: text/html
nginx переписывает
Location: http://www.rsportscars.com/
в
Location: http://rsportscars.example.com:1081/
Если поставить "port_in_redirect off", то будет
Location: http://rsportscars.example.com/
что приведёт к циклу, так как www.rsportscars.com будет всё время
возвращать редирект, который будет переписываться
в http://rsportscars.example.com/
Для второго случая нужно ставить:
proxy_set_header HOST $proxy_host;
port_in_redirect off;
proxy_redirect default; # default
--
Игорь Сысоев
http://sysoev.ru
|