@@ -2129,8 +2129,8 @@ type Server struct {
2129
2129
ErrorLog * log.Logger
2130
2130
2131
2131
disableKeepAlives int32 // accessed atomically.
2132
- nextProtoOnce sync.Once // guards initialization of TLSNextProto in Serve
2133
- nextProtoErr error
2132
+ nextProtoOnce sync.Once // guards setupHTTP2_* init
2133
+ nextProtoErr error // result of http2.ConfigureServer if used
2134
2134
}
2135
2135
2136
2136
// A ConnState represents the state of a client connection to a server.
@@ -2260,10 +2260,8 @@ func (srv *Server) Serve(l net.Listener) error {
2260
2260
}
2261
2261
var tempDelay time.Duration // how long to sleep on accept failure
2262
2262
2263
- if srv .shouldConfigureHTTP2ForServe () {
2264
- if err := srv .setupHTTP2 (); err != nil {
2265
- return err
2266
- }
2263
+ if err := srv .setupHTTP2_Serve (); err != nil {
2264
+ return err
2267
2265
}
2268
2266
2269
2267
// TODO: allow changing base context? can't imagine concrete
@@ -2408,7 +2406,7 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
2408
2406
2409
2407
// Setup HTTP/2 before srv.Serve, to initialize srv.TLSConfig
2410
2408
// before we clone it and create the TLS Listener.
2411
- if err := srv .setupHTTP2 (); err != nil {
2409
+ if err := srv .setupHTTP2_ListenAndServeTLS (); err != nil {
2412
2410
return err
2413
2411
}
2414
2412
@@ -2436,14 +2434,36 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
2436
2434
return srv .Serve (tlsListener )
2437
2435
}
2438
2436
2439
- func (srv * Server ) setupHTTP2 () error {
2437
+ // setupHTTP2_ListenAndServeTLS conditionally configures HTTP/2 on
2438
+ // srv and returns whether there was an error setting it up. If it is
2439
+ // not configured for policy reasons, nil is returned.
2440
+ func (srv * Server ) setupHTTP2_ListenAndServeTLS () error {
2440
2441
srv .nextProtoOnce .Do (srv .onceSetNextProtoDefaults )
2441
2442
return srv .nextProtoErr
2442
2443
}
2443
2444
2445
+ // setupHTTP2_Serve is called from (*Server).Serve and conditionally
2446
+ // configures HTTP/2 on srv using a more conservative policy than
2447
+ // setupHTTP2_ListenAndServeTLS because Serve may be called
2448
+ // concurrently.
2449
+ //
2450
+ // The tests named TestTransportAutomaticHTTP2* and
2451
+ // TestConcurrentServerServe in server_test.go demonstrate some
2452
+ // of the supported use cases and motivations.
2453
+ func (srv * Server ) setupHTTP2_Serve () error {
2454
+ srv .nextProtoOnce .Do (srv .onceSetNextProtoDefaults_Serve )
2455
+ return srv .nextProtoErr
2456
+ }
2457
+
2458
+ func (srv * Server ) onceSetNextProtoDefaults_Serve () {
2459
+ if srv .shouldConfigureHTTP2ForServe () {
2460
+ srv .onceSetNextProtoDefaults ()
2461
+ }
2462
+ }
2463
+
2444
2464
// onceSetNextProtoDefaults configures HTTP/2, if the user hasn't
2445
2465
// configured otherwise. (by setting srv.TLSNextProto non-nil)
2446
- // It must only be called via srv.nextProtoOnce (use srv.setupHTTP2 ).
2466
+ // It must only be called via srv.nextProtoOnce (use srv.setupHTTP2_* ).
2447
2467
func (srv * Server ) onceSetNextProtoDefaults () {
2448
2468
if strings .Contains (os .Getenv ("GODEBUG" ), "http2server=0" ) {
2449
2469
return
0 commit comments