Search code examples
http2rfc

Why a header block requires transmission in contiguous frames with no interleaved frames of same or other stream?


In page 14 of RFC 7540, it is mentioned that "Each header block is processed as a discrete unit. Header blocks MUST be interleaved as a contiguous sequence of frames, with no interleaved frames of any type or from any other stream"

According to the best of my understanding, this is also a kind of Head of Line Blocking. Any reason behind why the implementers came up with this idea even for different Streams as well?

Thank you!


Solution

  • You are correct that this does add a Head of Line Blocking. This is necessary because HPACK introduces state meaning that other header frame cannot be interwoven without causing confusion as to which order to update the HPACK dynamic table.

    There were other proposals discussed during the design, including changing this to a large frame - but by insisting on contiguous HEADERS + CONTINUATION frames that's effectively the same thing and there are other good reasons to have CONTINUATION frames.

    Interestingly QUIC and HTTP/3 are looking to drop CONTINUATION frames and go with larger frame sizes:

    CONTINUATION (0x9): : CONTINUATION frames do not exist; instead, larger HEADERS/PUSH_PROMISE frames than HTTP/2 are permitted.

    But then again QPACK also had to solve the HOL problem due to the fact that independent streams are truly independent under QUIC, whereas order is still guaranteed under TCP.

    Ultimately HTTP/2 CONTINUATION frames are expected to very rarely used: the vast majority of HEADERS will fit into a single HEADERS frame (limited at 16k). So this is not a big deal for most use cases, and simplicity trumps technical over complications for edge cases IMHO.