diff --git a/kernel/model/assets.go b/kernel/model/assets.go index d0e8faab0..90d41d641 100644 --- a/kernel/model/assets.go +++ b/kernel/model/assets.go @@ -38,7 +38,6 @@ import ( "github.com/88250/lute/html" "github.com/88250/lute/parse" "github.com/gabriel-vasile/mimetype" - "github.com/imroc/req/v3" "github.com/siyuan-note/filelock" "github.com/siyuan-note/httpclient" "github.com/siyuan-note/logging" @@ -101,11 +100,8 @@ func NetAssets2LocalAssets(rootID string, onlyImg bool, originalURL string) (err } } - browserClient := req.C(). - SetUserAgent(util.UserAgent). - SetTimeout(30 * time.Second). - EnableInsecureSkipVerify(). - SetProxy(httpclient.ProxyFromEnvironment) + browserClient := util.CreateCustomReqClient(). + EnableInsecureSkipVerify() // 添加了自定义TLS指纹, 可以完成对于CDN的资源下载 forbiddenCount := 0 destNodes := getRemoteAssetsLinkDestsInTree(tree, onlyImg) diff --git a/kernel/util/tls.go b/kernel/util/tls.go new file mode 100644 index 000000000..8bd338f76 --- /dev/null +++ b/kernel/util/tls.go @@ -0,0 +1,93 @@ +// SiYuan - Refactor your thinking +// Copyright (c) 2020-present, b3log.org +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package util + +import ( + "crypto/tls" + "net" + "net/http" + "time" + + "github.com/imroc/req/v3" + "github.com/siyuan-note/httpclient" +) + +// createCustomTLSConfig 创建自定义 TLS 配置 +func createCustomTLSConfig() *tls.Config { + return &tls.Config{ + InsecureSkipVerify: false, + MinVersion: tls.VersionTLS12, + MaxVersion: tls.VersionTLS13, + + // 模拟 Chrome 的密码套件顺序 + CipherSuites: []uint16{ + tls.TLS_AES_128_GCM_SHA256, + tls.TLS_AES_256_GCM_SHA384, + tls.TLS_CHACHA20_POLY1305_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + }, + + CurvePreferences: []tls.CurveID{ + tls.X25519, + tls.CurveP256, + tls.CurveP384, + }, + } +} + +// CreateCustomHTTPClient 创建自定义 HTTP 客户端 +func CreateCustomHTTPClient() *http.Client { + dialer := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + } + + transport := &http.Transport{ + TLSClientConfig: createCustomTLSConfig(), + DialContext: dialer.DialContext, + MaxIdleConns: 100, + MaxIdleConnsPerHost: 10, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ResponseHeaderTimeout: 10 * time.Second, + ForceAttemptHTTP2: false, + TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper), + } + + return &http.Client{ + Transport: transport, + Timeout: 60 * time.Second, + } +} + +// CreateCustomReqClient 创建自定义 req 客户端 +func CreateCustomReqClient() *req.Client { + client := req.C() + + client.SetTLSClientConfig(createCustomTLSConfig()) + + client.SetUserAgent(UserAgent). + SetTimeout(30 * time.Second). + SetProxy(httpclient.ProxyFromEnvironment) + + return client +}