fix redirectHTTP middleware, add bypass.user_agents option

This commit is contained in:
yusing 2025-03-01 04:55:29 +08:00
parent 9c04065c33
commit 68929631f2
2 changed files with 33 additions and 11 deletions

View file

@ -1,6 +1,7 @@
package middleware package middleware
import ( import (
"net"
"net/http" "net/http"
"strings" "strings"
@ -8,22 +9,43 @@ import (
"github.com/yusing/go-proxy/internal/logging" "github.com/yusing/go-proxy/internal/logging"
) )
type redirectHTTP struct{} type redirectHTTP struct {
Bypass struct {
UserAgents []string
}
}
var RedirectHTTP = NewMiddleware[redirectHTTP]() var RedirectHTTP = NewMiddleware[redirectHTTP]()
// before implements RequestModifier. // 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 { if r.TLS != nil {
return true return true
} }
r.URL.Scheme = "https"
host := r.Host if len(m.Bypass.UserAgents) > 0 {
if i := strings.Index(host, ":"); i != -1 { ua := r.UserAgent()
host = host[:i] // strip port number if present for _, uaBypass := range m.Bypass.UserAgents {
} if strings.Contains(ua, uaBypass) {
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 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
} }

View file

@ -14,7 +14,7 @@ func TestRedirectToHTTPs(t *testing.T) {
reqURL: types.MustParseURL("http://example.com"), reqURL: types.MustParseURL("http://example.com"),
}) })
ExpectNoError(t, err) 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) ExpectEqual(t, result.ResponseHeaders.Get("Location"), "https://example.com:"+common.ProxyHTTPSPort)
} }