序列化header块是如何划分的?

How serialized header block is divided?

我正在实施我自己的 HTTP/2 服务器。通读了RFC 7540,部分关于HTTP header frame的内容把我弄糊涂了:

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

所以在我的想象中,这个过程是这样的:

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

但是序列化的header块是如何被划分的部分没有提到。

所以我的问题是:是否可以将一个 HTTP header separate/divide 分成多个 Header 块片段? 例如,部分Header1 Bin DataBlock Fragment 1承载,其余由Block Fragment 2承载.

谢谢!

是的,可以将对应于 1 个 HTTP header 的字节拆分为 2 个(或更多)帧。

您通过 HPACK 将 HTTP header 编码为字节,因此您现在只有一个 byte[]。 假设 byte[] 的长度为 23。

您可以创建一个带有标志 end_headers=falseHEADERS 框架,并将例如 23 个字节中的 13 个放入其中。 然后,您创建一个带有标志 end_headers=trueCONTINUATION 帧,并将剩余的 10 个字节放入其中。

拆分 byte[] 的地方完全不透明。

重要的是 HEADERSCONTINUATION 帧必须一个接一个地发送,中间没有其他帧。

接收方将看到带有end_headers=falseHEADERS帧,将提取13个字节并将它们放在一边,等待CONTINUATION帧。 当CONTINUATION帧到达时,接收端会提取这10个字节,将其与之前的13个字节拼接得到原来23个字节的副本,现在可以通过HPACK进行解码,得到原始HTTPheaders.