Re: Документация к директиве fastcgi_cache_key
пт, 30 нояб. 2018 г. в 13:36, Илья Шипицин : > протоколы действительно разные. > но выглядит так, что предложение Гены поможет написать документацию, более > устойчивую к тупому копипасту (есть такой патерн, что глядя на пример > документации на авторитетном сайте, его копируют) > > пт, 30 нояб. 2018 г. в 14:30, Gena Makhomed : > >> On 29.11.2018 21:02, Maxim Dounin wrote: >> >> > CGI и HTTP - это два разных протокола. В последних вариациях на >> > тему спецификации CGI записано, что на HEAD-запросы тело >> > возвращать не надо (а если вдруг вернули - то сервер его должен >> > поскипать), https://tools.ietf.org/html/rfc3875#section-4.3.3: >> > >> > The HEAD method requests the script to do sufficient processing to >> > return the response header fields, without providing a response >> > message-body. The script MUST NOT provide a response message-body >> > for a HEAD request. If it does, then the server MUST discard the >> > message-body when reading the response from the script. >> > >> > Однако на момент собственно появления и активного распространения >> > CGI никаких подобных требований не существовало, см. >> > https://www.w3.org/CGI/ и в частности >> > https://tools.ietf.org/html/draft-robinson-www-interface-00. >> >> Там написано: >> >> REQUEST_METHOD >> >>This variable is specific to requests made with HTTP. >> >>The method with which the request was made, as described in >>section 5.1.1 of the HTTP/1.0 specification [3]. >> >> http-method = "GET" | "HEAD" | "POST" | extension-method >> >> "described in HTTP/1.0 specification" - написано где смотреть семантику. >> А в HTTP/1.0 specification написано, что "server must not return any >> Entity-Body in the response". >> >> CGI и HTTP - это два разных протокола, но первый ссылается на второй. >> При этом CGI протокол не запрещает бекенду отвечать на HEAD-запросы >> так, как этого требует от веб-сервера спецификация HTTP протокола. >> >> > И на >> > практике я не встречал скрипты, которые бы отдельно обрабатывали >> > HEAD-запросы. >> >> Но они есть. >> И их поведение ничем не противоречит спецификации FastCGI протокола. >> >> >>> Речь про какие-то фреймворки, которые обрабатывают >> >>> HEAD автоматически, не донося соответствующую информацию до кода? >> >>> Или про какой-то стандартный софт, который не возвращает тело для >> >>> HEAD-запросов? >> >> >> >> Какая разница, сам софт или фрейморк используемый софтом в каждом >> >> конкретном случае обрабатывает HEAD запросы согласно требований RFC? >> > >> > Никакой. Но с этой точки зрения так же нет разницы, что именно >> > написано в примерах в описании директивы fastcgi_cache_key. >> >> Вы не против, если я создам на хабре статью, в которой напишу >> про эту проблему с ошибочными примерами в документации nginx >> к директиве fastcgi_cache_key и ее аналогам? >> >> -- >> Best regards, >> Gena >> >> ___ >> nginx-ru mailing list >> nginx-ru@nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-ru > > ___ > nginx-ru mailing list > nginx-ru@nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-ru Прошу прощения, что влезаю. Есть статья Дмитрия Котерова от октября 2009 года, посвещенная кешированию в nginx http://dklab.ru/chicken/nablas/56.html Если механизм кеширование не сильно изменился, то данные там акутальные. На хабре, конечно, охват аудитории больше будет, если там появится подобная статья. ___ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Документация к директиве fastcgi_cache_key
протоколы действительно разные. но выглядит так, что предложение Гены поможет написать документацию, более устойчивую к тупому копипасту (есть такой патерн, что глядя на пример документации на авторитетном сайте, его копируют) пт, 30 нояб. 2018 г. в 14:30, Gena Makhomed : > On 29.11.2018 21:02, Maxim Dounin wrote: > > > CGI и HTTP - это два разных протокола. В последних вариациях на > > тему спецификации CGI записано, что на HEAD-запросы тело > > возвращать не надо (а если вдруг вернули - то сервер его должен > > поскипать), https://tools.ietf.org/html/rfc3875#section-4.3.3: > > > > The HEAD method requests the script to do sufficient processing to > > return the response header fields, without providing a response > > message-body. The script MUST NOT provide a response message-body > > for a HEAD request. If it does, then the server MUST discard the > > message-body when reading the response from the script. > > > > Однако на момент собственно появления и активного распространения > > CGI никаких подобных требований не существовало, см. > > https://www.w3.org/CGI/ и в частности > > https://tools.ietf.org/html/draft-robinson-www-interface-00. > > Там написано: > > REQUEST_METHOD > >This variable is specific to requests made with HTTP. > >The method with which the request was made, as described in >section 5.1.1 of the HTTP/1.0 specification [3]. > > http-method = "GET" | "HEAD" | "POST" | extension-method > > "described in HTTP/1.0 specification" - написано где смотреть семантику. > А в HTTP/1.0 specification написано, что "server must not return any > Entity-Body in the response". > > CGI и HTTP - это два разных протокола, но первый ссылается на второй. > При этом CGI протокол не запрещает бекенду отвечать на HEAD-запросы > так, как этого требует от веб-сервера спецификация HTTP протокола. > > > И на > > практике я не встречал скрипты, которые бы отдельно обрабатывали > > HEAD-запросы. > > Но они есть. > И их поведение ничем не противоречит спецификации FastCGI протокола. > > >>> Речь про какие-то фреймворки, которые обрабатывают > >>> HEAD автоматически, не донося соответствующую информацию до кода? > >>> Или про какой-то стандартный софт, который не возвращает тело для > >>> HEAD-запросов? > >> > >> Какая разница, сам софт или фрейморк используемый софтом в каждом > >> конкретном случае обрабатывает HEAD запросы согласно требований RFC? > > > > Никакой. Но с этой точки зрения так же нет разницы, что именно > > написано в примерах в описании директивы fastcgi_cache_key. > > Вы не против, если я создам на хабре статью, в которой напишу > про эту проблему с ошибочными примерами в документации nginx > к директиве fastcgi_cache_key и ее аналогам? > > -- > Best regards, > Gena > > ___ > nginx-ru mailing list > nginx-ru@nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-ru ___ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Документация к директиве fastcgi_cache_key
On 29.11.2018 21:02, Maxim Dounin wrote: CGI и HTTP - это два разных протокола. В последних вариациях на тему спецификации CGI записано, что на HEAD-запросы тело возвращать не надо (а если вдруг вернули - то сервер его должен поскипать), https://tools.ietf.org/html/rfc3875#section-4.3.3: The HEAD method requests the script to do sufficient processing to return the response header fields, without providing a response message-body. The script MUST NOT provide a response message-body for a HEAD request. If it does, then the server MUST discard the message-body when reading the response from the script. Однако на момент собственно появления и активного распространения CGI никаких подобных требований не существовало, см. https://www.w3.org/CGI/ и в частности https://tools.ietf.org/html/draft-robinson-www-interface-00. Там написано: REQUEST_METHOD This variable is specific to requests made with HTTP. The method with which the request was made, as described in section 5.1.1 of the HTTP/1.0 specification [3]. http-method = "GET" | "HEAD" | "POST" | extension-method "described in HTTP/1.0 specification" - написано где смотреть семантику. А в HTTP/1.0 specification написано, что "server must not return any Entity-Body in the response". CGI и HTTP - это два разных протокола, но первый ссылается на второй. При этом CGI протокол не запрещает бекенду отвечать на HEAD-запросы так, как этого требует от веб-сервера спецификация HTTP протокола. И на практике я не встречал скрипты, которые бы отдельно обрабатывали HEAD-запросы. Но они есть. И их поведение ничем не противоречит спецификации FastCGI протокола. Речь про какие-то фреймворки, которые обрабатывают HEAD автоматически, не донося соответствующую информацию до кода? Или про какой-то стандартный софт, который не возвращает тело для HEAD-запросов? Какая разница, сам софт или фрейморк используемый софтом в каждом конкретном случае обрабатывает HEAD запросы согласно требований RFC? Никакой. Но с этой точки зрения так же нет разницы, что именно написано в примерах в описании директивы fastcgi_cache_key. Вы не против, если я создам на хабре статью, в которой напишу про эту проблему с ошибочными примерами в документации nginx к директиве fastcgi_cache_key и ее аналогам? -- Best regards, Gena ___ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Документация к директиве fastcgi_cache_key
Hello! On Thu, Nov 29, 2018 at 08:35:18PM +0200, Gena Makhomed wrote: > On 29.11.2018 18:30, Maxim Dounin wrote: > > >> В документации к директиве fastcgi_cache_key приведен такой пример: > >> > >> fastcgi_cache_key localhost:9000$request_uri; > >> > >> У этого примера есть несколько проблем: > >> > >> 1. Если кто-то сделает к бекенду HEAD-запрос, то в кеш запишется пустой > >> ответ и на последующие GET-запросы будет отдаваться пустая страница. > > > AFAIK, никакой специальной обработки HEAD-запросов в FastCGI не > > предусмотрено. И в том числе не предсмотрено в каком-нибудь PHP > > из коробки. Соответственно всё будет работать штатно. > > Специальная обработка HEAD-запросов предусмотрена в HTTP протоколе: > https://tools.ietf.org/html/rfc7231#section-4.3.2 > > The HEAD method is identical to GET except that the server MUST NOT > send a message body in the response (i.e., the response terminates at > the end of the header section). > > В nginx присутствует workaround, который исправляет поведение бекендов, > которые на HEAD-запрос *ошибочно* отвечают так же, как и на GET-запрос. > > Но далеко не все бекенды содержат в себе эту ошибку, многие из них ведут > себя именно так, как этого от них требует спецификация HTTP протокола. CGI и HTTP - это два разных протокола. В последних вариациях на тему спецификации CGI записано, что на HEAD-запросы тело возвращать не надо (а если вдруг вернули - то сервер его должен поскипать), https://tools.ietf.org/html/rfc3875#section-4.3.3: The HEAD method requests the script to do sufficient processing to return the response header fields, without providing a response message-body. The script MUST NOT provide a response message-body for a HEAD request. If it does, then the server MUST discard the message-body when reading the response from the script. Однако на момент собственно появления и активного распространения CGI никаких подобных требований не существовало, см. https://www.w3.org/CGI/ и в частности https://tools.ietf.org/html/draft-robinson-www-interface-00. И на практике я не встречал скрипты, которые бы отдельно обрабатывали HEAD-запросы. > > Речь про какие-то фреймворки, которые обрабатывают > > HEAD автоматически, не донося соответствующую информацию до кода? > > Или про какой-то стандартный софт, который не возвращает тело для > > HEAD-запросов? > > Какая разница, сам софт или фрейморк используемый софтом в каждом > конкретном случае обрабатывает HEAD запросы согласно требований RFC? Никакой. Но с этой точки зрения так же нет разницы, что именно написано в примерах в описании директивы fastcgi_cache_key. [...] -- Maxim Dounin http://mdounin.ru/ ___ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: Документация к директиве fastcgi_cache_key
On 29.11.2018 18:30, Maxim Dounin wrote: В документации к директиве fastcgi_cache_key приведен такой пример: fastcgi_cache_key localhost:9000$request_uri; У этого примера есть несколько проблем: 1. Если кто-то сделает к бекенду HEAD-запрос, то в кеш запишется пустой ответ и на последующие GET-запросы будет отдаваться пустая страница. AFAIK, никакой специальной обработки HEAD-запросов в FastCGI не предусмотрено. И в том числе не предсмотрено в каком-нибудь PHP из коробки. Соответственно всё будет работать штатно. Специальная обработка HEAD-запросов предусмотрена в HTTP протоколе: https://tools.ietf.org/html/rfc7231#section-4.3.2 The HEAD method is identical to GET except that the server MUST NOT send a message body in the response (i.e., the response terminates at the end of the header section). В nginx присутствует workaround, который исправляет поведение бекендов, которые на HEAD-запрос *ошибочно* отвечают так же, как и на GET-запрос. Но далеко не все бекенды содержат в себе эту ошибку, многие из них ведут себя именно так, как этого от них требует спецификация HTTP протокола. Речь про какие-то фреймворки, которые обрабатывают HEAD автоматически, не донося соответствующую информацию до кода? Или про какой-то стандартный софт, который не возвращает тело для HEAD-запросов? Какая разница, сам софт или фрейморк используемый софтом в каждом конкретном случае обрабатывает HEAD запросы согласно требований RFC? Эта проблема встречается не только у меня, вот например: https://www.claudiokuenzler.com/blog/705/empty-blank-page-nginx-fastcgi-cache-head-get https://serverfault.com/a/612729 Отдельно отмечу, что правильный вариант работы с HEAD-запросами для целей кэширования - это отправлять на бэкенд GET-запросы, и кэшировать ответ. Именно так делает proxy-модуль. В proxy модуле есть директива proxy_cache_convert_head, которая имеет значение on по-умолчанию, поэтому там все работает нормально. В fastcgi/uwsgi/scgi модулях аналогичной директивы нет. В случае FastCGI подобная автоматическая конвертация не работает, так как метод запроса не отправляется на бэкенд иначе как через произвольно заданный fastcgi_param, Нет. FastCGI - это расширение протокола CGI, а протокол CGI *требует*, чтобы параметр REQUEST_METHOD присутствовал в каждом запросе: https://tools.ietf.org/html/rfc3875#section-4.1.12 The REQUEST_METHOD meta-variable MUST be set to the method which should be used by the script to process the request, as described in section 4.3. REQUEST_METHOD = method method = "GET" | "POST" | "HEAD" | extension-method extension-method = "PUT" | "DELETE" | token да и сама конвертация представляется ненужной, так как в типичном случае ответы на HEAD-запросы не отличаются от таковых на GET-запросы. Но ведь не все бекенды нарушают требование HTTP протокола, есть и такие, которые обрабатывают HEAD-запросы правильно. Однако если вдруг она нужна - это можно сделать, просто передав в fastcgi_param GET вместо HEAD. Можете привести фрагмент конфига, как это можно сделать? 2. Как правило на современных серверах размещено больше одного сайта. При такой настройке как рекомендуется в документации - кеш будет представлять собой смесь из содержимого разных сайтов и нормально работать не будет. Вопрос тут в том, что именно является идентификатором запрашиваемого ресурса. Пример в документации предполагает, что мы коннектимся на localhost:9000, и получаем там ответы, идентифицируемые URI запроса. Идентификатором ресурса является https://en.wikipedia.org/wiki/URI который включает в себя и scheme и host и path[?query] ($request_uri) Это в общем случае верно для конфигурации, которая приводится в описании модуля fastcgi, и с этой конфигурацией приведённый пример fastcgi_cache_key будет работать корректно. Если конфигурация другая - fastcgi_cache_key может потребоваться другой. Однако проблема в том, что без знания конфигурации - неизвестно, какой именно fastcgi_cache_key потребуется. Поэтому я и предлагаю написать в документации пример директивы, который будет корректно работать *всегда*. 3. если бекенд возвращает для HTTP-версии сайта редирект на HTTPS версию сайта, такое значение fastcgi_cache_key бужет приводить к проблемам, так как для HTTPS-запроса будет возвращаться 301 редирект из кеша. Можно ли исправить документацию и написать там в качестве примера такой фрагмент: fastcgi_cache_key "$request_method $scheme://$host$request_uri"; такая директива работает нормально, нет трех вышеперечисленных проблем. Ключём кэширования должен выступать идентификатор ресурса, который запрашивается с бэкенда. Идентификатор ресурса - это URI, в случае HTTP протокола. В предложенном варианте - отсутствует какая-либо информация о бэкенде вообще, так что он представляется мне идеалогически неверным. А в чем тут практическая проблема, если в fastcgi_cache_key отсутствует информация о бекенде? Или проблемы никакой нет? У нас,
Re: Документация к директиве fastcgi_cache_key
Hello! On Thu, Nov 29, 2018 at 04:59:09PM +0200, Gena Makhomed wrote: > Здравствуйте, All! > > В документации к директиве fastcgi_cache_key приведен такой пример: > > fastcgi_cache_key localhost:9000$request_uri; > > У этого примера есть несколько проблем: > > 1. Если кто-то сделает к бекенду HEAD-запрос, то в кеш запишется пустой > ответ и на последующие GET-запросы будет отдаваться пустая страница. AFAIK, никакой специальной обработки HEAD-запросов в FastCGI не предусмотрено. И в том числе не предсмотрено в каком-нибудь PHP из коробки. Соответственно всё будет работать штатно. Речь про какие-то фреймворки, которые обрабатывают HEAD автоматически, не донося соответствующую информацию до кода? Или про какой-то стандартный софт, который не возвращает тело для HEAD-запросов? Отдельно отмечу, что правильный вариант работы с HEAD-запросами для целей кэширования - это отправлять на бэкенд GET-запросы, и кэшировать ответ. Именно так делает proxy-модуль. В случае FastCGI подобная автоматическая конвертация не работает, так как метод запроса не отправляется на бэкенд иначе как через произвольно заданный fastcgi_param, да и сама конвертация представляется ненужной, так как в типичном случае ответы на HEAD-запросы не отличаются от таковых на GET-запросы. Однако если вдруг она нужна - это можно сделать, просто передав в fastcgi_param GET вместо HEAD. > 2. Как правило на современных серверах размещено больше одного сайта. > При такой настройке как рекомендуется в документации - кеш будет > представлять собой смесь из содержимого разных сайтов и нормально > работать не будет. Вопрос тут в том, что именно является идентификатором запрашиваемого ресурса. Пример в документации предполагает, что мы коннектимся на localhost:9000, и получаем там ответы, идентифицируемые URI запроса. Это в общем случае верно для конфигурации, которая приводится в описании модуля fastcgi, и с этой конфигурацией приведённый пример fastcgi_cache_key будет работать корректно. Если конфигурация другая - fastcgi_cache_key может потребоваться другой. Однако проблема в том, что без знания конфигурации - неизвестно, какой именно fastcgi_cache_key потребуется. > 3. если бекенд возвращает для HTTP-версии сайта редирект на HTTPS версию > сайта, такое значение fastcgi_cache_key бужет приводить к проблемам, > так как для HTTPS-запроса будет возвращаться 301 редирект из кеша. > > Можно ли исправить документацию и написать там в качестве примера > такой фрагмент: > > fastcgi_cache_key "$request_method $scheme://$host$request_uri"; > > такая директива работает нормально, нет трех вышеперечисленных проблем. Ключём кэширования должен выступать идентификатор ресурса, который запрашивается с бэкенда. В предложенном варианте - отсутствует какая-либо информация о бэкенде вообще, так что он представляется мне идеалогически неверным. У нас, конечно, уже есть подобная конструкция в описании proxy_cach_key, но там за счёт $cookie_user куда более очевидно, что это именно пример, а не что-то, отлитое в граните и пригодное для всех конфигов. Возможно, по какому-то такому пути и стоит пойти. > P.S. > > Недавно в очередной раз столкнулся в проблемой, когда люди бездумно > копируют в конфиг рекомендуемые варианты директивы fastcgi_cache_key > из документации, не подозревая, что в документации записано в качестве > рекомендуемого варианта то, что нормально работать у них не будет. Кажется, что правильным будет для начала написать в описании fastcgi_cache_key (uwsgi_cache_key, scgi_cache_key), что ключ должен идентифицировать запрашиваемый ресурс, а не ставится "абы как, авось повезёт". -- Maxim Dounin http://mdounin.ru/ ___ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru