Как надежно определить длину тела при закрытии соединения (RFC 2616 4.4.5)

Я не могу понять одну вещь прямо. RFC 2616 в 4.4.5 утверждает, что Message Length можно определитьBy the server closing the connection.".

Это подразумевает, что для сервера допустимо отвечать (например, возвращая большое изображение) ответом, который не имеет Content-Length в заголовке, но клиент должен продолжать извлекать данные до тех пор, пока соединение не будет закрыто, а затем предположить, что все данные были загружены.

Но как клиент может точно знать, что соединение было намеренно закрыто сервером? Серверное приложение могло произойти сбой во время отправки данных, и ОС сервера, скорее всего, отправит FIN пакет, чтобы изящно закрыть TCP соединение с клиентом.

1 ответ

Решение

Вы абсолютно правы, этот механизм абсолютно ненадежен. Это описано в RFC 7230:

Поскольку нет никакого способа отличить успешно завершенное сообщение с разделителями с разделителями от частично полученного сообщения, прерванного из-за сбоя в сети, сервер ДОЛЖЕН генерировать сообщения с кодированием или с разделителями по длине, когда это возможно. Функция близкого разграничения существует главным образом для обратной совместимости с HTTP/1.0.

К счастью, большая часть трафика HTTP сегодня - HTTP/1.1, с Content-Length или "Transfer-Encoding", чтобы явно определить конец сообщения.

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

На этой ноте, (хорошо сформированный) html документ или .gif, .avi и т.д., определяет свое собственное завершение; мы узнаем, получили ли мы неполный документ. Поэтому не так сложно передать его по HTTP / 1.0 без Content-Length.

Тем не менее, для простого текстового документа, javascript, css и т.д. EOF используется для обозначения конца документа, поэтому он проблематичен по HTTP/1.0.

Другие вопросы по тегам