diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2016-11-01 15:24:11 +0000 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2016-11-01 17:01:30 +0000 |
| commit | b2c54afe1451f93e1fbbad257a151d8425cd308d (patch) | |
| tree | 8a5df30c71c5c51b644311b5bc79a144b0f752d5 /src/net/http/clientserver_test.go | |
| parent | 3c2f607274b2284826ea887fa9d2ef62817df608 (diff) | |
| download | go-b2c54afe1451f93e1fbbad257a151d8425cd308d.tar.xz | |
net/http, net/http/httptest: make http2's TrailerPrefix work for http1
Go's http1 implementation originally had a mechanism to send HTTP
trailers based on pre-declaring the trailer keys whose values you'd
later let after the header was written.
http2 copied the same mechanism, but it was found to be unsufficient
for gRPC's wire protocol. A second trailer mechanism was added later
(but only to http2) for handlers that want to send a trailer without
knowing in advance they'd need to.
Copy the same mechanism back to http1 and document it.
Fixes #15754
Change-Id: I8c40d55e28b0e5b7087d3d1a904a392c56ee1f9b
Reviewed-on: https://go-review.googlesource.com/32479
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/net/http/clientserver_test.go')
| -rw-r--r-- | src/net/http/clientserver_test.go | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/net/http/clientserver_test.go b/src/net/http/clientserver_test.go index f552424189..d01e7558dc 100644 --- a/src/net/http/clientserver_test.go +++ b/src/net/http/clientserver_test.go @@ -1270,3 +1270,34 @@ func testNoSniffExpectRequestBody(t *testing.T, h2 bool) { t.Errorf("status code = %v; want %v", res.StatusCode, StatusUnauthorized) } } + +func TestServerUndeclaredTrailers_h1(t *testing.T) { testServerUndeclaredTrailers(t, h1Mode) } +func TestServerUndeclaredTrailers_h2(t *testing.T) { testServerUndeclaredTrailers(t, h2Mode) } +func testServerUndeclaredTrailers(t *testing.T, h2 bool) { + defer afterTest(t) + cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { + w.Header().Set("Foo", "Bar") + w.Header().Set("Trailer:Foo", "Baz") + w.(Flusher).Flush() + w.Header().Add("Trailer:Foo", "Baz2") + w.Header().Set("Trailer:Bar", "Quux") + })) + defer cst.close() + res, err := cst.c.Get(cst.ts.URL) + if err != nil { + t.Fatal(err) + } + if _, err := io.Copy(ioutil.Discard, res.Body); err != nil { + t.Fatal(err) + } + res.Body.Close() + delete(res.Header, "Date") + delete(res.Header, "Content-Type") + + if want := (Header{"Foo": {"Bar"}}); !reflect.DeepEqual(res.Header, want) { + t.Errorf("Header = %#v; want %#v", res.Header, want) + } + if want := (Header{"Foo": {"Baz", "Baz2"}, "Bar": {"Quux"}}); !reflect.DeepEqual(res.Trailer, want) { + t.Errorf("Trailer = %#v; want %#v", res.Trailer, want) + } +} |
