Nginx игнорирует клиентский запрос HTTP 1.0 и отвечает по HTTP 1.1
Я тестирую с помощью nginx/php5-fpm
с кодом
<?php
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
// also tested: header("Status: 404 Not Found");
echo $_SERVER["SERVER_PROTOCOL"];
И заставить использовать HTTP 1.0 с curl
команда.
curl -0 -v 'http://www.example.com/test.php'
> GET /test.php HTTP/1.0
< HTTP/1.1 404 Not Found
< Server: nginx
< Date: Sat, 27 Oct 2012 08:51:27 GMT
< Content-Type: text/html
< Connection: close
<
* Closing connection #0
HTTP/1.0
Как видите, я уже запрашиваю использование HTTP 1.0
, но nginx ответь мне HTTP 1.1
премия
@MaximDounin, @MichaelHampton уже предоставил ответ на спецификацию, спасибо. Я немного расширяю этот вопрос для будущего читателя:
В. В чем преимущество ответа HTTP 1.1, когда клиент запрашивает HTTP 1.0? Не должен ли подход, принятый Google, более разумным, то есть когда клиент запрашивает 1.0, ответ с 1.0?
2 ответа
Это нормальное и ожидаемое поведение, согласно RFC 2616:
Приложения, которые хотя бы условно совместимы с этой спецификацией, ДОЛЖНЫ использовать HTTP-версию "HTTP/1.1" в своих сообщениях и ДОЛЖНЫ делать это для любого сообщения, несовместимого с HTTP/1.0. Для получения дополнительной информации о том, когда отправлять определенные значения HTTP-версии, см. RFC 2145.
HTTP-сервер ДОЛЖЕН отправить версию ответа, равную самой высокой версии, для которой сервер хотя бы условно соответствует, и чья основная версия меньше или равна той, которая получена в запросе. HTTP-сервер НЕ ДОЛЖЕН отправлять версию, для которой он не является хотя бы условно совместимым. Сервер МОЖЕТ отправить ответ 505 (версия HTTP не поддерживается), если не может отправить ответ, используя основную версию, используемую в запросе клиента.
HTTP-сервер МОЖЕТ отправить более низкую версию ответа, если известно или подозревается, что клиент неправильно реализует HTTP-спецификацию, но это не должно быть значением по умолчанию, и ЭТО НЕ СЛЕДУЕТ делать, если версия запроса HTTP / 1.1 или выше.
На английском это означает следующее: если клиент отправляет запрос HTTP / 1.0, то приемлем ответ HTTP / 1.0 или HTTP / 1.1, но предпочтительным является HTTP / 1.1.
Причина, по которой это делается, заключается в том, что один конец может объявить самую высокую версию HTTP, которую он может поддерживать, так что другой конец может решить обновить свою поддержку протокола (если это возможно). Затем оба конца решат, с какой версией протокола они могут жить. Этот дизайн также помогает бороться с ошибочными реализациями, как заявлено в RFC 2145.
В то же время предполагалось, что могут появиться дополнительные версии протокола HTTP, как младшие, так и основные версии, а правила призваны помочь обеспечить совместимость. Подход Google к RFC-невежеству может прекратиться после завершения работы над HTTP/2.0. (Вы знаете его в виде черновика как SPDY.)
В. В чем преимущество ответа HTTP 1.1, когда клиент запрашивает HTTP 1.0?
На самом деле он отправляет вам HTTP/1.0-совместимый ответ. Он не будет использовать какие-либо функции, такие как keepalive, которые требуют HTTP/1.1.
Причина для этого в том, что это дешевый способ сказать серверу:
"эй, я знаю, что вы отправили мне запрос с использованием HTTP/1.0, но только для того, чтобы сообщить вам, что я способен на HTTP / 1.1. и вот ответ на ваш первоначальный запрос: [..] "
(Примечание. Если сервер поддерживает вымышленный HTTP/1.8, он ответит так.)
Это экономит вам дополнительный запрос в некоторых ситуациях. Если вам нужно получить 3 разных URI с сервера, вы можете отправить первый как HTTP/1.0, а затем перейти на самую высокую версию, которую и вы, и сервер поддерживают последующие запросы.