Fix proxying of unannounced trailers

This commit is contained in:
Fernandez Ludovic 2017-06-29 16:41:44 +02:00 committed by Emile Vauge
parent 6473002021
commit 4699d6be18
3 changed files with 39 additions and 15 deletions

6
glide.lock generated
View file

@ -1,5 +1,5 @@
hash: 9a62fe4058ef43ed185d96638322dd3d44ae21f7f65fae14c4c6d404876c2872
updated: 2017-06-28T15:47:14.848940186+02:00
hash: cebc972cf87c4b0a8f86801f38750c51b09c8dee3bf62bb48f8eaa6ab7946352
updated: 2017-06-29T16:47:14.848940186+02:00
imports:
- name: cloud.google.com/go
version: 2e6a95edb1071d750f6d7db777bf66cd2997af6c
@ -409,7 +409,7 @@ imports:
- name: github.com/vdemeester/docker-events
version: be74d4929ec1ad118df54349fda4b0cba60f849b
- name: github.com/vulcand/oxy
version: ad5bdb606fa9c64db267f0e43d63834908bdb05e
version: 7da864c1d53bd58165435bb78bbf8c01f01c8f4a
repo: https://github.com/containous/oxy.git
vcs: git
subpackages:

View file

@ -8,7 +8,7 @@ import:
- package: github.com/cenk/backoff
- package: github.com/containous/flaeg
- package: github.com/vulcand/oxy
version: ad5bdb606fa9c64db267f0e43d63834908bdb05e
version: 7da864c1d53bd58165435bb78bbf8c01f01c8f4a
repo: https://github.com/containous/oxy.git
vcs: git
subpackages:

View file

@ -159,7 +159,9 @@ func (f *Forwarder) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// serveHTTP forwards HTTP traffic using the configured transport
func (f *httpForwarder) serveHTTP(w http.ResponseWriter, req *http.Request, ctx *handlerContext) {
start := time.Now().UTC()
response, err := f.roundTripper.RoundTrip(f.copyRequest(req, req.URL))
if err != nil {
ctx.log.Errorf("Error forwarding to %v, err: %v", req.URL, err)
ctx.errHandler.ServeHTTP(w, req, err)
@ -169,6 +171,16 @@ func (f *httpForwarder) serveHTTP(w http.ResponseWriter, req *http.Request, ctx
utils.CopyHeaders(w.Header(), response.Header)
// Remove hop-by-hop headers.
utils.RemoveHeaders(w.Header(), HopHeaders...)
announcedTrailerKeyCount := len(response.Trailer)
if announcedTrailerKeyCount > 0 {
trailerKeys := make([]string, 0, announcedTrailerKeyCount)
for k := range response.Trailer {
trailerKeys = append(trailerKeys, k)
}
w.Header().Add("Trailer", strings.Join(trailerKeys, ", "))
}
w.WriteHeader(response.StatusCode)
stream := f.streamResponse
@ -179,6 +191,20 @@ func (f *httpForwarder) serveHTTP(w http.ResponseWriter, req *http.Request, ctx
}
}
written, err := io.Copy(newResponseFlusher(w, stream), response.Body)
if err != nil {
ctx.log.Errorf("Error copying upstream response body: %v", err)
ctx.errHandler.ServeHTTP(w, req, err)
return
}
defer response.Body.Close()
forceSetTrailers := len(response.Trailer) != announcedTrailerKeyCount
shallowCopyTrailers(w.Header(), response.Trailer, forceSetTrailers)
if written != 0 {
w.Header().Set(ContentLength, strconv.FormatInt(written, 10))
}
if req.TLS != nil {
ctx.log.Infof("Round trip: %v, code: %v, duration: %v tls:version: %x, tls:resume:%t, tls:csuite:%x, tls:server:%v",
@ -192,17 +218,6 @@ func (f *httpForwarder) serveHTTP(w http.ResponseWriter, req *http.Request, ctx
req.URL, response.StatusCode, time.Now().UTC().Sub(start))
}
defer response.Body.Close()
if err != nil {
ctx.log.Errorf("Error copying upstream response Body: %v", err)
ctx.errHandler.ServeHTTP(w, req, err)
return
}
if written != 0 {
w.Header().Set(ContentLength, strconv.FormatInt(written, 10))
}
}
// copyRequest makes a copy of the specified request to be sent using the configured
@ -364,3 +379,12 @@ func isWebsocketRequest(req *http.Request) bool {
}
return containsHeader(Connection, "upgrade") && containsHeader(Upgrade, "websocket")
}
func shallowCopyTrailers(dstHeader, srcTrailer http.Header, forceSetTrailers bool) {
for k, vv := range srcTrailer {
if forceSetTrailers {
k = http.TrailerPrefix + k
}
dstHeader[k] = vv
}
}