Skip to content

Commit 1611839

Browse files
tcolgatebradfitz
authored andcommitted
net/http/httputil: ReverseProxy should pass on unannounced Trailers
Trailers that are not announced in the Trailer must be passed on to the downstream client. Rather than iterate over each and find missing trailer values, this re-adds all trailers to the headers if there is a disparity between the number of announced trailers and the final number. This fixes #20437 Change-Id: I867e85f45feff68616a9a9bd6f65f12d73825eb7 Reviewed-on: https://go-review.googlesource.com/43712 Reviewed-by: Brad Fitzpatrick <[email protected]> Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent bc495c5 commit 1611839

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

src/net/http/httputil/reverseproxy.go

+14-2
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
233233

234234
// The "Trailer" header isn't included in the Transport's response,
235235
// at least for *http.Transport. Build it up from Trailer.
236-
if len(res.Trailer) > 0 {
236+
announcedTrailers := len(res.Trailer)
237+
if announcedTrailers > 0 {
237238
trailerKeys := make([]string, 0, len(res.Trailer))
238239
for k := range res.Trailer {
239240
trailerKeys = append(trailerKeys, k)
@@ -252,7 +253,18 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
252253
}
253254
p.copyResponse(rw, res.Body)
254255
res.Body.Close() // close now, instead of defer, to populate res.Trailer
255-
copyHeader(rw.Header(), res.Trailer)
256+
257+
if len(res.Trailer) == announcedTrailers {
258+
copyHeader(rw.Header(), res.Trailer)
259+
return
260+
}
261+
262+
for k, vv := range res.Trailer {
263+
k = http.TrailerPrefix + k
264+
for _, v := range vv {
265+
rw.Header().Add(k, v)
266+
}
267+
}
256268
}
257269

258270
func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader) {

src/net/http/httputil/reverseproxy_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ func TestReverseProxy(t *testing.T) {
6969
w.WriteHeader(backendStatus)
7070
w.Write([]byte(backendResponse))
7171
w.Header().Set("X-Trailer", "trailer_value")
72+
w.Header().Set(http.TrailerPrefix+"X-Unannounced-Trailer", "unannounced_trailer_value")
7273
}))
7374
defer backend.Close()
7475
backendURL, err := url.Parse(backend.URL)
@@ -122,6 +123,9 @@ func TestReverseProxy(t *testing.T) {
122123
if g, e := res.Trailer.Get("X-Trailer"), "trailer_value"; g != e {
123124
t.Errorf("Trailer(X-Trailer) = %q ; want %q", g, e)
124125
}
126+
if g, e := res.Trailer.Get("X-Unannounced-Trailer"), "unannounced_trailer_value"; g != e {
127+
t.Errorf("Trailer(X-Unannounced-Trailer) = %q ; want %q", g, e)
128+
}
125129

126130
// Test that a backend failing to be reached or one which doesn't return
127131
// a response results in a StatusBadGateway.

0 commit comments

Comments
 (0)