aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas S. Husin <nsh@golang.org>2026-03-30 22:24:12 -0400
committerNicholas Husin <nsh@golang.org>2026-03-31 08:30:49 -0700
commitdb6661a2fd321d4af14efc48492144f86bb50c93 (patch)
treefaaed4e5b01022c1aa8a6e34375ab4af5e930c68
parentaf4c316c28d2dad63851e7384a7aa198ee729aee (diff)
downloadgo-db6661a2fd321d4af14efc48492144f86bb50c93.tar.xz
net/http: support passing Server Shutdown context to HTTP/3 implementations
Currently, when Server.Shutdown is called with a given context, an HTTP/3 server implementation does not have access to said context. This forces HTTP/3 server implementations to guess a reasonable fixed timeout when attempting to gracefully shutdown, which is not ideal. Therefore, add ShutdownContext method to http3ServerHandler to handle this. For #77440 Change-Id: Ib15b615f646fd08788981eb06f3a70606a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/761480 Reviewed-by: Nicholas Husin <husin@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Damien Neil <dneil@google.com>
-rw-r--r--src/net/http/server.go39
1 files changed, 28 insertions, 11 deletions
diff --git a/src/net/http/server.go b/src/net/http/server.go
index c25e83b704..4cd18e9faf 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -3121,6 +3121,7 @@ type Server struct {
activeConn map[*conn]struct{}
onShutdown []func()
h2 *http2Server
+ h3 *http3ServerHandler
listenerGroup sync.WaitGroup
}
@@ -3188,6 +3189,9 @@ func (s *Server) Shutdown(ctx context.Context) error {
s.inShutdown.Store(true)
s.mu.Lock()
+ if s.h3 != nil {
+ s.h3.shutdownCtx = ctx
+ }
lnerr := s.closeListenersLocked()
for _, f := range s.onShutdown {
go f()
@@ -3751,43 +3755,53 @@ func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
// us to test our HTTP/3 implementation againts tests in net/http. HTTP/3 is
// not yet accessible to end-users.
type http3ServerHandler struct {
- handler serverHandler
- tlsConfig *tls.Config
- baseCtx context.Context
- errc chan error
+ handler serverHandler
+ tlsConfig *tls.Config
+ baseCtx context.Context
+ errc chan error
+ shutdownCtx context.Context
}
// ServeHTTP ensures that http3ServerHandler implements the Handler interface,
// and gives an HTTP/3 server implementation access to the net/http handler.
-func (h http3ServerHandler) ServeHTTP(w ResponseWriter, r *Request) {
+func (h *http3ServerHandler) ServeHTTP(w ResponseWriter, r *Request) {
h.handler.ServeHTTP(w, r)
}
// Addr gives an HTTP/3 server implementation the address that it should listen
// on.
-func (h http3ServerHandler) Addr() string {
+func (h *http3ServerHandler) Addr() string {
return h.handler.srv.Addr
}
// TLSConfig gives an HTTP/3 server implementation the *tls.Config that it
// should use.
-func (h http3ServerHandler) TLSConfig() *tls.Config {
+func (h *http3ServerHandler) TLSConfig() *tls.Config {
return h.tlsConfig
}
// BaseContext gives an HTTP/3 server implementation the base context to use
// for server requests.
-func (h http3ServerHandler) BaseContext() context.Context {
+func (h *http3ServerHandler) BaseContext() context.Context {
return h.baseCtx
}
// ListenErrHook should be called by an HTTP/3 server implementation to
// propagate any error it encounters when trying to listen, if any, to
// net/http.
-func (h http3ServerHandler) ListenErrHook(err error) {
+func (h *http3ServerHandler) ListenErrHook(err error) {
h.errc <- err
}
+// ShutdownContext gives an HTTP/3 server implementation the context that is
+// used when [Server.Shutdown] is called. This allows an HTTP/3 server
+// implementation to know how long it can take to gracefully shutdown in the
+// function it registers with [Server.RegisterOnShutdown]. Callers must not use
+// this method for any other purpose.
+func (h *http3ServerHandler) ShutdownContext() context.Context {
+ return h.shutdownCtx
+}
+
// ListenAndServeTLS listens on the TCP network address s.Addr and
// then calls [ServeTLS] to handle requests on incoming TLS connections.
// Accepted connections are configured to enable TCP keep-alives.
@@ -3823,12 +3837,15 @@ func (s *Server) ListenAndServeTLS(certFile, keyFile string) error {
return err
}
errc := make(chan error, 1)
- go fn(s, nil, http3ServerHandler{
+ s.mu.Lock()
+ s.h3 = &http3ServerHandler{
handler: serverHandler{s},
tlsConfig: config,
baseCtx: context.WithValue(context.Background(), ServerContextKey, s),
errc: errc,
- })
+ }
+ s.mu.Unlock()
+ go fn(s, nil, s.h3)
if err := <-errc; err != nil {
return err
}