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]

Reply via email to