http2: support getting the Server connection's base context from net/http
This is the x/net/http2 half of the fix. The net/http half is in CL 181260.
Updates golang/go#32476
Updates golang/go#30694
Change-Id: Ic25c678dad99acc4ae8d679384d9e9a38dc1291c
Reviewed-on: https://go-review.googlesource.com/c/net/+/181259
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/http2/server.go b/http2/server.go
index d4abeb2..57334dc 100644
--- a/http2/server.go
+++ b/http2/server.go
@@ -273,7 +273,20 @@
if testHookOnConn != nil {
testHookOnConn()
}
+ // The TLSNextProto interface predates contexts, so
+ // the net/http package passes down its per-connection
+ // base context via an exported but unadvertised
+ // method on the Handler. This is for internal
+ // net/http<=>http2 use only.
+ var ctx context.Context
+ type baseContexter interface {
+ BaseContext() context.Context
+ }
+ if bc, ok := h.(baseContexter); ok {
+ ctx = bc.BaseContext()
+ }
conf.ServeConn(c, &ServeConnOpts{
+ Context: ctx,
Handler: h,
BaseConfig: hs,
})
@@ -284,6 +297,10 @@
// ServeConnOpts are options for the Server.ServeConn method.
type ServeConnOpts struct {
+ // Context is the base context to use.
+ // If nil, context.Background is used.
+ Context context.Context
+
// BaseConfig optionally sets the base configuration
// for values. If nil, defaults are used.
BaseConfig *http.Server
@@ -294,6 +311,13 @@
Handler http.Handler
}
+func (o *ServeConnOpts) context() context.Context {
+ if o.Context != nil {
+ return o.Context
+ }
+ return context.Background()
+}
+
func (o *ServeConnOpts) baseConfig() *http.Server {
if o != nil && o.BaseConfig != nil {
return o.BaseConfig
@@ -439,7 +463,7 @@
}
func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) {
- ctx, cancel = context.WithCancel(context.Background())
+ ctx, cancel = context.WithCancel(opts.context())
ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())
if hs := opts.baseConfig(); hs != nil {
ctx = context.WithValue(ctx, http.ServerContextKey, hs)