Skip to content

fix(proxydial): preserve buffered CONNECT tunnel data - #102

Closed
idealistichacker wants to merge 1 commit into
Mag1cFall:mainfrom
idealistichacker:fix/connect-buffered-tunnel-data
Closed

idealistichacker wants to merge 1 commit into
Mag1cFall:mainfrom
idealistichacker:fix/connect-buffered-tunnel-data

Conversation

@idealistichacker

Copy link
Copy Markdown

问题

HTTP CONNECT 成功后,http.ReadResponse(bufio.NewReader(connection), request) 可能把响应头之后的隧道字节预读进 bufio.Reader。当前实现丢弃该 reader,直接返回底层连接,导致预读字节永久丢失。通过本机 SOCKS5 relay 的连接也会经过这条路径。

本地复现:假代理在一次写入中发送 200 Connection Established 响应头和 256 字节二进制数据,然后关闭连接。修复前,直接调用 Dialer 和通过 StartRelay 两种情况均读取到 0/256 字节,EOF。

改动

  • 保留解析 CONNECT 响应使用的 reader;有预读数据时返回包装连接,Read 继续读取同一 reader。
  • 没有预读数据时仍返回原连接。
  • 写入、关闭、地址与 deadline 委托给底层 net.Conn。
  • 转发 CloseWrite,避免 relay 的半关闭退化为关闭整个连接,截断对端在收到 EOF 后才发送的最后回复。
  • 不修改账号、认证、请求重试、指纹或公开 API 行为,不新增依赖。

验证

所有网络测试仅监听 127.0.0.1,不连接真实代理、Google 或模型服务,也不读取真实凭据。

  • RED:新增 TestCONNECTPreservesDataAfterResponseHeaders 在原实现的 direct / relay 两个子测试均因 0/256 字节、EOF 失败。
  • GREEN:go test ./internal/proxydial -count=50 通过。
  • Windows/amd64、Go 1.27.3:go test ./internal/proxydial -run TestCONNECT -count=100 通过。
  • Linux WSL、Go 1.27.3、GCC:CGO_ENABLED=1 go test -race -count=50 ./internal/proxydial 通过。
  • go test ./internal/config ./internal/i18n ./internal/proxydial 通过(i18n 无测试文件)。
  • go vet ./internal/config ./internal/i18n ./internal/proxydial 通过。
  • CGO_ENABLED=0 go build ./internal/proxydial、gofmt、git diff --check 通过。
  • 新增半关闭测试:客户端先读到代理附带的 greeting,发送 request 后 CloseWrite;对端读到 EOF 后才回传 request,客户端仍读到完整回复。
  • 原有上游代理凭据成功/失败、双向 echo 测试仍通过。

测试通过 channel 等待假代理完成,连接带 deadline;没有用 sleep 判断数据是否已到达。未运行需要 SpiderMonkey/音频等原生组件的应用全量构建/测试,未启动真实浏览器或账号。HTTPS 代理的真实证书握手未单独覆盖;修改位于 HTTP/HTTPS 共用的 CONNECT 响应读取路径。

AI 辅助

代码、回归测试和本 PR 描述由 OpenAI Codex 在账号所有者授权下自主准备。只声明上面实际执行过的验证。

@Mag1cFall

Copy link
Copy Markdown
Owner

据我所知只有smtp这种服务端先呼叫的协议才可能触发这个PR考虑的场景,或者是代理违反协议、在回复后附带了数据
若你看过net/http标准库的做法,他也是丢弃这个带缓冲的读取器,所以这个PR解决的场景本身并不成立,我暂且直接关闭PR了,如果真的有实际场景出现此问题,你可以再打开,谢谢!

@Mag1cFall Mag1cFall closed this Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants