From 9c017ff30dd21bbdcdb11f39458d3944db530d7e Mon Sep 17 00:00:00 2001 From: Aofei Sheng Date: Sat, 26 Sep 2020 13:21:41 +0800 Subject: [PATCH] net/http/httputil: copy response header back to http.ResponseWriter in ReverseProxy.handleUpgradeResponse Fixes: #41634 Change-Id: Ib78cc37a4d2ca0753d567eafb616238e4103484e Reviewed-on: https://go-review.googlesource.com/c/go/+/257777 Reviewed-by: Damien Neil Trust: Damien Neil Trust: Brad Fitzpatrick Run-TryBot: Damien Neil TryBot-Result: Go Bot --- src/net/http/httputil/reverseproxy.go | 6 ++++-- src/net/http/httputil/reverseproxy_test.go | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go index 46e5f68a843..4e369580ea8 100644 --- a/src/net/http/httputil/reverseproxy.go +++ b/src/net/http/httputil/reverseproxy.go @@ -549,8 +549,6 @@ func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.R return } - copyHeader(res.Header, rw.Header()) - hj, ok := rw.(http.Hijacker) if !ok { p.getErrorHandler()(rw, req, fmt.Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw)) @@ -581,6 +579,10 @@ func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.R return } defer conn.Close() + + copyHeader(rw.Header(), res.Header) + + res.Header = rw.Header() res.Body = nil // so res.Write only writes the headers; we have res.Body in backConn above if err := res.Write(brw); err != nil { p.getErrorHandler()(rw, req, fmt.Errorf("response write: %v", err)) diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go index ea786864d8b..cc05d55d879 100644 --- a/src/net/http/httputil/reverseproxy_test.go +++ b/src/net/http/httputil/reverseproxy_test.go @@ -1157,6 +1157,9 @@ func TestReverseProxyWebSocket(t *testing.T) { handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { rw.Header().Set("X-Header", "X-Value") rproxy.ServeHTTP(rw, req) + if got, want := rw.Header().Get("X-Modified"), "true"; got != want { + t.Errorf("response writer X-Modified header = %q; want %q", got, want) + } }) frontendProxy := httptest.NewServer(handler)