@@ -142,15 +142,24 @@ type Transport struct {
142
142
// If both are set, DialContext takes priority.
143
143
Dial func (network , addr string ) (net.Conn , error )
144
144
145
- // DialTLS specifies an optional dial function for creating
145
+ // DialTLSContext specifies an optional dial function for creating
146
146
// TLS connections for non-proxied HTTPS requests.
147
147
//
148
- // If DialTLS is nil, Dial and TLSClientConfig are used.
148
+ // If DialTLSContext is nil (and the deprecated DialTLS below is also nil),
149
+ // DialContext and TLSClientConfig are used.
149
150
//
150
- // If DialTLS is set, the Dial hook is not used for HTTPS
151
+ // If DialTLSContext is set, the Dial and DialContext hooks are not used for HTTPS
151
152
// requests and the TLSClientConfig and TLSHandshakeTimeout
152
153
// are ignored. The returned net.Conn is assumed to already be
153
154
// past the TLS handshake.
155
+ DialTLSContext func (ctx context.Context , network , addr string ) (net.Conn , error )
156
+
157
+ // DialTLS specifies an optional dial function for creating
158
+ // TLS connections for non-proxied HTTPS requests.
159
+ //
160
+ // Deprecated: Use DialTLSContext instead, which allows the transport
161
+ // to cancel dials as soon as they are no longer needed.
162
+ // If both are set, DialTLSContext takes priority.
154
163
DialTLS func (network , addr string ) (net.Conn , error )
155
164
156
165
// TLSClientConfig specifies the TLS configuration to use with
@@ -286,6 +295,7 @@ func (t *Transport) Clone() *Transport {
286
295
DialContext : t .DialContext ,
287
296
Dial : t .Dial ,
288
297
DialTLS : t .DialTLS ,
298
+ DialTLSContext : t .DialTLSContext ,
289
299
TLSHandshakeTimeout : t .TLSHandshakeTimeout ,
290
300
DisableKeepAlives : t .DisableKeepAlives ,
291
301
DisableCompression : t .DisableCompression ,
@@ -324,6 +334,10 @@ type h2Transport interface {
324
334
CloseIdleConnections ()
325
335
}
326
336
337
+ func (t * Transport ) hasCustomTLSDialer () bool {
338
+ return t .DialTLS != nil || t .DialTLSContext != nil
339
+ }
340
+
327
341
// onceSetNextProtoDefaults initializes TLSNextProto.
328
342
// It must be called via t.nextProtoOnce.Do.
329
343
func (t * Transport ) onceSetNextProtoDefaults () {
@@ -352,7 +366,7 @@ func (t *Transport) onceSetNextProtoDefaults() {
352
366
// Transport.
353
367
return
354
368
}
355
- if ! t .ForceAttemptHTTP2 && (t .TLSClientConfig != nil || t .Dial != nil || t .DialTLS != nil || t .DialContext != nil ) {
369
+ if ! t .ForceAttemptHTTP2 && (t .TLSClientConfig != nil || t .Dial != nil || t .DialContext != nil || t .hasCustomTLSDialer () ) {
356
370
// Be conservative and don't automatically enable
357
371
// http2 if they've specified a custom TLS config or
358
372
// custom dialers. Let them opt-in themselves via
@@ -1185,6 +1199,18 @@ func (q *wantConnQueue) cleanFront() (cleaned bool) {
1185
1199
}
1186
1200
}
1187
1201
1202
+ func (t * Transport ) customDialTLS (ctx context.Context , network , addr string ) (conn net.Conn , err error ) {
1203
+ if t .DialTLSContext != nil {
1204
+ conn , err = t .DialTLSContext (ctx , network , addr )
1205
+ } else {
1206
+ conn , err = t .DialTLS (network , addr )
1207
+ }
1208
+ if conn == nil && err == nil {
1209
+ err = errors .New ("net/http: Transport.DialTLS or DialTLSContext returned (nil, nil)" )
1210
+ }
1211
+ return
1212
+ }
1213
+
1188
1214
// getConn dials and creates a new persistConn to the target as
1189
1215
// specified in the connectMethod. This includes doing a proxy CONNECT
1190
1216
// and/or setting up TLS. If this doesn't return an error, the persistConn
@@ -1435,15 +1461,12 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers
1435
1461
}
1436
1462
return err
1437
1463
}
1438
- if cm .scheme () == "https" && t .DialTLS != nil {
1464
+ if cm .scheme () == "https" && t .hasCustomTLSDialer () {
1439
1465
var err error
1440
- pconn .conn , err = t .DialTLS ( "tcp" , cm .addr ())
1466
+ pconn .conn , err = t .customDialTLS ( ctx , "tcp" , cm .addr ())
1441
1467
if err != nil {
1442
1468
return nil , wrapErr (err )
1443
1469
}
1444
- if pconn .conn == nil {
1445
- return nil , wrapErr (errors .New ("net/http: Transport.DialTLS returned (nil, nil)" ))
1446
- }
1447
1470
if tc , ok := pconn .conn .(* tls.Conn ); ok {
1448
1471
// Handshake here, in case DialTLS didn't. TLSNextProto below
1449
1472
// depends on it for knowing the connection state.
0 commit comments