@@ -10,7 +10,6 @@ import (
10
10
"errors"
11
11
"fmt"
12
12
"io"
13
- "net"
14
13
"net/http"
15
14
"net/http/httptrace"
16
15
"net/http/httputil"
@@ -83,46 +82,54 @@ func NewClient(l logger.Logger, conf Config) *Client {
83
82
84
83
httpClient := conf .HTTPClient
85
84
86
- if conf .HTTPClient == nil {
87
- if conf .DisableHTTP2 {
88
- tr := & http.Transport {
89
- Proxy : http .ProxyFromEnvironment ,
90
- DisableCompression : false ,
91
- DisableKeepAlives : false ,
92
- DialContext : (& net.Dialer {
93
- Timeout : 30 * time .Second ,
94
- KeepAlive : 30 * time .Second ,
95
- }).DialContext ,
96
- MaxIdleConns : 100 ,
97
- IdleConnTimeout : 90 * time .Second ,
98
- TLSHandshakeTimeout : 30 * time .Second ,
99
- TLSNextProto : make (map [string ]func (authority string , c * tls.Conn ) http.RoundTripper ),
100
- }
101
- httpClient = & http.Client {
102
- Timeout : 60 * time .Second ,
103
- Transport : & authenticatedTransport {
104
- Token : conf .Token ,
105
- Delegate : tr ,
106
- },
107
- }
108
- } else {
109
- tr := & http2.Transport {
110
- ReadIdleTimeout : 30 * time .Second ,
111
- }
112
- if conf .TLSConfig != nil {
113
- tr .TLSClientConfig = conf .TLSConfig
114
- }
85
+ if httpClient != nil {
86
+ return & Client {
87
+ logger : l ,
88
+ client : httpClient ,
89
+ conf : conf ,
90
+ }
91
+ }
115
92
116
- httpClient = & http.Client {
117
- Timeout : 60 * time .Second ,
118
- Transport : & authenticatedTransport {
119
- Token : conf .Token ,
120
- Delegate : tr ,
121
- },
122
- }
93
+ // Base any modifications on the default transport.
94
+ transport := http .DefaultTransport .(* http.Transport ).Clone ()
95
+ // Allow override of TLSConfig. This must be set prior to calling
96
+ // http2.ConfigureTransports.
97
+ if conf .TLSConfig != nil {
98
+ transport .TLSClientConfig = conf .TLSConfig
99
+ }
100
+
101
+ if conf .DisableHTTP2 {
102
+ transport .TLSNextProto = make (map [string ]func (string , * tls.Conn ) http.RoundTripper )
103
+ // The default TLSClientConfig has h2 in NextProtos, so the
104
+ // negotiated TLS connection will assume h2 support.
105
+ // see https://github.com/golang/go/issues/50571
106
+ transport .TLSClientConfig .NextProtos = []string {"http/1.1" }
107
+ } else {
108
+ // There is a bug in http2 on Linux regarding using dead connections.
109
+ // This is a workaround. See https://github.com/golang/go/issues/59690
110
+ //
111
+ // Note that http2.ConfigureTransports alters its argument in order to
112
+ // supply http2 functionality, and the http2.Transport does not support
113
+ // HTTP/1.1 as a protocol, so we get slightly odd-looking code where
114
+ // we use `transport` later on instead of the just-returned `tr2`.
115
+ // tr2 is needed merely to configure the http2 option.
116
+ tr2 , err := http2 .ConfigureTransports (transport )
117
+ if err != nil {
118
+ l .Warn ("Failed to configure HTTP2 transports: %v" , err )
119
+ }
120
+ if tr2 != nil {
121
+ tr2 .ReadIdleTimeout = 30 * time .Second
123
122
}
124
123
}
125
124
125
+ httpClient = & http.Client {
126
+ Timeout : 60 * time .Second ,
127
+ Transport : & authenticatedTransport {
128
+ Token : conf .Token ,
129
+ Delegate : transport ,
130
+ },
131
+ }
132
+
126
133
return & Client {
127
134
logger : l ,
128
135
client : httpClient ,
0 commit comments