Files
go-omni/reports/websocket-validation-2026-10-29.md

110 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 客户端测试代替这一项。示例源文件可供手动运行,临时服务已停止。
## 远程发布验收
发布标签 `v0.31.0-preview` 固定在提交 `3272974bc1cd19c79efe7354b00b6ed67f27f51e`,已核对远程标签解引用结果。CLI 默认版本与框架版本一致,发布前再次通过全库 `go test ./...` 和 managedService 生成漂移检查。报告随后独立提交,不移动发布标签。
四组验收各自使用空 `GOMODCACHE`、临时 `GOBIN`、`GOWORK=off` 和 Go 1.25.0,从远程安装固定版本 CLI;消费项目均无本地 replace。四组校验和一致:`h1:d0sf951iJwMUtHj29D6BjUwOgg+C79GwQ+2vjAHLjDo=`。
| 验收 | 结果 | 报告 |
| --- | --- | --- |
| WS 发布包 | 6 个包、60 个顶层测试通过 race;11 项检查,含两个可运行示例、两代连接订阅恢复、生成路由与失败清理 | [WS 远程验收](websocket-remote.json) |
| API 受管工程 | 110 项检查,含 11 组生成消费者与旧能力回归 | [API 远程验收](websocket-managed-remote.json) |
| 通用工程 | 30 项检查 | [通用工程远程验收](websocket-program-remote.json) |
| 混合工作区 | 16 项检查 | [工作区远程验收](websocket-workspace-remote.json) |
复验命令(在源码仓库根目录,PATH 选择所需 Go 工具链):
```sh
python3 scripts/verifyWebsocketRelease.py --version v0.31.0-preview --report reports/websocket-remote.json
python3 scripts/verifyManagedRelease.py --version v0.31.0-preview --report reports/websocket-managed-remote.json
python3 scripts/verifyProgramRelease.py --version v0.31.0-preview --report reports/websocket-program-remote.json
python3 scripts/verifyWorkspaceRelease.py --version v0.31.0-preview --report reports/websocket-workspace-remote.json
```
这些结果确认发布内容的功能与消费可用性,不改变下文的工具链、HTTP/2 依赖安全结论和浏览器实测缺口。
## 功能与并发验证
使用 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)。