mirror of
https://github.com/golang/go
synced 2024-11-25 09:07:58 -07:00
net/http/httputil: remove hop-by-hop headers in ReverseProxy
Fixes #2735 R=golang-dev, rsc CC=golang-dev https://golang.org/cl/7470048
This commit is contained in:
parent
2f0a970bde
commit
c6e8993e79
@ -81,6 +81,19 @@ func copyHeader(dst, src http.Header) {
|
||||
}
|
||||
}
|
||||
|
||||
// Hop-by-hop headers. These are removed when sent to the backend.
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
|
||||
var hopHeaders = []string{
|
||||
"Connection",
|
||||
"Keep-Alive",
|
||||
"Proxy-Authenticate",
|
||||
"Proxy-Authorization",
|
||||
"Te", // canonicalized version of "TE"
|
||||
"Trailers",
|
||||
"Transfer-Encoding",
|
||||
"Upgrade",
|
||||
}
|
||||
|
||||
func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
transport := p.Transport
|
||||
if transport == nil {
|
||||
@ -96,14 +109,21 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
outreq.ProtoMinor = 1
|
||||
outreq.Close = false
|
||||
|
||||
// Remove the connection header to the backend. We want a
|
||||
// persistent connection, regardless of what the client sent
|
||||
// to us. This is modifying the same underlying map from req
|
||||
// (shallow copied above) so we only copy it if necessary.
|
||||
if outreq.Header.Get("Connection") != "" {
|
||||
outreq.Header = make(http.Header)
|
||||
copyHeader(outreq.Header, req.Header)
|
||||
outreq.Header.Del("Connection")
|
||||
// Remove hop-by-hop headers to the backend. Especially
|
||||
// important is "Connection" because we want a persistent
|
||||
// connection, regardless of what the client sent to us. This
|
||||
// is modifying the same underlying map from req (shallow
|
||||
// copied above) so we only copy it if necessary.
|
||||
copiedHeaders := false
|
||||
for _, h := range hopHeaders {
|
||||
if outreq.Header.Get(h) != "" {
|
||||
if !copiedHeaders {
|
||||
outreq.Header = make(http.Header)
|
||||
copyHeader(outreq.Header, req.Header)
|
||||
copiedHeaders = true
|
||||
}
|
||||
outreq.Header.Del(h)
|
||||
}
|
||||
}
|
||||
|
||||
if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
|
||||
|
@ -29,6 +29,9 @@ func TestReverseProxy(t *testing.T) {
|
||||
if c := r.Header.Get("Connection"); c != "" {
|
||||
t.Errorf("handler got Connection header value %q", c)
|
||||
}
|
||||
if c := r.Header.Get("Upgrade"); c != "" {
|
||||
t.Errorf("handler got Keep-Alive header value %q", c)
|
||||
}
|
||||
if g, e := r.Host, "some-name"; g != e {
|
||||
t.Errorf("backend got Host header %q, want %q", g, e)
|
||||
}
|
||||
@ -49,6 +52,7 @@ func TestReverseProxy(t *testing.T) {
|
||||
getReq, _ := http.NewRequest("GET", frontend.URL, nil)
|
||||
getReq.Host = "some-name"
|
||||
getReq.Header.Set("Connection", "close")
|
||||
getReq.Header.Set("Upgrade", "foo")
|
||||
getReq.Close = true
|
||||
res, err := http.DefaultClient.Do(getReq)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user