While investigating (in Chromium and Firefox devtools) some resources sent over HTTP/3
, I noticed that the content-length
header is never sent.
Why?
The Content-Length
header is not sent because HTTP/2 and HTTP/3 framing are based on the END_STREAM
flag.
The term "framing" here denotes "how request/response bytes are delimited to indicate the begin and the end of a request/response".
HTTP/1.1, being a textual protocol, needs the Content-Length
header to indicate the end of the request/response content.
HTTP/2/3, being binary protocols with frames, can just encode this information in the last frame for that request/response.
It is a HEADERS
or DATA
frame having the END_STREAM
flag set to true
that determines if there is request/response content, and if so, what frame carries the last content bytes.
In summary, the Content-Length
header is not necessary in HTTP/2 and HTTP/3 because they have a different framing than HTTP/1.1.
Proxies that convert from HTTP/2/3 to HTTP/1.1 synthesize the Content-Length
header, so that applications based on HTTP/1.1 can look it up, if necessary.
See also: How http2/http1.1 proxy handle the Transfer-Encoding?