From a10a209b23f877c80d8a5f3ebda1ce4b492ac3a9 Mon Sep 17 00:00:00 2001 From: Damien Neil Date: Fri, 7 Jan 2022 10:11:08 -0800 Subject: [PATCH] net/http/httputil: ignore CloseNotify when a non-background context is present 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 Reviewed-by: Brad Fitzpatrick Trust: Damien Neil --- src/net/http/httputil/reverseproxy.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go index 319e2a3f3f..b7244134f0 100644 --- a/src/net/http/httputil/reverseproxy.go +++ b/src/net/http/httputil/reverseproxy.go @@ -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() -- 2.50.0