transport/http: don't reuse a base transport between clients (#532)
Previously sync.Once was used to cache a fallback base transport.
This caused a race condition when setting MaxIdleConnsPerHost
and TLSClientConfig in defaultBaseTransport (above). Because of these
settings, it isn't valid to share the base transport across clients.
I conferred with @neild and determined that it is impossible to implement a
transport.Clone for < Go 1.13, so instead we should initialize
a new transport with default values each time in this case.
Fixes googleapis/google-cloud-go#2405
diff --git a/transport/http/dial.go b/transport/http/dial.go
index 96cf2e1..19a4c9a 100644
--- a/transport/http/dial.go
+++ b/transport/http/dial.go
@@ -16,7 +16,6 @@
"net/url"
"os"
"strings"
- "sync"
"time"
"go.opencensus.io/plugin/ochttp"
@@ -191,31 +190,23 @@
return trans
}
-var fallback struct {
- *http.Transport
- sync.Once
-}
-
// fallbackBaseTransport is used in <go1.13 as well as in the rare case if
// http.DefaultTransport has been reassigned something that's not a
// *http.Transport.
func fallbackBaseTransport() *http.Transport {
- fallback.Do(func() {
- fallback.Transport = &http.Transport{
- Proxy: http.ProxyFromEnvironment,
- DialContext: (&net.Dialer{
- Timeout: 30 * time.Second,
- KeepAlive: 30 * time.Second,
- DualStack: true,
- }).DialContext,
- MaxIdleConns: 100,
- MaxIdleConnsPerHost: 100,
- IdleConnTimeout: 90 * time.Second,
- TLSHandshakeTimeout: 10 * time.Second,
- ExpectContinueTimeout: 1 * time.Second,
- }
- })
- return fallback.Transport
+ return &http.Transport{
+ Proxy: http.ProxyFromEnvironment,
+ DialContext: (&net.Dialer{
+ Timeout: 30 * time.Second,
+ KeepAlive: 30 * time.Second,
+ DualStack: true,
+ }).DialContext,
+ MaxIdleConns: 100,
+ MaxIdleConnsPerHost: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ }
}
func addOCTransport(trans http.RoundTripper, settings *internal.DialSettings) http.RoundTripper {