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!
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.