From fcfe5e721c51e7edc247888ee50c22deb1bdde19 Mon Sep 17 00:00:00 2001 From: Yilin Jing Date: Fri, 27 Feb 2026 15:23:19 +0800 Subject: [PATCH] fix: explicitly set ProxyConnectHeader for HTTPS CONNECT proxy auth Go's http.Transport does not auto-retry 407 for CONNECT tunnels. Must set Proxy-Authorization header upfront via ProxyConnectHeader. --- backend/internal/service/kickstarter_graph.go | 9 +++++++++ backend/internal/service/kickstarter_rest.go | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/backend/internal/service/kickstarter_graph.go b/backend/internal/service/kickstarter_graph.go index 1c9e9d3..5f8d0d0 100644 --- a/backend/internal/service/kickstarter_graph.go +++ b/backend/internal/service/kickstarter_graph.go @@ -2,6 +2,7 @@ package service import ( "bytes" + "encoding/base64" "encoding/json" "fmt" "io" @@ -45,6 +46,14 @@ func NewKickstarterGraphClient(proxyURL string) *KickstarterGraphClient { parsed, err := url.Parse(proxyURL) if err == nil { transport.Proxy = http.ProxyURL(parsed) + // Explicitly set Proxy-Authorization for HTTPS CONNECT tunneling. + // Go's http.Transport does not auto-retry 407 challenges for CONNECT. + if parsed.User != nil { + creds := base64.StdEncoding.EncodeToString([]byte(parsed.User.String())) + transport.ProxyConnectHeader = http.Header{ + "Proxy-Authorization": []string{"Basic " + creds}, + } + } log.Printf("KickstarterGraphClient: using proxy %s://%s", parsed.Scheme, parsed.Host) } else { log.Printf("KickstarterGraphClient: invalid proxy URL, ignoring: %v", err) diff --git a/backend/internal/service/kickstarter_rest.go b/backend/internal/service/kickstarter_rest.go index 40290db..a64577c 100644 --- a/backend/internal/service/kickstarter_rest.go +++ b/backend/internal/service/kickstarter_rest.go @@ -1,6 +1,7 @@ package service import ( + "encoding/base64" "encoding/json" "fmt" "log" @@ -57,6 +58,12 @@ func NewKickstarterRESTClient(proxyURL string) *KickstarterRESTClient { parsed, err := url.Parse(proxyURL) if err == nil { transport.Proxy = http.ProxyURL(parsed) + if parsed.User != nil { + creds := base64.StdEncoding.EncodeToString([]byte(parsed.User.String())) + transport.ProxyConnectHeader = http.Header{ + "Proxy-Authorization": []string{"Basic " + creds}, + } + } log.Printf("KickstarterRESTClient: using proxy %s://%s", parsed.Scheme, parsed.Host) } else { log.Printf("KickstarterRESTClient: invalid proxy URL, ignoring: %v", err)