net/http: fix Server.ConnContext modifying context for all new connections
Fixes #35750
Change-Id: I65d38cfc5ddd66131777e104c269cc3559b2471d
GitHub-Last-Rev: 953fdfd49b2be665be43f8148d2a6180dae3b91c
GitHub-Pull-Request: golang/go#35751
Reviewed-on: https://go-review.googlesource.com/c/go/+/208318
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index 9077c0c..a2ab52b 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -6126,6 +6126,39 @@
}
}
+// Issue 35750: check ConnContext not modifying context for other connections
+func TestConnContextNotModifyingAllContexts(t *testing.T) {
+ setParallel(t)
+ defer afterTest(t)
+ type connKey struct{}
+ ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
+ rw.Header().Set("Connection", "close")
+ }))
+ ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context {
+ if got := ctx.Value(connKey{}); got != nil {
+ t.Errorf("in ConnContext, unexpected context key = %#v", got)
+ }
+ return context.WithValue(ctx, connKey{}, "conn")
+ }
+ ts.Start()
+ defer ts.Close()
+
+ var res *Response
+ var err error
+
+ res, err = ts.Client().Get(ts.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ res.Body.Close()
+
+ res, err = ts.Client().Get(ts.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ res.Body.Close()
+}
+
// Issue 30710: ensure that as per the spec, a server responds
// with 501 Not Implemented for unsupported transfer-encodings.
func TestUnsupportedTransferEncodingsReturn501(t *testing.T) {
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 4f1c73d..58aff084 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -2920,16 +2920,17 @@
}
return err
}
+ connCtx := ctx
if cc := srv.ConnContext; cc != nil {
- ctx = cc(ctx, rw)
- if ctx == nil {
+ connCtx = cc(connCtx, rw)
+ if connCtx == nil {
panic("ConnContext returned nil")
}
}
tempDelay = 0
c := srv.newConn(rw)
c.setState(c.rwc, StateNew) // before Serve can return
- go c.serve(ctx)
+ go c.serve(connCtx)
}
}