From fcc5c73bc08d2ea9275586f5e0e6dd46e39dddbc Mon Sep 17 00:00:00 2001 From: RedwindA Date: Sat, 27 Sep 2025 22:18:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AB=AF=E7=BC=93=E5=AD=98=E5=92=8C=E9=87=8D?= =?UTF-8?q?=E7=BD=AE=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BC=98=E5=8C=96=20HTTP?= =?UTF-8?q?=20=E5=AE=A2=E6=88=B7=E7=AB=AF=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- service/http_client.go | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/service/http_client.go b/service/http_client.go index b191ddd7..dfed9b54 100644 --- a/service/http_client.go +++ b/service/http_client.go @@ -7,12 +7,17 @@ import ( "net/http" "net/url" "one-api/common" + "sync" "time" "golang.org/x/net/proxy" ) -var httpClient *http.Client +var ( + httpClient *http.Client + proxyClientLock sync.Mutex + proxyClients = make(map[string]*http.Client) +) func InitHttpClient() { if common.RelayTimeout == 0 { @@ -28,12 +33,31 @@ func GetHttpClient() *http.Client { return httpClient } +// ResetProxyClientCache 清空代理客户端缓存,确保下次使用时重新初始化 +func ResetProxyClientCache() { + proxyClientLock.Lock() + defer proxyClientLock.Unlock() + for _, client := range proxyClients { + if transport, ok := client.Transport.(*http.Transport); ok && transport != nil { + transport.CloseIdleConnections() + } + } + proxyClients = make(map[string]*http.Client) +} + // NewProxyHttpClient 创建支持代理的 HTTP 客户端 func NewProxyHttpClient(proxyURL string) (*http.Client, error) { if proxyURL == "" { return http.DefaultClient, nil } + proxyClientLock.Lock() + if client, ok := proxyClients[proxyURL]; ok { + proxyClientLock.Unlock() + return client, nil + } + proxyClientLock.Unlock() + parsedURL, err := url.Parse(proxyURL) if err != nil { return nil, err @@ -41,11 +65,15 @@ func NewProxyHttpClient(proxyURL string) (*http.Client, error) { switch parsedURL.Scheme { case "http", "https": - return &http.Client{ + client := &http.Client{ Transport: &http.Transport{ Proxy: http.ProxyURL(parsedURL), }, - }, nil + } + proxyClientLock.Lock() + proxyClients[proxyURL] = client + proxyClientLock.Unlock() + return client, nil case "socks5", "socks5h": // 获取认证信息 @@ -67,13 +95,17 @@ func NewProxyHttpClient(proxyURL string) (*http.Client, error) { return nil, err } - return &http.Client{ + client := &http.Client{ Transport: &http.Transport{ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { return dialer.Dial(network, addr) }, }, - }, nil + } + proxyClientLock.Lock() + proxyClients[proxyURL] = client + proxyClientLock.Unlock() + return client, nil default: return nil, fmt.Errorf("unsupported proxy scheme: %s", parsedURL.Scheme)