3. 格式 (Format)
[HTTP] 第 6 节定义了 HTTP 消息的一般结构, 并将这些消息组成不同部分. 本格式描述这些部分如何组成字节序列. 从高层看, 二进制消息由以下部分组成:
- 成帧指示符 (Framing indicator) - 一个整数, 描述消息是请求还是响应, 以及后续各节如何格式化
- 对于响应 (For a response) - 零个或多个信息性响应 (每个响应包含状态码和头部节)
- 控制数据 (Control data) - 请求方法/目标 (用于请求) 或状态码 (用于响应)
- 头部节 (Header section) - 零个或多个头字段
- 内容 (Content) - 零个或多个字节组成的序列
- 尾部节 (Trailer section) - 零个或多个尾字段
- 可选填充 (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. 填充和截断
可以向消息追加任意数量的零值字节作为填充. 消息可以在特定边界处截断, 而不会因此变为无效.