This is an automated email from the ASF dual-hosted git repository. hsluoyz pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/casbin-gateway.git
commit 4f2be9ac4618d3b9675e4707f9c6cf07f5f8f25c Author: Yang Luo <[email protected]> AuthorDate: Fri Sep 4 23:12:09 2026 +0800 fix(providers): name this gateway in the User-Agent, not Go's default --- controllers/proxy.go | 4 ++-- proxy/proxy.go | 32 ++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/controllers/proxy.go b/controllers/proxy.go index 127b11b..ab0c21b 100644 --- a/controllers/proxy.go +++ b/controllers/proxy.go @@ -182,7 +182,7 @@ type routingFields struct { // It has no overall Timeout on purpose, see proxyResponseHeaderTimeout. var proxyClient = &http.Client{ CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }, - Transport: &http.Transport{ + Transport: proxy.WithUserAgent(&http.Transport{ Proxy: proxy.Proxy, DialContext: (&net.Dialer{ Timeout: 10 * time.Second, @@ -194,7 +194,7 @@ var proxyClient = &http.Client{ TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, ResponseHeaderTimeout: proxyResponseHeaderTimeout, - }, + }), } // ChatCompletions is the OpenAI-compatible chat completions proxy endpoint. diff --git a/proxy/proxy.go b/proxy/proxy.go index 27bfab1..ea165ce 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -37,9 +37,14 @@ var ( proxyUrl *url.URL transportOnce sync.Once - transport *http.Transport + transport http.RoundTripper ) +// UserAgent identifies this gateway to the upstreams it calls. Go leaves the +// header at "Go-http-client/1.1", which the bot filters in front of several +// relays refuse outright with a 403 and an HTML error page. +const UserAgent = "casbin-gateway" + func InitHttpClient() { // Reading the setting here rather than on first use keeps the "proxy // enabled" line in the startup log. @@ -63,14 +68,33 @@ func Proxy(req *http.Request) (*url.URL, error) { // Transport returns the shared transport for outbound requests. Sharing one // instance keeps the connection pool shared as well. -func Transport() *http.Transport { +func Transport() http.RoundTripper { transportOnce.Do(func() { - transport = http.DefaultTransport.(*http.Transport).Clone() - transport.Proxy = Proxy + base := http.DefaultTransport.(*http.Transport).Clone() + base.Proxy = Proxy + transport = WithUserAgent(base) }) return transport } +// WithUserAgent names this gateway on every request that does not already +// carry a User-Agent of its own, so a request forwarding the caller's keeps it. +func WithUserAgent(base http.RoundTripper) http.RoundTripper { + return userAgentTransport{base: base} +} + +type userAgentTransport struct { + base http.RoundTripper +} + +func (t userAgentTransport) RoundTrip(req *http.Request) (*http.Response, error) { + if _, ok := req.Header["User-Agent"]; !ok { + req = req.Clone(req.Context()) + req.Header.Set("User-Agent", UserAgent) + } + return t.base.RoundTrip(req) +} + // currentProxyUrl parses the httpProxy setting, re-parsing it only when the // setting itself has changed. func currentProxyUrl() *url.URL { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
