HTTP message framing (source code)

= HTTP message framing
{c}

<HTTP message framing> determines where an <HTTP request> or <HTTP response> ends and whether it is complete. The concrete rules depend on the protocol version. In <HTTP 1.1>, an empty line ends the header section, but the end of the message body requires the applicable length, transfer-coding or connection rules. A body can itself contain line breaks.<HTTP 1.1 (RFC 9112)>[§2.1, message format; §6.3, ordered body-length rules]{ref}

Consider an ordinary successful response to `GET` whose text is `café` in <UTF-8>. Its four displayed letters occupy five octets, with hexadecimal values `63 61 66 c3 a9`. With no transfer coding and no overriding bodyless-response rule, `Content-Length: 5` therefore frames this body. Counting displayed characters would give the wrong boundary.<HTTP 1.1 (RFC 9112)>[§6.3, item 6, valid Content-Length counts octets]{ref}

An alternative is <chunked transfer coding>. Use `Transfer-Encoding: chunked` instead of the content-length field. The body can then be written in visible escape notation as `2\r\nca\r\n3\r\nfé\r\n0\r\n\r\n`. Here `\r\n` denotes an actual carriage-return/line-feed pair, and the text is encoded in <UTF-8>. The first chunk supplies two octets; the second supplies three; the zero-sized chunk and empty trailer section finish the coding. This transfer-coded body occupies twenty octets and yields the same five content octets after decoding.<HTTP 1.1 (RFC 9112)>[§7.1, chunk-size hexadecimal grammar, chunk-data and last-chunk]{ref}

Precedence matters. Responses to `HEAD` and responses with status `1xx`, `204` or `304` have no message body even when fields appear to suggest a length. Some responses instead end with connection closure; requests are not close-delimited. Receiving fewer than the declared number of octets leaves a length-delimited message incomplete.<HTTP 1.1 (RFC 9112)>[§6.3, items 1 and 7–8; §8, incomplete messages]{ref}

Framing is separate from <media type>: a recipient first needs to delimit the transmitted data, then interpret its format. It also makes <HTTP persistent connections> possible, since a recipient can finish one exchange without treating connection closure as the only indication of completion.