httphttp-headershttp3

Why is content-length header not sent over HTTP/3?


While investigating (in Chromium and Firefox devtools) some resources sent over HTTP/3, I noticed that the content-length header is never sent.

Why?


Solution

  • 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?