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 <bradfitz@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Trust: Damien Neil <dneil@google.com>
This commit is contained in:
Damien Neil 2022-01-07 10:11:08 -08:00
parent b88600f926
commit a10a209b23

View 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()