From 163d68318f8f844fe1aa6423806b6f0273357b07 Mon Sep 17 00:00:00 2001 From: Lemon Date: Tue, 7 Apr 2026 07:46:11 +0800 Subject: [PATCH] feat: support socks5h scheme for proxy settings --- .../executor/codex_websockets_executor.go | 2 +- sdk/proxyutil/proxy.go | 4 ++-- sdk/proxyutil/proxy_test.go | 22 +++++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/internal/runtime/executor/codex_websockets_executor.go b/internal/runtime/executor/codex_websockets_executor.go index 2041cebc..94c9b262 100644 --- a/internal/runtime/executor/codex_websockets_executor.go +++ b/internal/runtime/executor/codex_websockets_executor.go @@ -734,7 +734,7 @@ func newProxyAwareWebsocketDialer(cfg *config.Config, auth *cliproxyauth.Auth) * } switch setting.URL.Scheme { - case "socks5": + case "socks5", "socks5h": var proxyAuth *proxy.Auth if setting.URL.User != nil { username := setting.URL.User.Username() diff --git a/sdk/proxyutil/proxy.go b/sdk/proxyutil/proxy.go index 029efeb7..c0d8b328 100644 --- a/sdk/proxyutil/proxy.go +++ b/sdk/proxyutil/proxy.go @@ -58,7 +58,7 @@ func Parse(raw string) (Setting, error) { } switch parsedURL.Scheme { - case "socks5", "http", "https": + case "socks5", "socks5h", "http", "https": setting.Mode = ModeProxy setting.URL = parsedURL return setting, nil @@ -95,7 +95,7 @@ func BuildHTTPTransport(raw string) (*http.Transport, Mode, error) { case ModeDirect: return NewDirectTransport(), setting.Mode, nil case ModeProxy: - if setting.URL.Scheme == "socks5" { + if setting.URL.Scheme == "socks5" || setting.URL.Scheme == "socks5h" { var proxyAuth *proxy.Auth if setting.URL.User != nil { username := setting.URL.User.Username() diff --git a/sdk/proxyutil/proxy_test.go b/sdk/proxyutil/proxy_test.go index 5b250117..f214bf6d 100644 --- a/sdk/proxyutil/proxy_test.go +++ b/sdk/proxyutil/proxy_test.go @@ -30,6 +30,7 @@ func TestParse(t *testing.T) { {name: "http", input: "http://proxy.example.com:8080", want: ModeProxy}, {name: "https", input: "https://proxy.example.com:8443", want: ModeProxy}, {name: "socks5", input: "socks5://proxy.example.com:1080", want: ModeProxy}, + {name: "socks5h", input: "socks5h://proxy.example.com:1080", want: ModeProxy}, {name: "invalid", input: "bad-value", want: ModeInvalid, wantErr: true}, } @@ -137,3 +138,24 @@ func TestBuildHTTPTransportSOCKS5ProxyInheritsDefaultTransportSettings(t *testin t.Fatalf("TLSHandshakeTimeout = %v, want %v", transport.TLSHandshakeTimeout, defaultTransport.TLSHandshakeTimeout) } } + +func TestBuildHTTPTransportSOCKS5HProxy(t *testing.T) { + t.Parallel() + + transport, mode, errBuild := BuildHTTPTransport("socks5h://proxy.example.com:1080") + if errBuild != nil { + t.Fatalf("BuildHTTPTransport returned error: %v", errBuild) + } + if mode != ModeProxy { + t.Fatalf("mode = %d, want %d", mode, ModeProxy) + } + if transport == nil { + t.Fatal("expected transport, got nil") + } + if transport.Proxy != nil { + t.Fatal("expected SOCKS5H transport to bypass http proxy function") + } + if transport.DialContext == nil { + t.Fatal("expected SOCKS5H transport to have custom DialContext") + } +}