@@ -76,8 +76,7 @@ const DefaultMaxIdleConnsPerHost = 2
76
76
// Transport uses HTTP/1.1 for HTTP URLs and either HTTP/1.1 or HTTP/2
77
77
// for HTTPS URLs, depending on whether the server supports HTTP/2,
78
78
// and how the Transport is configured. The [DefaultTransport] supports HTTP/2.
79
- // To explicitly enable HTTP/2 on a transport, use golang.org/x/net/http2
80
- // and call ConfigureTransport. See the package docs for more about HTTP/2.
79
+ // To explicitly enable HTTP/2 on a transport, set [Transport.Protocols].
81
80
//
82
81
// Responses with status codes in the 1xx range are either handled
83
82
// automatically (100 expect-continue) or ignored. The one
@@ -300,6 +299,13 @@ type Transport struct {
300
299
// This field does not yet have any effect.
301
300
// See https://go.dev/issue/67813.
302
301
HTTP2 * HTTP2Config
302
+
303
+ // Protocols is the set of protocols supported by the transport.
304
+ //
305
+ // If Protocols is nil, the default is usually HTTP/1 only.
306
+ // If ForceAttemptHTTP2 is true, or if TLSNextProto contains an "h2" entry,
307
+ // the default is HTTP/1 and HTTP/2.
308
+ Protocols * Protocols
303
309
}
304
310
305
311
func (t * Transport ) writeBufferSize () int {
@@ -349,6 +355,10 @@ func (t *Transport) Clone() *Transport {
349
355
t2 .HTTP2 = & HTTP2Config {}
350
356
* t2 .HTTP2 = * t .HTTP2
351
357
}
358
+ if t .Protocols != nil {
359
+ t2 .Protocols = & Protocols {}
360
+ * t2 .Protocols = * t .Protocols
361
+ }
352
362
if ! t .tlsNextProtoWasNil {
353
363
npm := maps .Clone (t .TLSNextProto )
354
364
if npm == nil {
@@ -399,18 +409,8 @@ func (t *Transport) onceSetNextProtoDefaults() {
399
409
}
400
410
}
401
411
402
- if t .TLSNextProto != nil {
403
- // This is the documented way to disable http2 on a
404
- // Transport.
405
- return
406
- }
407
- if ! t .ForceAttemptHTTP2 && (t .TLSClientConfig != nil || t .Dial != nil || t .DialContext != nil || t .hasCustomTLSDialer ()) {
408
- // Be conservative and don't automatically enable
409
- // http2 if they've specified a custom TLS config or
410
- // custom dialers. Let them opt-in themselves via
411
- // http2.ConfigureTransport so we don't surprise them
412
- // by modifying their tls.Config. Issue 14275.
413
- // However, if ForceAttemptHTTP2 is true, it overrides the above checks.
412
+ protocols := t .protocols ()
413
+ if ! protocols .HTTP2 () {
414
414
return
415
415
}
416
416
if omitBundledHTTP2 {
@@ -437,6 +437,40 @@ func (t *Transport) onceSetNextProtoDefaults() {
437
437
t2 .MaxHeaderListSize = uint32 (limit1 )
438
438
}
439
439
}
440
+
441
+ // Server.ServeTLS clones the tls.Config before modifying it.
442
+ // Transport doesn't. We may want to make the two consistent some day.
443
+ //
444
+ // http2configureTransport will have already set NextProtos, but adjust it again
445
+ // here to remove HTTP/1.1 if the user has disabled it.
446
+ t .TLSClientConfig .NextProtos = adjustNextProtos (t .TLSClientConfig .NextProtos , protocols )
447
+ }
448
+
449
+ func (t * Transport ) protocols () Protocols {
450
+ if t .Protocols != nil {
451
+ return * t .Protocols // user-configured set
452
+ }
453
+ var p Protocols
454
+ p .SetHTTP1 (true ) // default always includes HTTP/1
455
+ switch {
456
+ case t .TLSNextProto != nil :
457
+ // Setting TLSNextProto to an empty map is is a documented way
458
+ // to disable HTTP/2 on a Transport.
459
+ if t .TLSNextProto ["h2" ] != nil {
460
+ p .SetHTTP2 (true )
461
+ }
462
+ case ! t .ForceAttemptHTTP2 && (t .TLSClientConfig != nil || t .Dial != nil || t .DialContext != nil || t .hasCustomTLSDialer ()):
463
+ // Be conservative and don't automatically enable
464
+ // http2 if they've specified a custom TLS config or
465
+ // custom dialers. Let them opt-in themselves via
466
+ // Transport.Protocols.SetHTTP2(true) so we don't surprise them
467
+ // by modifying their tls.Config. Issue 14275.
468
+ // However, if ForceAttemptHTTP2 is true, it overrides the above checks.
469
+ case http2client .Value () == "0" :
470
+ default :
471
+ p .SetHTTP2 (true )
472
+ }
473
+ return p
440
474
}
441
475
442
476
// ProxyFromEnvironment returns the URL of the proxy to use for a
0 commit comments