From 0cbb6d75f3e5344da0ab8e0749fca458c1bb5962 Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Fri, 25 Jun 2021 10:56:42 +0100 Subject: [PATCH] attempt fix of h2 dialer by discarding http client on failure https://github.com/v2fly/v2ray-core/issues/1056#issuecomment-868321840 --- transport/internet/http/dialer.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/transport/internet/http/dialer.go b/transport/internet/http/dialer.go index e64a54a54..1f67c75e7 100644 --- a/transport/internet/http/dialer.go +++ b/transport/internet/http/dialer.go @@ -25,16 +25,24 @@ var ( globalDialerAccess sync.Mutex ) -func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.Config) *http.Client { +type dialerCanceller func() + +func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.Config) (*http.Client, dialerCanceller) { globalDialerAccess.Lock() defer globalDialerAccess.Unlock() + canceller := func() { + globalDialerAccess.Lock() + defer globalDialerAccess.Unlock() + delete(globalDialerMap, dest) + } + if globalDialerMap == nil { globalDialerMap = make(map[net.Destination]*http.Client) } if client, found := globalDialerMap[dest]; found { - return client + return client, canceller } transport := &http2.Transport{ @@ -81,7 +89,7 @@ func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.C } globalDialerMap[dest] = client - return client + return client, canceller } // Dial dials a new TCP connection to the given destination. @@ -91,7 +99,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me if tlsConfig == nil { return nil, newError("TLS must be enabled for http transport.").AtWarning() } - client := getHTTPClient(ctx, dest, tlsConfig) + client, canceller := getHTTPClient(ctx, dest, tlsConfig) opts := pipe.OptionsFromContext(ctx) preader, pwriter := pipe.New(opts...) @@ -129,6 +137,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me response, err := client.Do(request) // nolint: bodyclose if err != nil { + canceller() return nil, newError("failed to dial to ", dest).Base(err).AtWarning() } if response.StatusCode != 200 {