Search code examples
http2

How serialized header block is divided?


I'm implementing my own HTTP/2 server. Read through the RFC 7540, a portion of content about HTTP header frame got me confused:

https://www.rfc-editor.org/rfc/rfc7540#section-4.3

Header lists are collections of zero or more header fields. When
transmitted over a connection, a header list is serialized into a
header block using HTTP header compression [COMPRESSION]. The
serialized header block is then divided into one or more octet
sequences, called header block fragments

So in my imagination, the process would look like:

+-------------------+    +-------------------+    +------------------+    +---------+
|    Header List    |    |    Header Block   |    | Block Fragment 1 | -> | Frame 1 | 
+-------------------+    +-------------------+    +------------------+    +---------+
| :method = POST    |    | Header 1 Bin Data |    | Block Fragment 2 | -> | Frame 2 |
| :path = /resource | -> | Header 2 Bin Data | -> +------------------+    +---------+ 
| :scheme = https   |    | Header 3 Bin Data |    | Block Fragment 3 | -> | Frame 3 |
| .....             |    | Header 4 Bin ...  |    +------------------+    +---------+
+-------------------+    +-------------------+    ...                     ...

But how the serialized header block got divided does not mentioned in the section.

So my question is: Is that possible to separate/divide one HTTP header into multiple Header Block Fragments? For example, part of Header 1 Bin Data is carried by Block Fragment 1, and the rest is carried by Block Fragment 2.

Thank you!


Solution

  • Yes, it is possible to split the bytes corresponding to 1 HTTP header into 2 (or more) frames.

    You encode the HTTP headers into bytes via HPACK, so you have now just a byte[]. Let's assume the byte[] has length 23.

    You can create a HEADERS frame with flags end_headers=false and put for example 13 of the 23 bytes into it. Then, you create a CONTINUATION frame with flags end_headers=true and put the remaining 10 bytes into it.

    It is completely opaque where you split the byte[].

    The important thing is that the HEADERS and CONTINUATION frames must be sent one after the other, with no other frame between them.

    The receiving side will see the HEADERS frame with end_headers=false, will extract the 13 bytes and will put them aside, waiting for a CONTINUATION frame. When the CONTINUATION frame arrives, the receiving side will extract the 10 bytes, concatenate it with the previous 13 to obtain a copy of the original 23 bytes that can now be decoded via HPACK, obtaining the original HTTP headers.