跳到主要内容

3. 格式 (Format)

[HTTP] 第 6 节定义了 HTTP 消息的一般结构, 并将这些消息组成不同部分. 本格式描述这些部分如何组成字节序列. 从高层看, 二进制消息由以下部分组成:

  1. 成帧指示符 (Framing indicator) - 一个整数, 描述消息是请求还是响应, 以及后续各节如何格式化
  2. 对于响应 (For a response) - 零个或多个信息性响应 (每个响应包含状态码和头部节)
  3. 控制数据 (Control data) - 请求方法/目标 (用于请求) 或状态码 (用于响应)
  4. 头部节 (Header section) - 零个或多个头字段
  5. 内容 (Content) - 零个或多个字节组成的序列
  6. 尾部节 (Trailer section) - 零个或多个尾字段
  7. 可选填充 (Optional padding) - 任意数量的零值字节

所有长度和数值都使用 [QUIC] 第 16 节中的可变长度整数编码. 整数值不需要使用所需的最少字节数进行编码.

3.1. 已知长度消息

构造时长度已知的请求或响应使用图 1 所示格式.

Known-Length Request {
Framing Indicator (i) = 0,
Request Control Data (..),
Known-Length Field Section (..),
Known-Length Content (..),
Known-Length Field Section (..),
Padding (..),
}

Known-Length Response {
Framing Indicator (i) = 1,
Known-Length Informational Response (..) ...,
Final Response Control Data (..),
Known-Length Field Section (..),
Known-Length Content (..),
Known-Length Field Section (..),
Padding (..),
}

对于已知长度编码, 字段节和内容上的长度前缀是一个整数的可变长度编码. 该整数是字段节或内容中的字节数, 不包括长度字段本身.

3.2. 不定长度消息

如果构造请求或响应时没有为每个节编码已知长度, 则使用不定长度编码. 不定长度编码只对内容块使用长度前缀. 可以包含多个带长度前缀的内容部分, 每个部分前面都有一个非零 Chunk Length 整数.

3.3. 成帧指示符

成帧指示符是一个整数, 描述后续各节的结构:

  • 0 = 已知长度请求
  • 1 = 已知长度响应
  • 2 = 不定长度请求
  • 3 = 不定长度响应

其他值会导致消息无效.

3.4. 请求控制数据

请求的控制数据包含: Method, Scheme, Authority, Path. 每个字段都带有长度前缀. 各值遵循 HTTP/2 对 ":method", ":scheme", ":authority" 和 ":path" 伪头字段的规则.

3.5. 响应控制数据

响应的控制数据由编码为可变长度整数的状态码组成, 而不是带长度前缀的十进制字符串.

3.5.1. 信息性状态码

信息性状态码 (1xx) 可以在最终响应之前出现零次或多次.

3.6. 头部和尾部字段行

每个字段行编码为带长度前缀的名称, 后跟带长度前缀的值. 字段名称 MUST 转换为小写. 名称和值都是带长度前缀的字节序列.

3.7. 内容

已知长度消息和不定长度消息对内容的编码方式不同. 对于已知长度: 使用单个带长度前缀的块. 对于不定长度: 使用多个分块, 每个分块都有长度前缀, 并以零值整数终止.

3.8. 填充和截断

可以向消息追加任意数量的零值字节作为填充. 消息可以在特定边界处截断, 而不会因此变为无效.