Skip to content

fix: use environment HTTP proxies for CDP connections - #30

Merged
TristanIsK merged 7 commits into
lexmount:mainfrom
TristanIsK:codex/cloud-websocket-proxy
Sep 20, 2026
Merged

TristanIsK merged 7 commits into
lexmount:mainfrom
TristanIsK:codex/cloud-websocket-proxy

Conversation

@TristanIsK

@TristanIsK TristanIsK commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

云端 Agent 配置 HTTP 代理时,原有 HTTP 客户端可以创建浏览器会话,但 CDP WebSocket 仍然直连,导致后续网页操作连接失败。本 PR 在 CLI 和 SDK 共用的 CDP 连接入口支持环境代理,并补齐连接超时及兼容性处理,版本准备为 1.2.1

变更内容

  • 使用与 reqwest 相同的代理匹配器,支持 HTTP_PROXYHTTPS_PROXYALL_PROXY、对应小写变量及 NO_PROXY。仅支持 http:// CONNECT 代理;HTTPS-to-proxy 和 SOCKS 返回明确错误。
  • 代理认证信息仅用于 CONNECT,不转发给目标网站;保留 TLS 证书和主机名校验,代理失败不会回退直连。
  • 直连和代理共用一次 15 秒连接预算,覆盖 DNS、TCP、CONNECT、TLS/WebSocket 握手及重定向;每次阻塞读写都使用剩余时间,重定向或缓慢返回数据不会重置预算。
  • 连接超时关闭未完成的连接,CLI 保留原有 JSON 格式,向 stderr 返回 error: timeout、发生阶段及预算,退出码为 1。错误信息不包含 URL 或凭据。

审查意见及修复

  1. 代理路径丢失重定向行为:保留最多三次重定向,每次跳转重新匹配代理和 NO_PROXY,覆盖直连与代理之间切换。
  2. DNS 解析未纳入连接超时:调用方按同一截止时间停止等待;进程内最多两个 DNS 工作线程、四个排队任务,过期排队任务跳过,迟到结果不会继续建立连接。保留系统 DNS,以兼容 hosts/VPN;IP 地址直接跳过解析。
  3. SDK 测试受到宿主代理环境影响:SDK 集成测试在清理代理变量的独立子进程中运行,本地 HTTP 模拟客户端仅在测试中禁用代理;CI 额外使用不可用代理配置重复运行测试。
  4. 下游启用 native-tls 后连接被错误拒绝:移除握手后仅接受 Plain/Rustls 的判断,解除连接预算不再依赖 TLS 后端类型。下游 Cargo features 合并启用 native-tls 时也能正常连接。
  5. Windows 上连接成功后仍残留超时:通过 Arc<TcpStream> 共享同一个操作系统句柄进行读写和超时清除,避免依赖复制句柄的行为;完成清理后设置连接完成标志,后续 CDP 读写不再受连接预算影响。

已确认的边界

系统正在执行的 DNS 查询无法强制取消;调用方超时退出后,后台资源仍受上述上限约束。容量耗尽时,新域名查询明确返回 DNS resolver busy; retry later,等待工作线程恢复。

15 秒预算结束于 WebSocket 升级完成。REST 会话请求、CDP 目标初始化和后续网页操作保留原有超时行为,因此不是整条 CLI 命令或 Agent 对话的总时限;不会自动重试网页操作。公开 SDK 接口保持不变。

验证结果

当前验证提交:248781f

  • 断网 Linux 容器内 40 项 Rust 测试通过;一项需要本地 Chromium 的可选测试跳过。格式检查和 clippy -- -D warnings 通过。
  • 回归覆盖 DNS 阻塞、线程及队列上限、队列过期和恢复、握手停滞、缓慢返回响应、重定向共享预算,以及连接成功后的正常读写。
  • 真实 CLI 测试确认约 15 秒返回超时,stdout 为空、stderr 为结构化 JSON、退出码为 1,连接关闭且未发送网页操作。
  • 独立下游 SDK 测试使用临时可信 CA,验证 Rustls/native-tls 各自的直连和 CONNECT,共四种组合;均完成真实 TLS/WebSocket 握手、CDP 初始化和表达式执行,证书校验保持开启。同一测试在修复前的 74daec6 上能复现 unsupported CDP TLS backend,已接入 CI。
  • 原有握手后读写测试发现了 Windows 超时残留问题;使用同一操作系统句柄后,该测试在 Windows 上通过。
  • 当前提交的四项 CI 全部通过test(含不可用代理环境复测、四种 TLS 组合、格式检查及 clippy)、linux-releasewindows-bootstrapwindows-release
  • 独立子代理完成修复复核及最终整体审查,未发现本 PR 引入且需要阻断合并的新问题。

早期真实 ChatGPT Work 云端验收使用的是 af092b0 构建产物,已通过版本检查、doctor、创建会话、打开 example.com、快照、标题、截图和关闭会话;该记录不能作为当前提交的云端复测结果。

发布说明

本 PR 已于 2026-09-20 由用户合并,合并提交为 b41e08524b13729fa0b84b595a4b4acffdc3b865CLI v1.2.1 已正式发布,三平台二进制已上传 GitHub 和 COS,公开下载及 SHA256 校验通过;发布流水线全部成功。插件 1.1.19 草稿的 CLI 产物依赖已满足;本次未提交插件审核,当前正式包尚未重新进行真实 ChatGPT Work 云端验收。

@TristanIsK
TristanIsK marked this pull request as ready for review September 18, 2026 10:55
Comment thread src/cdp/proxy.rs Outdated
@TristanIsK

Copy link
Copy Markdown
Collaborator Author

codex云 agent 运行的沙箱,网络请求会走代理,因此需要判断 http_proxy 环境变量来适配环境。

@254808127

Copy link
Copy Markdown
Collaborator

[P2] 15 秒连接超时未覆盖代理 DNS 解析 — proxy.rs:90
to_socket_addrs() 在检查剩余时间之前同步解析代理域名。DNS 响应缓慢时,连接仍可能阻塞超过 15 秒;后面的 connect_timeout 无法中断这一步。建议将解析也纳入超时控制。Rust 文档确认该调用可能阻塞线程

[P2] SDK 集成测试会受到宿主机代理配置影响,已复现 — cdp.rs:56
改为读取环境代理后,现有 SDK 测试连接本地模拟服务器时也会走代理,但这些测试没有隔离环境。设置 HTTP_PROXY=http://127.0.0.1:1、清除 NO_PROXY 后,sdk_selects_the_requested_target_regardless_of_enumeration_order 出现 ConnectionRefused。建议在隔离的子进程中配置测试环境,或注入测试用 matcher。

@TristanIsK
TristanIsK merged commit b41e085 into lexmount:main Sep 20, 2026
4 checks passed
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