Длина сообщения и управление соединением - это две разные вещи, которые на самом деле не имеют ничего общего друг с другом (за исключением одного случая, когда длина сообщения полностью неизвестна, и закрытие соединения является единственным возможным способом обозначить EOF, но это редко бывает, а не твоя ситуация).
Разделение на блоки применяется только к длине сообщения, где фрагмент длины 0 обозначает EOF. Если соединение преждевременно закрыто до достижения EOF, сообщение является неполным, и получатель может решить, сохранять его или обрабатывать или нет.
Заголовок Connection
используется клиентом, чтобы указать, хочет ли он, чтобы сервер закрыл соединение или оставил его открытым после отправки своего ответа. Этот же заголовок используется сервером для указания того, действительно ли соединение закрывается или остается открытым после отправки ответа.
Не должен быть добавлен заголовок «Соединение» (или задано значение keep-alive, что совпадает с тем, что мы говорим о HTTP 1.1), или разрешено установить для него значение Соединение: закрыть
Это не имеет ничего общего с кусками. Независимо от формата сообщения клиент и сервер должны всегда указывать свои намерения для текущего соединения, должно ли оно быть закрыто или оставлено открытым. Это делается через наличие или отсутствие заголовка Connection
, в зависимости от версии HTTP:
Если используется HTTP 1.0, по умолчанию используется close
, если явно не отправлено Connection: keep-alive
.
Если используется HTTP 1.1+, по умолчанию используется keep-alive
, если явно не отправлено Connection: close
.
Если клиент запрашивает подтверждение активности, сервер решает, соблюдать его или нет. Сервер может либо оставить соединение открытым, либо закрыть соединение.
Если клиент запрашивает закрытие, сервер ДОЛЖЕН соблюдать его и закрывать соединение.
Отправка пустого чанка означает конец передачи, но означает ли это конец соединения?
Нет. Только заголовок Connection
делает это. Особенно в сценарии keep-alive
, таким образом, соединение остается открытым, чтобы клиент мог повторно использовать существующее соединение для отправки нового запроса после завершения передачи предыдущего ответа.
Я подумал, что мне нужно добавить Connection: close, когда я собираюсь закрыть соединение после отправки пустого чанка
Правильно, особенно в HTTP 1.1+, где keep-alive
- поведение по умолчанию.
где, если я не добавлю заголовок Connection, он останется открытым
Значение пропущенного заголовка Connection
зависит от используемой версии HTTP, как описано выше.