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


The following commit(s) were added to refs/heads/master by this push:
     new d83c6ba  fix: route outbound requests through the configured httpProxy
d83c6ba is described below

commit d83c6bad291dd8bae3edd325b952d44ec0c02133
Author: Yang Luo <[email protected]>
AuthorDate: Tue Aug 18 18:22:24 2026 +0800

    fix: route outbound requests through the configured httpProxy
---
 controllers/proxy.go        |   3 +-
 object/cert_whois.go        |   6 ---
 object/channel.go           |   4 +-
 object/site_cert_account.go |   3 +-
 proxy/proxy.go              | 103 +++++++++++++++++++++-----------------------
 5 files changed, 57 insertions(+), 62 deletions(-)

diff --git a/controllers/proxy.go b/controllers/proxy.go
index 892d29a..45b9dc1 100644
--- a/controllers/proxy.go
+++ b/controllers/proxy.go
@@ -27,6 +27,7 @@ import (
        "time"
 
        "github.com/apache/casbin-gateway/object"
+       "github.com/apache/casbin-gateway/proxy"
        "github.com/beego/beego"
 )
 
@@ -77,7 +78,7 @@ type openaiErrorDetail struct {
 var proxyClient = &http.Client{
        CheckRedirect: func(*http.Request, []*http.Request) error { return 
http.ErrUseLastResponse },
        Transport: &http.Transport{
-               Proxy: http.ProxyFromEnvironment,
+               Proxy: proxy.Proxy,
                DialContext: (&net.Dialer{
                        Timeout:   10 * time.Second,
                        KeepAlive: 30 * time.Second,
diff --git a/object/cert_whois.go b/object/cert_whois.go
index 9513a8a..85c678a 100644
--- a/object/cert_whois.go
+++ b/object/cert_whois.go
@@ -47,12 +47,6 @@ func getDomainExpireTime(domainName string) (string, error) {
        }
 
        client := whois.NewClient()
-       //if server != "whois.cnnic.cn" && server != "grs-whois.hichina.com" {
-       //      dialer := proxy.GetProxyDialer()
-       //      if dialer != nil {
-       //              client.SetDialer(dialer)
-       //      }
-       //}
 
        data, err := client.Whois(domainName, server)
        if err != nil {
diff --git a/object/channel.go b/object/channel.go
index a638b47..b11489c 100644
--- a/object/channel.go
+++ b/object/channel.go
@@ -23,6 +23,7 @@ import (
        "strings"
        "time"
 
+       "github.com/apache/casbin-gateway/proxy"
        "github.com/apache/casbin-gateway/util"
        "github.com/xorm-io/core"
 )
@@ -304,7 +305,8 @@ func TestChannelConnectivity(channel *Channel) (bool, int, 
string) {
        }
 
        client := &http.Client{
-               Timeout: 10 * time.Second,
+               Timeout:   10 * time.Second,
+               Transport: proxy.Transport(),
                // Do not follow redirects, so the reported status is the one 
the
                // configured base URL actually returns.
                CheckRedirect: func(*http.Request, []*http.Request) error { 
return http.ErrUseLastResponse },
diff --git a/object/site_cert_account.go b/object/site_cert_account.go
index 5755f70..5a1f546 100644
--- a/object/site_cert_account.go
+++ b/object/site_cert_account.go
@@ -17,6 +17,7 @@ package object
 import (
        "crypto"
        "fmt"
+       "net/http"
 
        "github.com/apache/casbin-gateway/proxy"
        "github.com/beego/beego"
@@ -70,7 +71,7 @@ func getLegoClientAndAccount(email string, privateKey string, 
devMode bool, useP
        if useProxy {
                config.HTTPClient = proxy.ProxyHttpClient
        } else {
-               config.HTTPClient = proxy.DefaultHttpClient
+               config.HTTPClient = http.DefaultClient
        }
 
        client, err := lego.NewClient(config)
diff --git a/proxy/proxy.go b/proxy/proxy.go
index 0b2535e..ff955fb 100644
--- a/proxy/proxy.go
+++ b/proxy/proxy.go
@@ -12,83 +12,80 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// Package proxy routes every outbound request through the proxy configured as
+// httpProxy in conf/app.conf, falling back to the HTTP_PROXY / HTTPS_PROXY
+// environment variables when that setting is empty.
 package proxy
 
 import (
        "fmt"
-       "net"
        "net/http"
-       "time"
+       "net/url"
+       "strings"
+       "sync"
 
        "github.com/beego/beego"
-       "golang.org/x/net/proxy"
 )
 
-var DefaultHttpClient *http.Client
+// ProxyHttpClient sends its requests through the configured proxy.
 var ProxyHttpClient *http.Client
 
-func InitHttpClient() {
-       // not use proxy
-       DefaultHttpClient = http.DefaultClient
-
-       // use proxy
-       ProxyHttpClient = getProxyHttpClient()
-}
-
-func isAddressOpen(address string) bool {
-       timeout := time.Millisecond * 100
-       conn, err := net.DialTimeout("tcp", address, timeout)
-       if err != nil {
-               // cannot connect to address, proxy is not active
-               return false
-       }
+var (
+       proxyUrlOnce sync.Once
+       proxyUrl     *url.URL
 
-       if conn != nil {
-               defer conn.Close()
-               fmt.Printf("Socks5 proxy enabled: %s\n", address)
-               return true
-       }
+       transportOnce sync.Once
+       transport     *http.Transport
+)
 
-       return false
+func InitHttpClient() {
+       proxyUrlOnce.Do(initProxyUrl)
+       ProxyHttpClient = &http.Client{Transport: Transport()}
 }
 
-func getProxyHttpClient() *http.Client {
-       httpProxy := beego.AppConfig.String("httpProxy")
-       if httpProxy == "" {
-               return &http.Client{}
-       }
-
-       if !isAddressOpen(httpProxy) {
-               return &http.Client{}
-       }
-
-       // 
https://stackoverflow.com/questions/33585587/creating-a-go-socks5-client
-       dialer, err := proxy.SOCKS5("tcp", httpProxy, nil, proxy.Direct)
-       if err != nil {
-               panic(err)
+// Proxy picks the proxy to reach req through. It is meant to be assigned to
+// http.Transport.Proxy, which calls it per request, so the httpProxy setting 
is
+// read on first use instead of at package initialization: in -tags embed 
builds
+// the embedded conf/app.conf is only loaded once main's init() runs, after 
every
+// imported package has already initialized its own variables.
+func Proxy(req *http.Request) (*url.URL, error) {
+       proxyUrlOnce.Do(initProxyUrl)
+       if proxyUrl == nil {
+               return http.ProxyFromEnvironment(req)
        }
+       return proxyUrl, nil
+}
 
-       tr := &http.Transport{Dial: dialer.Dial}
-       return &http.Client{
-               Transport: tr,
-       }
+// Transport returns the shared transport for outbound requests. Sharing one
+// instance keeps the connection pool shared as well.
+func Transport() *http.Transport {
+       transportOnce.Do(func() {
+               transport = http.DefaultTransport.(*http.Transport).Clone()
+               transport.Proxy = Proxy
+       })
+       return transport
 }
 
-func GetProxyDialer() *net.Dialer {
-       httpProxy := beego.AppConfig.String("httpProxy")
+// initProxyUrl parses the httpProxy setting. A bare "host:port" means SOCKS5,
+// which is what the setting has always been taken to mean; "socks5://",
+// "socks5h://", "http://"; and "https://"; addresses are honoured as written, 
and
+// may carry credentials.
+func initProxyUrl() {
+       httpProxy := strings.TrimSpace(beego.AppConfig.String("httpProxy"))
        if httpProxy == "" {
-               return nil
+               return
        }
 
-       if !isAddressOpen(httpProxy) {
-               return nil
+       if !strings.Contains(httpProxy, "://") {
+               httpProxy = "socks5://" + httpProxy
        }
 
-       // 
https://stackoverflow.com/questions/33585587/creating-a-go-socks5-client
-       dialer, err := proxy.SOCKS5("tcp", httpProxy, nil, proxy.Direct)
-       if err != nil {
-               panic(err)
+       parsedUrl, err := url.Parse(httpProxy)
+       if err != nil || parsedUrl.Host == "" {
+               fmt.Printf("httpProxy is not a valid proxy address, outbound 
traffic is left unproxied: %s\n", httpProxy)
+               return
        }
 
-       return dialer.(*net.Dialer)
+       proxyUrl = parsedUrl
+       fmt.Printf("Proxy enabled for outbound traffic: %s\n", 
proxyUrl.Redacted())
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to