Fix proxying of unannounced trailers
This commit is contained in:
parent
6473002021
commit
4699d6be18
3 changed files with 39 additions and 15 deletions
6
glide.lock
generated
6
glide.lock
generated
|
@ -1,5 +1,5 @@
|
||||||
hash: 9a62fe4058ef43ed185d96638322dd3d44ae21f7f65fae14c4c6d404876c2872
|
hash: cebc972cf87c4b0a8f86801f38750c51b09c8dee3bf62bb48f8eaa6ab7946352
|
||||||
updated: 2017-06-28T15:47:14.848940186+02:00
|
updated: 2017-06-29T16:47:14.848940186+02:00
|
||||||
imports:
|
imports:
|
||||||
- name: cloud.google.com/go
|
- name: cloud.google.com/go
|
||||||
version: 2e6a95edb1071d750f6d7db777bf66cd2997af6c
|
version: 2e6a95edb1071d750f6d7db777bf66cd2997af6c
|
||||||
|
@ -409,7 +409,7 @@ imports:
|
||||||
- name: github.com/vdemeester/docker-events
|
- name: github.com/vdemeester/docker-events
|
||||||
version: be74d4929ec1ad118df54349fda4b0cba60f849b
|
version: be74d4929ec1ad118df54349fda4b0cba60f849b
|
||||||
- name: github.com/vulcand/oxy
|
- name: github.com/vulcand/oxy
|
||||||
version: ad5bdb606fa9c64db267f0e43d63834908bdb05e
|
version: 7da864c1d53bd58165435bb78bbf8c01f01c8f4a
|
||||||
repo: https://github.com/containous/oxy.git
|
repo: https://github.com/containous/oxy.git
|
||||||
vcs: git
|
vcs: git
|
||||||
subpackages:
|
subpackages:
|
||||||
|
|
|
@ -8,7 +8,7 @@ import:
|
||||||
- package: github.com/cenk/backoff
|
- package: github.com/cenk/backoff
|
||||||
- package: github.com/containous/flaeg
|
- package: github.com/containous/flaeg
|
||||||
- package: github.com/vulcand/oxy
|
- package: github.com/vulcand/oxy
|
||||||
version: ad5bdb606fa9c64db267f0e43d63834908bdb05e
|
version: 7da864c1d53bd58165435bb78bbf8c01f01c8f4a
|
||||||
repo: https://github.com/containous/oxy.git
|
repo: https://github.com/containous/oxy.git
|
||||||
vcs: git
|
vcs: git
|
||||||
subpackages:
|
subpackages:
|
||||||
|
|
46
vendor/github.com/vulcand/oxy/forward/fwd.go
generated
vendored
46
vendor/github.com/vulcand/oxy/forward/fwd.go
generated
vendored
|
@ -159,7 +159,9 @@ func (f *Forwarder) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
// serveHTTP forwards HTTP traffic using the configured transport
|
// serveHTTP forwards HTTP traffic using the configured transport
|
||||||
func (f *httpForwarder) serveHTTP(w http.ResponseWriter, req *http.Request, ctx *handlerContext) {
|
func (f *httpForwarder) serveHTTP(w http.ResponseWriter, req *http.Request, ctx *handlerContext) {
|
||||||
start := time.Now().UTC()
|
start := time.Now().UTC()
|
||||||
|
|
||||||
response, err := f.roundTripper.RoundTrip(f.copyRequest(req, req.URL))
|
response, err := f.roundTripper.RoundTrip(f.copyRequest(req, req.URL))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.log.Errorf("Error forwarding to %v, err: %v", req.URL, err)
|
ctx.log.Errorf("Error forwarding to %v, err: %v", req.URL, err)
|
||||||
ctx.errHandler.ServeHTTP(w, req, 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)
|
utils.CopyHeaders(w.Header(), response.Header)
|
||||||
// Remove hop-by-hop headers.
|
// Remove hop-by-hop headers.
|
||||||
utils.RemoveHeaders(w.Header(), HopHeaders...)
|
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)
|
w.WriteHeader(response.StatusCode)
|
||||||
|
|
||||||
stream := f.streamResponse
|
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)
|
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 {
|
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",
|
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))
|
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
|
// 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")
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue