Reuse Client

pull/3813/head
风扇滑翔翼 2025-07-26 08:10:15 +00:00 committed by GitHub
parent 9bd719aa1a
commit 53cf8ca599
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 28 additions and 21 deletions

View File

@ -88,7 +88,10 @@ type echConfigRecord struct {
expire time.Time expire time.Time
} }
var GlobalECHConfigCache = utils.NewTypedSyncMap[string, *ECHConfigCache]() var (
GlobalECHConfigCache = utils.NewTypedSyncMap[string, *ECHConfigCache]()
clientForECHDOH = utils.NewTypedSyncMap[string, *http.Client]()
)
// Update updates the ECH config for given domain and server. // Update updates the ECH config for given domain and server.
// this method is concurrent safe, only one update request will be sent, others get the cache. // this method is concurrent safe, only one update request will be sent, others get the cache.
@ -164,26 +167,30 @@ func dnsQuery(server string, domain string) ([]byte, uint32, error) {
if err != nil { if err != nil {
return []byte{}, 0, err return []byte{}, 0, err
} }
// All traffic sent by core should via xray's internet.DialSystem var client *http.Client
// This involves the behavior of some Android VPN GUI clients if client, _ = clientForECHDOH.Load(server); client == nil {
tr := &http.Transport{ // All traffic sent by core should via xray's internet.DialSystem
IdleConnTimeout: 90 * time.Second, // This involves the behavior of some Android VPN GUI clients
ForceAttemptHTTP2: true, tr := &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { IdleConnTimeout: 90 * time.Second,
dest, err := net.ParseDestination(network + ":" + addr) ForceAttemptHTTP2: true,
if err != nil { DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return nil, err dest, err := net.ParseDestination(network + ":" + addr)
} if err != nil {
conn, err := internet.DialSystem(ctx, dest, nil) return nil, err
if err != nil { }
return nil, err conn, err := internet.DialSystem(ctx, dest, nil)
} if err != nil {
return conn, nil return nil, err
}, }
} return conn, nil
client := &http.Client{ },
Timeout: 5 * time.Second, }
Transport: tr, c := &http.Client{
Timeout: 5 * time.Second,
Transport: tr,
}
client, _ = clientForECHDOH.LoadOrStore(server, c)
} }
req, err := http.NewRequest("POST", server, bytes.NewReader(msg)) req, err := http.NewRequest("POST", server, bytes.NewReader(msg))
if err != nil { if err != nil {