From af2d6ad8d2fcfac391e5db7af4d4817aa9bb157b Mon Sep 17 00:00:00 2001 From: Seefs Date: Thu, 15 Jan 2026 14:43:53 +0800 Subject: [PATCH] feat: TLS_INSECURE_SKIP_VERIFY env --- .env.example | 3 +++ common/constants.go | 4 ++++ common/init.go | 11 +++++++++++ controller/model_sync.go | 17 +++++++++++++++-- controller/ratio_sync.go | 4 ++++ service/http_client.go | 39 ++++++++++++++++++++++++--------------- 6 files changed, 61 insertions(+), 17 deletions(-) diff --git a/.env.example b/.env.example index ea9061fb3..f4b9d02ee 100644 --- a/.env.example +++ b/.env.example @@ -57,6 +57,9 @@ # 流模式无响应超时时间,单位秒,如果出现空补全可以尝试改为更大值 # STREAMING_TIMEOUT=300 +# TLS / HTTP 跳过验证设置 +# TLS_INSECURE_SKIP_VERIFY=false + # Gemini 识别图片 最大图片数量 # GEMINI_VISION_MAX_IMAGE_NUM=16 diff --git a/common/constants.go b/common/constants.go index e33a64b22..51b798dbc 100644 --- a/common/constants.go +++ b/common/constants.go @@ -1,6 +1,7 @@ package common import ( + "crypto/tls" //"os" //"strconv" "sync" @@ -73,6 +74,9 @@ var MemoryCacheEnabled bool var LogConsumeEnabled = true +var TLSInsecureSkipVerify bool +var InsecureTLSConfig = &tls.Config{InsecureSkipVerify: true} + var SMTPServer = "" var SMTPPort = 587 var SMTPSSLEnabled = false diff --git a/common/init.go b/common/init.go index 0789f8cc2..9501ce3be 100644 --- a/common/init.go +++ b/common/init.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "log" + "net/http" "os" "path/filepath" "strconv" @@ -81,6 +82,16 @@ func InitEnv() { DebugEnabled = os.Getenv("DEBUG") == "true" MemoryCacheEnabled = os.Getenv("MEMORY_CACHE_ENABLED") == "true" IsMasterNode = os.Getenv("NODE_TYPE") != "slave" + TLSInsecureSkipVerify = GetEnvOrDefaultBool("TLS_INSECURE_SKIP_VERIFY", false) + if TLSInsecureSkipVerify { + if tr, ok := http.DefaultTransport.(*http.Transport); ok && tr != nil { + if tr.TLSClientConfig != nil { + tr.TLSClientConfig.InsecureSkipVerify = true + } else { + tr.TLSClientConfig = InsecureTLSConfig + } + } + } // Parse requestInterval and set RequestInterval requestInterval, _ = strconv.Atoi(os.Getenv("POLLING_INTERVAL")) diff --git a/controller/model_sync.go b/controller/model_sync.go index b2ac99da8..737f92d40 100644 --- a/controller/model_sync.go +++ b/controller/model_sync.go @@ -99,6 +99,9 @@ func newHTTPClient() *http.Client { ExpectContinueTimeout: 1 * time.Second, ResponseHeaderTimeout: time.Duration(timeoutSec) * time.Second, } + if common.TLSInsecureSkipVerify { + transport.TLSClientConfig = common.InsecureTLSConfig + } transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { host, _, err := net.SplitHostPort(addr) if err != nil { @@ -115,7 +118,17 @@ func newHTTPClient() *http.Client { return &http.Client{Transport: transport} } -var httpClient = newHTTPClient() +var ( + httpClientOnce sync.Once + httpClient *http.Client +) + +func getHTTPClient() *http.Client { + httpClientOnce.Do(func() { + httpClient = newHTTPClient() + }) + return httpClient +} func fetchJSON[T any](ctx context.Context, url string, out *upstreamEnvelope[T]) error { var lastErr error @@ -138,7 +151,7 @@ func fetchJSON[T any](ctx context.Context, url string, out *upstreamEnvelope[T]) } cacheMutex.RUnlock() - resp, err := httpClient.Do(req) + resp, err := getHTTPClient().Do(req) if err != nil { lastErr = err // backoff with jitter diff --git a/controller/ratio_sync.go b/controller/ratio_sync.go index b8224b816..0b6a6dff0 100644 --- a/controller/ratio_sync.go +++ b/controller/ratio_sync.go @@ -11,6 +11,7 @@ import ( "sync" "time" + "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/logger" "github.com/QuantumNous/new-api/dto" @@ -110,6 +111,9 @@ func FetchUpstreamRatios(c *gin.Context) { dialer := &net.Dialer{Timeout: 10 * time.Second} transport := &http.Transport{MaxIdleConns: 100, IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, ResponseHeaderTimeout: 10 * time.Second} + if common.TLSInsecureSkipVerify { + transport.TLSClientConfig = common.InsecureTLSConfig + } transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { host, _, err := net.SplitHostPort(addr) if err != nil { diff --git a/service/http_client.go b/service/http_client.go index 783aac899..2c3168f24 100644 --- a/service/http_client.go +++ b/service/http_client.go @@ -40,6 +40,9 @@ func InitHttpClient() { ForceAttemptHTTP2: true, Proxy: http.ProxyFromEnvironment, // Support HTTP_PROXY, HTTPS_PROXY, NO_PROXY env vars } + if common.TLSInsecureSkipVerify { + transport.TLSClientConfig = common.InsecureTLSConfig + } if common.RelayTimeout == 0 { httpClient = &http.Client{ @@ -102,13 +105,17 @@ func NewProxyHttpClient(proxyURL string) (*http.Client, error) { switch parsedURL.Scheme { case "http", "https": + transport := &http.Transport{ + MaxIdleConns: common.RelayMaxIdleConns, + MaxIdleConnsPerHost: common.RelayMaxIdleConnsPerHost, + ForceAttemptHTTP2: true, + Proxy: http.ProxyURL(parsedURL), + } + if common.TLSInsecureSkipVerify { + transport.TLSClientConfig = common.InsecureTLSConfig + } client := &http.Client{ - Transport: &http.Transport{ - MaxIdleConns: common.RelayMaxIdleConns, - MaxIdleConnsPerHost: common.RelayMaxIdleConnsPerHost, - ForceAttemptHTTP2: true, - Proxy: http.ProxyURL(parsedURL), - }, + Transport: transport, CheckRedirect: checkRedirect, } client.Timeout = time.Duration(common.RelayTimeout) * time.Second @@ -137,17 +144,19 @@ func NewProxyHttpClient(proxyURL string) (*http.Client, error) { return nil, err } - client := &http.Client{ - Transport: &http.Transport{ - MaxIdleConns: common.RelayMaxIdleConns, - MaxIdleConnsPerHost: common.RelayMaxIdleConnsPerHost, - ForceAttemptHTTP2: true, - DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - return dialer.Dial(network, addr) - }, + transport := &http.Transport{ + MaxIdleConns: common.RelayMaxIdleConns, + MaxIdleConnsPerHost: common.RelayMaxIdleConnsPerHost, + ForceAttemptHTTP2: true, + DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + return dialer.Dial(network, addr) }, - CheckRedirect: checkRedirect, } + if common.TLSInsecureSkipVerify { + transport.TLSClientConfig = common.InsecureTLSConfig + } + + client := &http.Client{Transport: transport, CheckRedirect: checkRedirect} client.Timeout = time.Duration(common.RelayTimeout) * time.Second proxyClientLock.Lock() proxyClients[proxyURL] = client