Commit 21751774 authored by Julien Salleyron's avatar Julien Salleyron Committed by Brad Fitzpatrick

net/http/httputil: fix missing previous headers in response when switching protocol in ReverseProxy

When using switching protocol, previous headers set before the reverse proxy are lost.

Fixes #29407

Change-Id: Ia2b9784022d9bccef8625519ccbabbe8a276dfc0
GitHub-Last-Rev: 79bb493dcbb9b76d9d2ff9cd0854b29d634f8b73
GitHub-Pull-Request: golang/go#29408
Reviewed-on: https://go-review.googlesource.com/c/155741Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 8962b71c
...@@ -497,6 +497,9 @@ func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.R ...@@ -497,6 +497,9 @@ func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.R
p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch protocol %q when %q was requested", resUpType, reqUpType)) p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch protocol %q when %q was requested", resUpType, reqUpType))
return return
} }
copyHeader(res.Header, rw.Header())
hj, ok := rw.(http.Hijacker) hj, ok := rw.(http.Hijacker)
if !ok { if !ok {
p.getErrorHandler()(rw, req, fmt.Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw)) p.getErrorHandler()(rw, req, fmt.Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw))
......
...@@ -1013,7 +1013,12 @@ func TestReverseProxyWebSocket(t *testing.T) { ...@@ -1013,7 +1013,12 @@ func TestReverseProxyWebSocket(t *testing.T) {
rproxy := NewSingleHostReverseProxy(backURL) rproxy := NewSingleHostReverseProxy(backURL)
rproxy.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests rproxy.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
frontendProxy := httptest.NewServer(rproxy) handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("X-Header", "X-Value")
rproxy.ServeHTTP(rw, req)
})
frontendProxy := httptest.NewServer(handler)
defer frontendProxy.Close() defer frontendProxy.Close()
req, _ := http.NewRequest("GET", frontendProxy.URL, nil) req, _ := http.NewRequest("GET", frontendProxy.URL, nil)
...@@ -1028,6 +1033,13 @@ func TestReverseProxyWebSocket(t *testing.T) { ...@@ -1028,6 +1033,13 @@ func TestReverseProxyWebSocket(t *testing.T) {
if res.StatusCode != 101 { if res.StatusCode != 101 {
t.Fatalf("status = %v; want 101", res.Status) t.Fatalf("status = %v; want 101", res.Status)
} }
got := res.Header.Get("X-Header")
want := "X-Value"
if got != want {
t.Errorf("Header(XHeader) = %q; want %q", got, want)
}
if upgradeType(res.Header) != "websocket" { if upgradeType(res.Header) != "websocket" {
t.Fatalf("not websocket upgrade; got %#v", res.Header) t.Fatalf("not websocket upgrade; got %#v", res.Header)
} }
...@@ -1042,8 +1054,8 @@ func TestReverseProxyWebSocket(t *testing.T) { ...@@ -1042,8 +1054,8 @@ func TestReverseProxyWebSocket(t *testing.T) {
if !bs.Scan() { if !bs.Scan() {
t.Fatalf("Scan: %v", bs.Err()) t.Fatalf("Scan: %v", bs.Err())
} }
got := bs.Text() got = bs.Text()
want := `backend got "Hello"` want = `backend got "Hello"`
if got != want { if got != want {
t.Errorf("got %#q, want %#q", got, want) t.Errorf("got %#q, want %#q", got, want)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment