跳到主要内容

2. HTTP 数据报

HTTP 数据报 (HTTP Datagrams) 是一种约定, 用于在 HTTP 连接内传送双向且可能不可靠的数据报, 并在可行时进行复用. 所有 HTTP 数据报都与一个 HTTP 请求相关联.

当 HTTP 数据报在 HTTP/3 连接上传送时, 可以使用 QUIC DATAGRAM 帧提供解复用和不可靠交付; 见第 2.1 节. 为 HTTP 数据报协商使用 QUIC DATAGRAM 帧, 是通过交换 HTTP/3 设置来完成的; 见第 2.1.1 节.

在 HTTP/2 上运行时, 解复用由 HTTP/2 成帧层提供, 但不提供不可靠交付. HTTP 数据报使用 Capsule Protocol 进行协商和传送; 见第 3.5 节.

在 HTTP/1.x 上运行时, 请求在连接中严格串行化; 因此不提供解复用. 同样也不提供不可靠交付. HTTP 数据报使用 Capsule Protocol 进行协商和传送; 见第 3.5 节.

HTTP 数据报必须只在与明确支持它们的 HTTP 请求相关联时发送. 例如, 现有 HTTP 方法 GET 和 POST 没有为关联的 HTTP 数据报定义语义; 因此, 不能发送与 GET 或 POST 请求流关联的 HTTP 数据报.

如果接收到 HTTP 数据报, 且它关联的请求没有已知的 HTTP 数据报语义, 接收方必须终止该请求. 如果正在使用 HTTP/3, 请求流必须以 H3_DATAGRAM_ERROR (0x33) 中止. HTTP 扩展可以通过为 HTTP 数据报定义协商机制和语义来覆盖这些要求.

2.1. HTTP/3 数据报

与 HTTP/3 一起使用时, QUIC DATAGRAM 帧的 Datagram Data 字段使用以下格式:

HTTP/3 Datagram {
Quarter Stream ID (i),
HTTP Datagram Payload (..),
}

图 1: HTTP/3 数据报格式

Quarter Stream ID: 一个可变长度整数, 其中包含与此数据报关联的客户端发起双向流的值除以四后的结果 (除以四源于这样一个事实: HTTP 请求在客户端发起的双向流上发送, 而这些流的流 ID 可被四整除). 最大合法 QUIC 流 ID 值为 2^62-1, 因此 Quarter Stream ID 字段的最大合法值为 2^60-1. 收到包含更大值的 HTTP/3 数据报必须被视为类型为 H3_DATAGRAM_ERROR (0x33) 的 HTTP/3 连接错误.

HTTP Datagram Payload: 数据报的载荷, 其语义由使用 HTTP 数据报的扩展定义. 请注意, 该字段可以为空.

收到载荷短到无法解析 Quarter Stream ID 字段的 QUIC DATAGRAM 帧, 必须被视为类型为 H3_DATAGRAM_ERROR (0x33) 的 HTTP/3 连接错误.

除非对应流的发送侧处于打开状态, 否则禁止发送 HTTP/3 数据报. 如果在对应流的接收侧关闭后收到数据报, 则必须静默丢弃收到的数据报.

如果收到 HTTP/3 数据报, 且其 Quarter Stream ID 字段映射到一个尚未创建的流, 接收方应静默丢弃该数据报, 或在等待对应流创建期间临时缓冲该数据报 (大约一个往返时间).

如果收到 HTTP/3 数据报, 且其 Quarter Stream ID 字段映射到一个由于客户端发起双向流限制而无法创建的流, 则应当将其视为类型为 H3_ID_ERROR 的 HTTP/3 连接错误. 生成错误并非强制要求, 因为 QUIC 流限制可能对 HTTP/3 层不可知.

本文档未定义 HTTP/3 数据报的优先级处理. 未来扩展可以定义如何对数据报进行优先级排序, 并可以定义允许传达优先级偏好的信令.

2.1.1. SETTINGS_H3_DATAGRAM HTTP/3 设置

端点可以通过发送值为 1 的 SETTINGS_H3_DATAGRAM (0x33) 设置, 向对端表明其愿意接收 HTTP/3 数据报.

SETTINGS_H3_DATAGRAM 设置的值必须为 0 或 1. 值 0 表示该实现不愿意接收 HTTP 数据报. 如果收到的 SETTINGS_H3_DATAGRAM 设置值既不是 0 也不是 1, 接收方必须以错误 H3_SETTINGS_ERROR 终止连接.

在 SETTINGS_H3_DATAGRAM 设置已发送且已接收, 且其值均为 1 之前, 禁止发送 QUIC DATAGRAM 帧.

当客户端使用 0-RTT 时, 可以存储服务器 SETTINGS_H3_DATAGRAM 设置的值. 这样做允许客户端在 0-RTT 分组中发送 QUIC DATAGRAM 帧. 当服务器决定接受 0-RTT 数据时, 它们必须发送一个 SETTINGS_H3_DATAGRAM 设置, 其值大于或等于它们在向客户端发送 NewSessionTicket 消息的连接中所发送的值. 如果客户端将 SETTINGS_H3_DATAGRAM 设置值与其 0-RTT 状态一起存储, 则必须验证服务器在握手中发送的 SETTINGS_H3_DATAGRAM 设置新值大于或等于已存储值; 否则, 客户端必须以错误 H3_SETTINGS_ERROR 终止连接. 在所有情况下, SETTINGS_H3_DATAGRAM 设置参数允许的最大值为 1.

推荐支持接收 HTTP/3 数据报的实现始终发送值为 1 的 SETTINGS_H3_DATAGRAM 设置, 即使应用不打算使用 HTTP/3 数据报. 这有助于避免 "sticking out" (显得突出); 见第 4 节.

2.2. 使用 Capsule 的 HTTP 数据报

当 HTTP/3 数据报不可用或不适合使用时, 可以使用 Capsule Protocol 发送 HTTP 数据报; 见第 3.5 节.