Content-Length
Заголовок Content-Length
определяет длину байта тела запроса / ответа. Если вы не укажете указать заголовок Content-Length
, HTTP-серверы неявно добавят заголовок Transfer-Encoding: chunked
. Заголовки Content-Length
и Transfer-Encoding
не должны использоваться вместе. Получатель не будет знать, какова длина тела, и не сможет оценить время завершения загрузки. Если вы добавите заголовок Content-Length
, убедитесь, что он соответствует всему телу в байтах, если он неверен, поведение получателей не определено.
Заголовок Content-Length
не разрешает потоковую передачу, но это полезно для больших двоичных файлов, где вы хотите поддерживать частичное обслуживание контента. Это в основном означает возобновляемую загрузку, приостановленную загрузку, частичную загрузку и мультидоменные загрузки. Это требует использования дополнительного заголовка с именем Range
. Эта техника называется Служба байтов .
Transfer-Encoding
Использование Transfer-Encoding: chunked
- это то, что позволяет осуществлять потоковую передачу в пределах одного запроса или ответа. Это означает, что данные передаются по частям и не влияют на представление содержимого.
Официально HTTP-клиент предназначен для отправки запроса с полем заголовка TE
, которое указывает, какие виды кодировок передачи клиент готов принять. Это не всегда отправляется, однако большинство серверов предполагают, что клиенты могут обрабатывать chunked
кодировки.
Кодировка передачи chunked
позволяет лучше использовать постоянные TCP-соединения, которые HTTP 1.1 по умолчанию принимает за истину.
Content-Encoding
Также возможно сжимать фрагментированные или не фрагментированные данные. Это практически делается через заголовок Content-Encoding
.
Обратите внимание, что Content-Length
равна длине тела после Content-Encoding
. Это означает, что если вы распаковали свой ответ, то вычисление длины происходит после сжатия. Вам нужно будет иметь возможность загрузить все тело в память, если вы хотите рассчитать длину (если вы не располагаете этой информацией в другом месте).
При потоковой передаче с использованием кускового кодирования алгоритм сжатия также должен поддерживать оперативную обработку. К счастью, gzip поддерживает потоковое сжатие. Я считаю, что контент сначала сжимается, а затем разбивается на куски. Таким образом, куски принимаются, а затем распаковываются для получения реального контента. Если бы все было наоборот, вы получите сжатый поток, а затем распаковка даст нам куски. Что не имеет смысла.
Типичный ответ сжатого потока может иметь следующие заголовки:
Content-Type: text/html
Content-Encoding: gzip
Transfer-Encoding: chunked
Семантически использование Content-Encoding
указывает на схему кодирования «конец в конец», что означает, что только конечный клиент или конечный сервер должен декодировать контент. Прокси в середине не должны декодировать контент.
Если вы хотите разрешить прокси-серверам в середине декодировать контент, правильный заголовок для использования - это заголовок Transfer-Encoding
. Если HTTP-запрос имеет заголовок TE: gzip chunked
, то разрешено отвечать Transfer-Encoding: gzip chunked
.
Однако это очень редко поддерживается. Так что прямо сейчас вы должны использовать Content-Encoding
для сжатия.
Chunked vs Store & Forward