ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 


  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА












     АРХИВ :: nginx-ru
Nginx-ru mailing list archive (nginx-ru@sysoev.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: proxy cache key и fastcgi cache key



On 11.01.2014 0:17, Валентин Бартенев wrote:

Кому интересно почитать, подробней вот ссылка.
http://habrahabr.ru/post/166855/
...
$host
in this order of precedence: host name from the request line, or host
name from the ?Host? request header field, or the server name matching a
request
...
Единственный правильный способ: пойти в IETF с предложением исправить
соответствующие RFC, которые в том числе оговаривают, что следует делать
при получении нескольких заголовков Host, ну а потом уже сюда.

с RFC то как раз все в порядке: "network location of the URI
(authority) MUST be transmitted in a Host header field",
только вот nginx не соответствует этим требованиям...

http://tools.ietf.org/search/rfc2616#section-5.1.2
...
Если почитать внимательнее, то приведенные требования относятся к клиенту.
Понятно, что сервер в принципе не может влиять на то, что transmitted в
запросе.

nginx выступает в роли сервера только в том случае,
когда он самостоятельно обслуживает клиентский запос.

В тот момент, когда nginx делает http запрос к удаленному
серверу он выступает в роли клиента. поэтому я и цитировал 5.1.2

а дальше, получив ответ от удаленного сервера он с этим ответом
делает разные интересные вещи, например, сканирует его на предмет
ssi-директив, или пропускает через свои sub/addition/и т.п. модули.
и то, что получится в результате - складывает в файл кеша на диске,
и после дополнительной цепочки преобразований - отправляет то,
что получилось в результате как ответ на запрос своего клиента.

например, если исходный запрос от клиента к nginx был

GET http://good-site.com/pub/WWW/TheProject.html HTTP/1.1
Host: bad-site.com

содержимое заголовка Host: согласно 5.2.1 должно игнорироваться,
адрес хоста в этом случае: good-site.com

а согласно требований 5.1.2 - network location of the URI (authority) MUST be transmitted in a Host header field, то есть исходящий запрос
должен быть

GET /pub/WWW/TheProject.html HTTP/1.1
Host: good-site.com

nginx же в настройке по-умолчанию не соответсвует RFC,
и вместо требуемого значения пишет в заголовок Host:
значение переменной $proxy_host

Теперь рассмотрим вариант связи с backend`ом по протоколу FastCGI,
но поскольку у нас большой и сложный сайт сделаем два фронтенда:

1) основной nginx frontend
2) nginx frontend на хосте backend`а
3) backend, работающий по протоколу FastCGI.

запрос от клиента проходит цепочку (1)->(2)->(3).
поскольку между (1) и (2) используется протокол http,
то согласно требований 5.1.2 и 5.2.1 на (2) запрос приходит
в виде

GET /pub/WWW/TheProject.html HTTP/1.1
Host: good-site.com

не смотря на то, что в исходном запросе
от клиента был игнорируемый заголовок Host: bad-site.com

а дальше - все просто. В соответствии с требованиями
спецификации протокола FastCGI - nginx записывает в переменную
HTTP_HOST значение good-site.com.

точнее, он ДОЛЖЕН так делать, согласно требований HTTP протокола
прямо из коробки, без какой-либо дополнительной настройки.

Эта схема работает одинаково вне зависимости от количества
промежуточных серверов между nginx frontend и backend.

точнее, ДОЛЖНА работать одинаково,
вне зависимости от количества промежуточных серверов.

если в случае отсутствия промежуточных серверов nginx ведет себя
не так, - то это BUG, ибо в случае, когда на nginx frontend
приходит запрос в виде absoluteURI, - тогда "Any Host header
field value in the request MUST be ignored".
nginx этого по каким-то причинам не делает.

хотя согласно требований RFC - обе эти формы записи:

GET http://good-site.com/pub/WWW/TheProject.html HTTP/1.1

и

GET /pub/WWW/TheProject.html HTTP/1.1
Host: good-site.com

полностью эквивалентны между собой. и nginx имеет
полное право и даже обязанность трансформировать
запрос с absoluteURI в запрос с relativeURI
и network location of the URI (authority)
MUST be transmitted in a Host header field.

=============================================================

Что касается сервера, написано буквально секцией ниже:
http://tools.ietf.org/search/rfc2616#section-5.2

5.2 The Resource Identified by a Request

    The exact resource identified by an Internet request is determined by
    examining both the Request-URI and the Host header field.

    An origin server that does not allow resources to differ by the
    requested host MAY ignore the Host header field value when
    determining the resource identified by an HTTP/1.1 request. (But see
    section 19.6.1.1 for other requirements on Host support in HTTP/1.1.)

    An origin server that does differentiate resources based on the host
    requested (sometimes referred to as virtual hosts or vanity host
    names) MUST use the following rules for determining the requested
    resource on an HTTP/1.1 request:

    1. If Request-URI is an absoluteURI, the host is part of the
      Request-URI. Any Host header field value in the request MUST be
      ignored.

    2. If the Request-URI is not an absoluteURI, and the request includes
      a Host header field, the host is determined by the Host header
      field value.

    3. If the host as determined by rule 1 or 2 is not a valid host on
      the server, the response MUST be a 400 (Bad Request) error message.

    Recipients of an HTTP/1.0 request that lacks a Host header field MAY
    attempt to use heuristics (e.g., examination of the URI path for
    something unique to a particular host) in order to determine what
    exact resource is being requested.

Ровным счетом так nginx и поступает, если передан absoluteURI, то виртуальный
сервер определяется по нему, а заголовок Host игнорируется.

Та часть nginx, которая работает в режиме сервера определяет Host
правильно. И правильно сохранет его в свою переменную $host.

Но дальше в нарушение RFC вместо $host зачем-то используется $http_host
не смотря на прямой запрет: Any Host header field value in the request MUST be ignored.

А несоответствие требованиям RFC 2616 - это ведь BUG, верно?

--
Best regards,
 Gena

_______________________________________________
nginx-ru mailing list
nginx-ru@xxxxxxxxx
http://mailman.nginx.org/mailman/listinfo/nginx-ru


 




Copyright © Lexa Software, 1996-2009.