diff options
author | Pierre Carru <pierre.carru@eshard.com> | 2020-04-26 09:11:35 +0000 |
---|---|---|
committer | Emmanuel Odeke <emm.odeke@gmail.com> | 2020-04-26 09:26:10 +0000 |
commit | 8bcf2834afdf6a1f7937390903a41518715ef6f5 (patch) | |
tree | 6bb3e48e81d1f481435f375bf42a55aac39ef5d6 /src/net/http/httputil/reverseproxy.go | |
parent | 09630172d45c09e150bd1329e37b74611d4af830 (diff) | |
download | go-8bcf2834afdf6a1f7937390903a41518715ef6f5.tar.gz go-8bcf2834afdf6a1f7937390903a41518715ef6f5.zip |
net/http/httputil: make Switching Protocol requests (e.g. Websockets) cancelable
Ensures that a canceled client request for Switching Protocols
(e.g. h2c, Websockets) will cause the underlying connection to
be terminated.
Adds a goroutine in handleUpgradeResponse in order to select on
the incoming client request's context and appropriately cancel it.
Fixes #35559
Change-Id: I1238e18fd4cce457f034f78d9cdce0e7f93b8bf6
GitHub-Last-Rev: 3629c78493f667703ea99f9f4db5e63ddaaa0e6b
GitHub-Pull-Request: golang/go#38021
Reviewed-on: https://go-review.googlesource.com/c/go/+/224897
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Diffstat (limited to 'src/net/http/httputil/reverseproxy.go')
-rw-r--r-- | src/net/http/httputil/reverseproxy.go | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go index 4d6a085f60..eb17bef979 100644 --- a/src/net/http/httputil/reverseproxy.go +++ b/src/net/http/httputil/reverseproxy.go @@ -526,7 +526,20 @@ func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.R p.getErrorHandler()(rw, req, fmt.Errorf("internal error: 101 switching protocols response with non-writable body")) return } - defer backConn.Close() + + backConnCloseCh := make(chan bool) + go func() { + // Ensure that the cancelation of a request closes the backend. + // See issue https://golang.org/issue/35559. + select { + case <-req.Context().Done(): + case <-backConnCloseCh: + } + backConn.Close() + }() + + defer close(backConnCloseCh) + conn, brw, err := hj.Hijack() if err != nil { p.getErrorHandler()(rw, req, fmt.Errorf("Hijack failed on protocol switch: %v", err)) |