]> Cypherpunks repositories - gostls13.git/commitdiff
net/http/httputil: ignore CloseNotify when a non-background context is present
authorDamien Neil <dneil@google.com>
Fri, 7 Jan 2022 18:11:08 +0000 (10:11 -0800)
committerDamien Neil <dneil@google.com>
Thu, 24 Mar 2022 21:51:49 +0000 (21:51 +0000)
If the http.Request passed to ReverseProxy.ServeHTTP has a context
with a non-nil Done channel, don't watch the ResponseWriter's
CloseNotify channel.

Avoids starting an extra background goroutine in the common case.

Change-Id: I1328f3e02d3025caa0f446a2f20dfc14ef604c64
Reviewed-on: https://go-review.googlesource.com/c/go/+/376415
Trust: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Trust: Damien Neil <dneil@google.com>

src/net/http/httputil/reverseproxy.go

index 319e2a3f3f0430af0bb7feaf28f73f97d3d2c930..b7244134f04131ca0151e9046358eb5b2794257e 100644 (file)
@@ -218,7 +218,18 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
        }
 
        ctx := req.Context()
-       if cn, ok := rw.(http.CloseNotifier); ok {
+       if ctx.Done() != nil {
+               // CloseNotifier predates context.Context, and has been
+               // entirely superseded by it. If the request contains
+               // a Context that carries a cancelation signal, don't
+               // bother spinning up a goroutine to watch the CloseNotify
+               // channel (if any).
+               //
+               // If the request Context has a nil Done channel (which
+               // means it is either context.Background, or a custom
+               // Context implementation with no cancelation signal),
+               // then consult the CloseNotifier if available.
+       } else if cn, ok := rw.(http.CloseNotifier); ok {
                var cancel context.CancelFunc
                ctx, cancel = context.WithCancel(ctx)
                defer cancel()