9. Extensions to HTTP/3 (HTTP/3扩展)
HTTP/3允许通过扩展协议来增强功能。扩展是可选的,可以由实现决定是否支持。本节描述如何定义和使用HTTP/3扩展。
9.1 扩展机制
HTTP/3使用与HTTP/2相同的扩展机制。扩展可以使用:
- 新的帧类型(第7.2节)
- 新的SETTINGS参数(第7.2.4节)
- 新的错误代码(第8节)
- 新的单向流类型(第6.2节)
9.2 扩展发现
HTTP/3支持贪婪扩展发现 (greedy extension discovery),通过保留特定值的空间:
- 保留的帧类型:
0x1f * N + 0x21 - 保留的SETTINGS标识符:
0x1f * N + 0x21 - 保留的错误代码:
0x1f * N + 0x21 - 保留的流类型:
0x1f * N + 0x21
其中N是非负整数(0, 1, 2, ...)
贪婪发现的目的
保留这些值允许实现:
- 测试对未知扩展的处理
- 防止实现对特定值产生依赖
- 确保协议的可扩展性
处理保留值
实现必须 (MUST):
- 不明确发送这些保留值(除非用于测试)
- 将接收到的这些值视为未知值并忽略
- 不将这些值视为错误
9.3 扩展协商
扩展可以通过以下方式协商:
SETTINGS帧协商
客户端 → 服务器: SETTINGS { EXTENSION_FOO = 1 }
服务器 → 客户端: SETTINGS { EXTENSION_FOO = 1 }
结果: 扩展FOO已启用
ALPN协商
某些扩展可能需要在TLS握手期间通过ALPN协商:
ClientHello: ALPN = ["h3-foo", "h3"]
ServerHello: ALPN = "h3-foo"
结果: 使用带扩展FOO的HTTP/3
9.4 扩展设计指南
定义HTTP/3扩展时应考虑:
1. 向后兼容性
- 扩展应该 (SHOULD) 设计为可选
- 不支持扩展的端点应该 (SHOULD) 能够正常运行
2. 协商机制
- 明确定义扩展如何协商
- 使用SETTINGS或ALPN
3. 影响范围
- 明确扩展影响流、连接还是两者
- 定义扩展如何与其他扩展交互
4. 安全考虑
- 分析扩展的安全影响
- 考虑隐私影响
9.5 已知的HTTP/3扩展
虽然本文档不定义特定扩展,但以下是已知的HTTP/3扩展示例:
Extended CONNECT
- 参考:[RFC 8441]
- 目的:允许CONNECT方法用于非TCP协议(如WebSocket over HTTP/3)
- 协商:SETTINGS_ENABLE_CONNECT_PROTOCOL
WebTransport
- 目的:在HTTP/3上提供双向数据流
- 使用:游戏、实时应用
QPACK Dynamic Table
- 参考:[RFC 9204]
- 目的:HTTP/3的头部压缩
- 集成:QPACK编码器和解码器流
扩展示例:自定义流类型
假设我们想定义一个新的单向流类型用于日志传输:
// 定义新的流类型
STREAM_TYPE_LOGGING = 0x54
// 流格式
Logging Stream {
Stream Type (i) = 0x54,
Log Entry (..) ...,
}
Log Entry {
Timestamp (i),
Level (i),
Message Length (i),
Message (..),
}
// SETTINGS协商
SETTINGS_ENABLE_LOGGING = 0x1000
协商过程:
- 客户端发送:
SETTINGS { SETTINGS_ENABLE_LOGGING = 1 } - 服务器响应:
SETTINGS { SETTINGS_ENABLE_LOGGING = 1 } - 双方现在可以创建类型为
0x54的流
关键要点:
- HTTP/3具有强大的扩展机制
- 使用SETTINGS、帧类型、流类型和错误代码进行扩展
- 保留值支持贪婪扩展发现
- 扩展应该向后兼容和可选
- 扩展通过SETTINGS或ALPN协商