From 22d5d09f1e39bf0ef77bfcf80388c676e7e91574 Mon Sep 17 00:00:00 2001 From: Damien Neil Date: Thu, 6 Mar 2025 13:24:58 -0800 Subject: net/http/httputil: close hijacked connections when CloseWrite not available CL 637939 changed ReverseProxy's handling of hijacked connections: After copying all data in one direction, it half-closes the outbound connection rather than fully closing both. Revert to the old behavior when the outbound connection does not support CloseWrite, avoiding a case where one side of the proxied connection closes but the other remains open. Fixes #72140 Change-Id: Ic0cacaa6323290f89ba48fd6cae737e86045a435 Reviewed-on: https://go-review.googlesource.com/c/go/+/655595 Reviewed-by: Jonathan Amsterdam LUCI-TryBot-Result: Go LUCI Auto-Submit: Damien Neil --- src/net/http/httputil/reverseproxy.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/net/http/httputil/reverseproxy.go') diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go index bbb7c13d41..079d5c86f7 100644 --- a/src/net/http/httputil/reverseproxy.go +++ b/src/net/http/httputil/reverseproxy.go @@ -794,16 +794,19 @@ func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.R go spc.copyToBackend(errc) go spc.copyFromBackend(errc) - // wait until both copy functions have sent on the error channel + // Wait until both copy functions have sent on the error channel, + // or until one fails. err := <-errc if err == nil { err = <-errc } - if err != nil { + if err != nil && err != errCopyDone { p.getErrorHandler()(rw, req, fmt.Errorf("can't copy: %v", err)) } } +var errCopyDone = errors.New("hijacked connection copy complete") + // switchProtocolCopier exists so goroutines proxying data back and // forth have nice names in stacks. type switchProtocolCopier struct { @@ -822,7 +825,7 @@ func (c switchProtocolCopier) copyFromBackend(errc chan<- error) { return } - errc <- nil + errc <- errCopyDone } func (c switchProtocolCopier) copyToBackend(errc chan<- error) { @@ -837,7 +840,7 @@ func (c switchProtocolCopier) copyToBackend(errc chan<- error) { return } - errc <- nil + errc <- errCopyDone } func cleanQueryParams(s string) string { -- cgit v1.3-5-g45d5