From 71ad13256effb21e3d5090937a812b7862550592 Mon Sep 17 00:00:00 2001 From: yusing Date: Sat, 1 Mar 2025 04:55:29 +0800 Subject: [PATCH] fix redirectHTTP middleware, add bypass.user_agents option --- internal/net/http/middleware/redirect_http.go | 42 ++++++++++++++----- .../net/http/middleware/redirect_http_test.go | 2 +- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/internal/net/http/middleware/redirect_http.go b/internal/net/http/middleware/redirect_http.go index 95b7dcd..1419d01 100644 --- a/internal/net/http/middleware/redirect_http.go +++ b/internal/net/http/middleware/redirect_http.go @@ -1,6 +1,7 @@ package middleware import ( + "net" "net/http" "strings" @@ -8,22 +9,43 @@ import ( "github.com/yusing/go-proxy/internal/logging" ) -type redirectHTTP struct{} +type redirectHTTP struct { + Bypass struct { + UserAgents []string + } +} var RedirectHTTP = NewMiddleware[redirectHTTP]() // before implements RequestModifier. -func (redirectHTTP) before(w http.ResponseWriter, r *http.Request) (proceed bool) { +func (m *redirectHTTP) before(w http.ResponseWriter, r *http.Request) (proceed bool) { if r.TLS != nil { return true } - r.URL.Scheme = "https" - host := r.Host - if i := strings.Index(host, ":"); i != -1 { - host = host[:i] // strip port number if present + + if len(m.Bypass.UserAgents) > 0 { + ua := r.UserAgent() + for _, uaBypass := range m.Bypass.UserAgents { + if strings.Contains(ua, uaBypass) { + return true + } + } } - r.URL.Host = host + ":" + common.ProxyHTTPSPort - logging.Debug().Str("url", r.URL.String()).Msg("redirect to https") - http.Redirect(w, r, r.URL.String(), http.StatusTemporaryRedirect) - return true + + r.URL.Scheme = "https" + host, _, err := net.SplitHostPort(r.Host) + if err != nil { + host = r.Host + } + + if common.ProxyHTTPSPort != "443" { + r.URL.Host = host + ":" + common.ProxyHTTPSPort + } else { + r.URL.Host = host + } + + http.Redirect(w, r, r.URL.String(), http.StatusMovedPermanently) + + logging.Debug().Str("url", r.URL.String()).Str("user_agent", r.UserAgent()).Msg("redirect to https") + return false } diff --git a/internal/net/http/middleware/redirect_http_test.go b/internal/net/http/middleware/redirect_http_test.go index 82c6581..53221d0 100644 --- a/internal/net/http/middleware/redirect_http_test.go +++ b/internal/net/http/middleware/redirect_http_test.go @@ -14,7 +14,7 @@ func TestRedirectToHTTPs(t *testing.T) { reqURL: types.MustParseURL("http://example.com"), }) ExpectNoError(t, err) - ExpectEqual(t, result.ResponseStatus, http.StatusTemporaryRedirect) + ExpectEqual(t, result.ResponseStatus, http.StatusPermanentRedirect) ExpectEqual(t, result.ResponseHeaders.Get("Location"), "https://example.com:"+common.ProxyHTTPSPort) }