Подтвердить что ты не робот

Как интерпретировать "Соединение: сохранить, закрыть"?

Из того, что я понимаю, HTTP-соединение может быть либо keep-alive, либо close.

Я отправил HTTP-запрос на сервер:

GET /page1/ HTTP/1.1
Host: server.com
Connection: keep-alive

И он ответил:

HTTP/1.1 200 OK
Connection: keep-alive, close

По сути, я считаю, что сервер прослушивается, потому что ответ вроде keep-alive, close неоднозначен.

Однако, как приемник, как мы должны обрабатывать такое сообщение? Должны ли мы интерпретировать это значение заголовка как keep-alive или close?

4b9b3361

Ответ 1

TL; DR: Chrome интерпретирует этот заголовок ответа как keep-alive и поддерживает постоянное соединение, в то время как Firefox закрывает каждое соединение.

Я наткнулся на этот вопрос, пытаясь оптимизировать время загрузки страницы для моего сайта.

В ссылочном RFC я не нашел ничего о том, как можно обрабатывать несколько записей в заголовке Connection. Мне показалось, что реализация может выбирать из двух возможных вариантов:

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

Итак, мне нужно было выяснить. Давайте сделаем еще более глубокое исследование:

Я заметил, что Chrome всегда отправлял HTTP/1.1 запрос с Connection: keep-alive, и моя конфигурация по умолчанию Apache всегда отвечала заголовком Connection: close. Поэтому я начал исследовать и посмотрел на сегменты TCP с Wireshark.

Chrome должен отображать 14 элементов для отображения веб-сайта, в основном из них - статические вещи, такие как изображения или файлы css. И потребовалось 14 соединений TCP, и это заняло много времени (примерно 1,2 секунды). После каждого запроса на изображение (например,) появился сегмент TCP с флагом FIN, установленным в 1.

А как насчет Chrome против Firefox? Кажется, что у Chrome есть максимальное количество одновременных подключений к одному серверу из 6. Firefox имеет более гранулированную конфигурацию и отличается постоянством (максимум 6, видимый примерно: config) и непостоянный (максимальные числа сильно различались в разных источниках). Но подождите... Оба, Chrome и Firefox отправляют заголовки запросов HTTP/1.1 с помощью Connection: keep-alive, поэтому оба должны быть ограничены 6 (так как это запрос для открытия постоянного соединения).

Я решил попробовать простой трюк и добавил следующие строки в мой .htaccess в корневой папке:

<ifModule mod_headers.c>
Header set Connection keep-alive
</ifModule>

Теперь сервер отвечает:

Connection: keep-alive, close

Теперь я снова посмотрел на сегменты TCP: теперь на моем сервере было только 9 соединений с Chrome, и только 3 с флагом FIN, установленным в 1. Таким образом, этот трюк, похоже, работал. Но почему были эти 3 соединения, которые закрыли соединение после передачи данных? Это были запросы PHP, как подтвержден HTTP-заголовок X-Powered-By: PHP/5.4.11.

А как насчет Firefox? Были еще те 14 запросов!

Как это исправить и заставить процессы fcgi работать с keep-alive тоже?

Я добавил следующие строки в мой раздел virtualhost конфигурации httpd.conf:

KeepAlive On
KeepAliveTimeout 5
MaxKeepAliveRequests 100

и удалили те, которые были добавлены в .htaccess. Теперь сервер не отправляет путаницу - Connection: keep-alive, close, но только Connection: keep-alive, и все работает отлично!

Вывод:

Заголовок с полем подключения, установленным на

HTTP/1.1 200 OK
Connection: keep-alive, close

будет интерпретироваться Chrome как keep-alive, в то время как Firefox, похоже, закрывает каждое соединение. Кажется, что это зависит от фактической реализации.

Итак, если вы хотите внедрить клиент для обработки заголовков ответов, содержащих Connection: keep-alive, close, я бы предложил попробовать использовать keep-alive, если вам нужно больше одного запроса. Самое худшее, что может случиться: сервер закроет соединение, и вам нужно будет снова подключиться (это точно другой вариант, который у вас был бы!)

Ответ 2

Это означает, что сервер не будет выполнять постоянные соединения и закроет соединение после этого запроса.

Ответ 3

Ответ на RFC 7230 - 6.1. Подключение. В нем говорится:

Значение поля заголовка соединения имеет следующую грамматику:

 Connection        = 1#connection-option
 connection-option = token

В языке RFC, 1#connection-option означает по крайней мере одно и самое большее число connection-option. Это означает, что может быть несколько вариантов, среди которых получатель выбирает всех, кого он предпочитает. Это не двусмысленность, а выбор.

Ответ 4

Вы используете HTTP/1.1, и вы указываете Connection: keep-alive.

В HTTP/1.1 все подключения сохраняются по умолчанию, а заголовок Connection: keep-alive устарел, поэтому его не следует отправлять.

Connection: keep-alive - это небольшой взлом, используемый в так называемые дни HTTP/1.0+. (+ означает "хаки, необходимые, чтобы заставить его работать".)

В HTTP: окончательное руководство Брайана Тотти, Марджори Сайер, Сайлу Редди, Аньшу Аггарвал, Дэвида Гурли О'Рейли мы читаем:

Keep-alive устарел и больше не документирован в текущей спецификации HTTP/1.1. Тем не менее, поддержание связи в режиме реального времени по-прежнему относительно широко используется браузерами и серверами, поэтому разработчики HTTP должны быть готовы к взаимодействию с ним.

Сервер может "взаимодействовать" и троллировать вас за избыточность.