HTTP/2 服务器: 为 WebSocket-over-h2 (RFC 8441 服务器端) 广告 SETTINGS_ENABLE_CONNECT_PROTOCOL
摘要
Deno 问题 #11261 ("支持通过 H2 进行 WebSocket") 已于 2026-06-03 关闭,涵盖了 RFC 8441 中的 客户端 部分。服务器端尚未实现:
Deno.serve的 HTTP/2 后端从未发布SETTINGS_ENABLE_CONNECT_PROTOCOL=1,因此支持扩展 CONNECT WebSocket 协议的客户端在 ALPN 协商 h2 时会出现不透明的协议错误。后果: 基于 Deno 的服务器加上基于 Deno 的 WebSocket 客户端无法在 h2 上进行互操作。如果 ALPN 选择 h2,客户端的 WebSocket 升级将失败;如果 ALPN 选择 http/1.1,则会正常工作。
重现
服务器: 任何使用
Deno.serve在 TLS 上的默认 ALPN (提供h2, http/1.1) 并使用处理器中的Deno.upgradeWebSocket的服务器。客户端: 当前版本的 Deno 内置
WebSocket通过wss://与该服务器建立连接。结果: 客户端发出
流错误接收: 检测到不具体的协议错误。h2 扩展 CONNECT 与:protocol: websocket从未完成,因为服务器没有发送SETTINGS_ENABLE_CONNECT_PROTOCOL=1。如果服务器被迫从 ALPN 中删除 h2,则才会正常工作。
通过源代码进行验证
ext/http/http_next.rs: 没有引用enable_connect_protocol、EnableConnectProtocol和:protocol。h2 服务器从未发布该设置。客户端端正常工作: 关闭问题 #11261 引用了修复,确认在 ALPN 选择 h2 时扩展 CONNECT 将被发送。
影响
任何使用 TLS 并需要 WebSocket 的 Deno 服务器-Deno 客户端拓扑都必须从服务器 ALPN 中删除 h2(每个客户端 Pod 中的反向代理侧车)或通过带外标志强制使用 http/1.1。今天在生产环境中我们遇到了此问题,通过为每个客户端 Pod 配置一个 nginx 侧车来解决了问题。
请求
在
Deno.serve中,当处理器调用Deno.upgradeWebSocket时,将SETTINGS_ENABLE_CONNECT_PROTOCOL=1添加到 h2 SETTINGS 帧中。接受带:protocol: websocket的扩展 CONNECT 并将其路由到相同的升级处理器。或者,如果更喜欢运行时标志:在
Deno.serve上暴露选项,例如{ enableConnectProtocol: true }。相关
- 关闭: #11261 (客户端端)。
- RFC 8441: 通过 HTTP/2 进行 WebSocket 启动。
我很乐意测试修复或提供有用的更小的重现。
内容来源: denoland/deno