strange redirect

Igor Sysoev is at rambler-co.ru
Tue Feb 26 09:24:09 MSK 2008


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





More information about the nginx-ru mailing list