]> Cypherpunks repositories - gostls13.git/commitdiff
net/http/httputil: fix unannounced trailers when body is empty
authorSALLEYRON Julien <julien.salleyron@gmail.com>
Mon, 3 Dec 2018 20:46:23 +0000 (20:46 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 3 Dec 2018 21:45:17 +0000 (21:45 +0000)
Fix unannounced trailers when body is empty and without announced trailers.

Fixes #29031

Change-Id: If49951a42fe56d4be4436a999627db4c2678659d
GitHub-Last-Rev: 3469adc8f5fd977438350274134950687853a468
GitHub-Pull-Request: golang/go#29032
Reviewed-on: https://go-review.googlesource.com/c/151898
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/net/http/httputil/reverseproxy.go
src/net/http/httputil/reverseproxy_test.go

index f0607a68ea2d3f269fc49c8fd7a3b1ededb0ec4b..5d07ba3d361873d834c36a794e8ca3973271c119 100644 (file)
@@ -282,14 +282,7 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
        }
 
        rw.WriteHeader(res.StatusCode)
-       if len(res.Trailer) > 0 {
-               // Force chunking if we saw a response trailer.
-               // This prevents net/http from calculating the length for short
-               // bodies and adding a Content-Length.
-               if fl, ok := rw.(http.Flusher); ok {
-                       fl.Flush()
-               }
-       }
+
        err = p.copyResponse(rw, res.Body, p.flushInterval(req, res))
        if err != nil {
                defer res.Body.Close()
@@ -304,6 +297,15 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
        }
        res.Body.Close() // close now, instead of defer, to populate res.Trailer
 
+       if len(res.Trailer) > 0 {
+               // Force chunking if we saw a response trailer.
+               // This prevents net/http from calculating the length for short
+               // bodies and adding a Content-Length.
+               if fl, ok := rw.(http.Flusher); ok {
+                       fl.Flush()
+               }
+       }
+
        if len(res.Trailer) == announcedTrailers {
                copyHeader(rw.Header(), res.Trailer)
                return
index 039273e7c581ec4bc808629f674ea69add44bf98..588022c066bf1dbe04e0a90735f81897c7e47014 100644 (file)
@@ -7,23 +7,23 @@
 package httputil
 
 import (
-       "bufio"
-       "bytes"
-       "errors"
-       "fmt"
-       "io"
        "io/ioutil"
        "log"
        "net/http"
        "net/http/httptest"
        "net/url"
-       "os"
+       "testing"
+       "time"
        "reflect"
-       "strconv"
+       "io"
        "strings"
+       "bufio"
        "sync"
-       "testing"
-       "time"
+       "strconv"
+       "bytes"
+       "errors"
+       "fmt"
+       "os"
 )
 
 const fakeHopHeader = "X-Fake-Hop-Header-For-Test"
@@ -1048,3 +1048,33 @@ func TestReverseProxyWebSocket(t *testing.T) {
                t.Errorf("got %#q, want %#q", got, want)
        }
 }
+
+func TestUnannouncedTrailer(t *testing.T) {
+       backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+               w.WriteHeader(http.StatusOK)
+               w.(http.Flusher).Flush()
+               w.Header().Set(http.TrailerPrefix+"X-Unannounced-Trailer", "unannounced_trailer_value")
+       }))
+       defer backend.Close()
+       backendURL, err := url.Parse(backend.URL)
+       if err != nil {
+               t.Fatal(err)
+       }
+       proxyHandler := NewSingleHostReverseProxy(backendURL)
+       proxyHandler.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
+       frontend := httptest.NewServer(proxyHandler)
+       defer frontend.Close()
+       frontendClient := frontend.Client()
+
+       res, err := frontendClient.Get(frontend.URL)
+       if err != nil {
+               t.Fatalf("Get: %v", err)
+       }
+
+       ioutil.ReadAll(res.Body)
+
+       if g, w := res.Trailer.Get("X-Unannounced-Trailer"), "unannounced_trailer_value"; g != w {
+               t.Errorf("Trailer(X-Unannounced-Trailer) = %q; want %q", g, w)
+       }
+
+}