86 lines
7.0 KiB
Markdown
86 lines
7.0 KiB
Markdown
# WebSocket 验收记录(2026-10-29)
|
||
|
||
本次增加通用 WS Client/Server/Session、Hub、可选 RPC/订阅恢复、观测、App 生命周期与生成项目扩展。对应版本 `v0.31.0-preview`,本文记录源码验证;远程发布验收单独记录。
|
||
|
||
## 结论
|
||
|
||
- 功能、真实 TCP/TLS、并发竞态、静态检查、Go 1.22 兼容性和可运行 Go 示例通过。
|
||
- 最终全库回归输出见 [websocket-regression-go1.25.txt](websocket-regression-go1.25.txt);Go 1.27.3 下 `go test ./ws/...` 也通过。生成示例只同步 appGen 与清单,生成漂移检查及消费项目编译通过;新增生成消费回归验证了自定义路由和失败清理。
|
||
- Origin 模糊测试发现并修复无括号 IPv6 归一化歧义,失败样本保留在 `ws/testdata/fuzz/FuzzOrigin`;修复后 10 秒约 552,325 次执行通过。
|
||
- 新增核心包在隔离 Go 1.27.3 工具链、govulncheck v1.9.0 下扫描未发现已知漏洞。
|
||
- **包含 ws/omni 的完整接入安全扫描未通过**:仓库原有 `golang.org/x/net v0.33.0` 报告 4 项 HTTP/2 可达漏洞。不能将本次功能验收解释为整个框架已通过安全发布门槛。
|
||
- 浏览器自动化访问 `http://127.0.0.1:8088` 被浏览器权限策略拒绝,因此浏览器 UI/浏览器协议实测未完成;不以 Go 客户端测试代替这一项。示例源文件可供手动运行,临时服务已停止。
|
||
|
||
## 功能与并发验证
|
||
|
||
使用 Apple M2 Max / darwin arm64,主测试工具链 Go 1.25.0。独立 Go 1.22.12 用于最低版本兼容检查,没有替换系统 Go。
|
||
|
||
执行过:
|
||
|
||
```sh
|
||
go test ./...
|
||
go test -race -count=5 -timeout=120s ./ws/... ./examples/websocketRPC ./app ./httpx
|
||
go test -race -coverprofile=/tmp/go-omni-websocket-coverage.out ./ws/...
|
||
go vet ./ws/... ./app ./httpx ./examples/websocket ./examples/websocketRPC
|
||
GOTOOLCHAIN=go1.22.12 go test ./ws/... ./app ./httpx
|
||
go test ./ws -run '^$' -fuzz FuzzOrigin -fuzztime=10s -parallel=4
|
||
go test ./ws/rpc -run '^$' -fuzz FuzzProtocolDecode -fuzztime=10s
|
||
go run ./examples/websocket
|
||
go run ./examples/websocketRPC
|
||
```
|
||
|
||
真实网络覆盖:回显、文本/二进制、128 个并行连接各 50 次往返、TLS/mTLS、HTTP CONNECT 代理认证、握手取消/超时、重连时刷新认证头、重试预算、快速重连与连接上限、双向嵌套 RPC、断线后两代 Session 的订阅恢复。
|
||
|
||
最终审查另修复了远端 `1001 going away` 被当成本地主动关闭、导致 Run 不重连的问题,并验证本地主动关闭仍停止重试;补充累计拨号/失败/重连指标和配置上界。修复后 `go test -race -count=3 ./ws/...` 通过。
|
||
|
||
安全与资源覆盖:同源/白名单/无 Origin/重复 Origin/null、拒绝错误子协议、认证拒绝与 panic、连接/握手速率限额、非法 UTF-8、压缩膨胀限额、发送数据拷贝、接收队列满、慢消费者、阻塞业务时仍处理 Ping/Pong、取消写入、断网、反复关闭、握手与停止并发、回调未退出时保留共享资源。
|
||
|
||
RPC 覆盖:双向请求、取消、迟到回复、重复在途 ID、未知字段、重复 JSON 键、嵌套深度、消息长度、pending/执行并发上限、公共与内部错误区分、panic 脱敏、订阅期望状态与恢复。RPC fuzz 10 秒约 71,268 次执行通过。
|
||
|
||
覆盖率快照:
|
||
|
||
| 包 | 语句覆盖率 |
|
||
| --- | ---: |
|
||
| ws | 84.7% |
|
||
| ws/hub | 86.5% |
|
||
| ws/observe | 88.4% |
|
||
| ws/omni | 86.7% |
|
||
| ws/rpc | 80.7% |
|
||
|
||
覆盖率只描述这组测试执行到的代码,不等同于正确性或安全证明。测试不包含生产长时间浸泡、跨地区网络容量、HTTP/2 extended CONNECT 或 Autobahn 全套认证。
|
||
|
||
## 性能基准
|
||
|
||
```sh
|
||
go test -run '^$' -bench . -benchmem -benchtime=500ms -count=3 ./ws/...
|
||
```
|
||
|
||
原始输出:[websocket-bench-go1.25.txt](websocket-bench-go1.25.txt)。环境为 Apple M2 Max、Go 1.25.0、GOMAXPROCS=12、loopback、无 TLS、压缩关闭。三次样本的范围如下;首轮客户端样本与其它验证有时间重叠,保留原始波动,不选取单个最好值作为承诺。
|
||
|
||
| 基准 | 时间/操作 | 分配 |
|
||
| --- | ---: | ---: |
|
||
| Client 回声往返(9 B) | 26.0–47.3 μs | 1520 B / 13 allocs |
|
||
| Server 回声往返(64 B) | 23.6–24.3 μs | 1568 B / 13 allocs |
|
||
| Server 回声往返(1 KiB) | 26.4–30.6 μs | 7136 B / 17 allocs |
|
||
| Server 回声往返(64 KiB) | 140.9–145.2 μs | 约 636 KB / 45 allocs |
|
||
| Session 发送(256 B) | 5.34–5.37 μs | 1168 B / 9 allocs |
|
||
| Hub 广播到 1000 个模拟连接 | 64.7–65.4 μs | 约 54.7 KB / 6 allocs |
|
||
| 内存传输 RPC Call | 17.6–17.8 μs | 8386 B / 193 allocs |
|
||
| 严格 RPC envelope 解析 | 4.68–4.89 μs | 3656 B / 106 allocs |
|
||
|
||
网络往返基准包括双方处理及本机 socket 成本;64 KiB 场景的分配包含双方完整读入及安全发送拷贝,后续大消息优化需在保持消息所有权的前提下进行。Hub 基准仅测注册表和分发,RPC 内存基准不包含网络。这里没有从单连接 loopback 数字外推生产 QPS 或最大连接数。
|
||
|
||
内存预算需按连接数乘以消息/队列上限估算,并额外计入解码中消息、协议缓冲和业务持有的 payload。默认 4096 连接上限并不意味着任何机器都能承受所有连接同时用满双向 4 MiB 队列。部署时需根据机器容量设置 MaxConnections、消息与队列字节数、RPC 执行并发;压缩及 TLS 应另做容量测量。
|
||
|
||
## 漏洞扫描与剩余风险
|
||
|
||
扫描包含源码可达性分析,不是人工证明每条告警均可利用。没有隐藏、忽略或豁免扫描结果。
|
||
|
||
1. Go 1.25.0 + govulncheck v1.1.4 扫描 `./ws/...`:29 项标准库 symbol findings,以及 4 项 x/net symbol findings;Gorilla WebSocket 没有报告项。工具链版本是现有本机版本。扫描结果摘要保留在 [JSON](websocket-vuln-go1.25.json)。
|
||
2. 隔离 Go 1.27.3 + govulncheck v1.9.0 扫描 `./ws/...`:标准库告警消除,剩余 4 项 x/net HTTP/2 findings,详见 [完整输出](websocket-vuln-patched-go.txt)。
|
||
3. 同一修补工具链扫描 `./ws ./ws/hub ./ws/rpc ./ws/observe`:`No vulnerabilities found.`,见 [输出](websocket-vuln-core-patched-go.txt)。这不覆盖 ws/omni 引入的原有 App/HTTP2 依赖图。
|
||
|
||
剩余报告:GO-2026-6617(HPACK 并发)、GO-2026-6612(流控退款)、GO-2026-6611(重复窗口变更 CPU)、GO-2026-6603(Trailer 内存)。扫描器给出的修复版本为 `golang.org/x/net v0.60.0`;它的 [官方 go.mod](https://raw.githubusercontent.com/golang/net/v0.60.0/go.mod) 要求 Go 1.26,并升级 x/crypto、x/sys、x/text。此变更会改变框架当前公开的 Go 1.22 基线与多个既有适配器,未在 WS 功能提交中隐式实施。需要作为明确的框架安全升级进行全库与消费项目回归,生产发布前解决。
|
||
|
||
生产应使用受支持且已修补的 Go 工具链。Go 1.22 测试只验证源码兼容,不代表该旧工具链具备当前安全修复。对应标准库证书问题的官方说明见 [GO-2026-6809](https://pkg.go.dev/vuln/GO-2026-6809);HTTP/2 问题见 [GO-2026-6617](https://pkg.go.dev/vuln/GO-2026-6617)。
|