6 "github.com/bradfitz/http2/hpack"
13 // TestH1H1PlainGET tests whether simple HTTP/1 GET request works.
14 func TestH1H1PlainGET(t *testing.T) {
15 st := newServerTester(nil, t, noopHandler)
18 res, err := st.http1(requestParam{
19 name: "TestH1H1PlainGET",
22 t.Fatalf("Error st.http1() = %v", err)
26 if got := res.status; got != want {
27 t.Errorf("status = %v; want %v", got, want)
31 // TestH1H1PlainGETClose tests whether simple HTTP/1 GET request with
32 // Connetion: close request header field works.
33 func TestH1H1PlainGETClose(t *testing.T) {
34 st := newServerTester(nil, t, noopHandler)
37 res, err := st.http1(requestParam{
38 name: "TestH1H1PlainGETClose",
39 header: []hpack.HeaderField{
40 pair("Connection", "close"),
44 t.Fatalf("Error st.http1() = %v", err)
48 if got := res.status; got != want {
49 t.Errorf("status = %v; want %v", got, want)
53 // TestH1H1MultipleRequestCL tests that server rejects request which
54 // contains multiple Content-Length header fields.
55 func TestH1H1MultipleRequestCL(t *testing.T) {
56 st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
57 t.Errorf("server should not forward bad request")
61 if _, err := io.WriteString(st.conn, fmt.Sprintf(`GET / HTTP/1.1
63 Test-Case: TestH1H1MultipleRequestCL
67 `, st.authority)); err != nil {
68 t.Fatalf("Error io.WriteString() = %v", err)
71 resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
73 t.Fatalf("Error http.ReadResponse() = %v", err)
77 if got := resp.StatusCode; got != want {
78 t.Errorf("status: %v; want %v", got, want)
82 // TestH1H1ConnectFailure tests that server handles the situation that
83 // connection attempt to HTTP/1 backend failed.
84 func TestH1H1ConnectFailure(t *testing.T) {
85 st := newServerTester(nil, t, noopHandler)
88 // shutdown backend server to simulate backend connect failure
91 res, err := st.http1(requestParam{
92 name: "TestH1H1ConnectFailure",
95 t.Fatalf("Error st.http1() = %v", err)
98 if got := res.status; got != want {
99 t.Errorf("status: %v; want %v", got, want)
103 // TestH1H1GracefulShutdown tests graceful shutdown.
104 func TestH1H1GracefulShutdown(t *testing.T) {
105 st := newServerTester(nil, t, noopHandler)
108 res, err := st.http1(requestParam{
109 name: "TestH1H1GracefulShutdown-1",
112 t.Fatalf("Error st.http1() = %v", err)
115 if got, want := res.status, 200; got != want {
116 t.Errorf("status: %v; want %v", got, want)
119 st.cmd.Process.Signal(syscall.SIGQUIT)
121 res, err = st.http1(requestParam{
122 name: "TestH1H1GracefulShutdown-2",
125 t.Fatalf("Error st.http1() = %v", err)
128 if got, want := res.status, 200; got != want {
129 t.Errorf("status: %v; want %v", got, want)
132 if got, want := res.connClose, true; got != want {
133 t.Errorf("res.connClose: %v; want %v", got, want)
137 if _, err := st.conn.Read(nil); err == nil || err != want {
138 t.Errorf("st.conn.Read(): %v; want %v", err, want)
142 // TestH1H1HostRewrite tests that server rewrites Host header field
143 func TestH1H1HostRewrite(t *testing.T) {
144 st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
145 w.Header().Add("request-host", r.Host)
149 res, err := st.http1(requestParam{
150 name: "TestH1H1HostRewrite",
153 t.Fatalf("Error st.http1() = %v", err)
155 if got, want := res.status, 200; got != want {
156 t.Errorf("status: %v; want %v", got, want)
158 if got, want := res.header.Get("request-host"), st.backendHost; got != want {
159 t.Errorf("request-host: %v; want %v", got, want)
163 // TestH1H1HTTP10 tests that server can accept HTTP/1.0 request
164 // without Host header field
165 func TestH1H1HTTP10(t *testing.T) {
166 st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
167 w.Header().Add("request-host", r.Host)
171 if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H1HTTP10\r\n\r\n"); err != nil {
172 t.Fatalf("Error io.WriteString() = %v", err)
175 resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
177 t.Fatalf("Error http.ReadResponse() = %v", err)
180 if got, want := resp.StatusCode, 200; got != want {
181 t.Errorf("status: %v; want %v", got, want)
183 if got, want := resp.Header.Get("request-host"), st.backendHost; got != want {
184 t.Errorf("request-host: %v; want %v", got, want)
188 // TestH1H1HTTP10NoHostRewrite tests that server generates host header
189 // field using actual backend server even if --no-http-rewrite is
191 func TestH1H1HTTP10NoHostRewrite(t *testing.T) {
192 st := newServerTester([]string{"--no-host-rewrite"}, t, func(w http.ResponseWriter, r *http.Request) {
193 w.Header().Add("request-host", r.Host)
197 if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H1HTTP10NoHostRewrite\r\n\r\n"); err != nil {
198 t.Fatalf("Error io.WriteString() = %v", err)
201 resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
203 t.Fatalf("Error http.ReadResponse() = %v", err)
206 if got, want := resp.StatusCode, 200; got != want {
207 t.Errorf("status: %v; want %v", got, want)
209 if got, want := resp.Header.Get("request-host"), st.backendHost; got != want {
210 t.Errorf("request-host: %v; want %v", got, want)
214 // TestH1H2ConnectFailure tests that server handles the situation that
215 // connection attempt to HTTP/2 backend failed.
216 func TestH1H2ConnectFailure(t *testing.T) {
217 st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
220 // simulate backend connect attempt failure
223 res, err := st.http1(requestParam{
224 name: "TestH1H2ConnectFailure",
227 t.Fatalf("Error st.http1() = %v", err)
230 if got := res.status; got != want {
231 t.Errorf("status: %v; want %v", got, want)
235 // TestH1H2NoHost tests that server rejects request without Host
236 // header field for HTTP/2 backend.
237 func TestH1H2NoHost(t *testing.T) {
238 st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
239 t.Errorf("server should not forward bad request")
243 // without Host header field, we expect 400 response
244 if _, err := io.WriteString(st.conn, "GET / HTTP/1.1\r\nTest-Case: TestH1H2NoHost\r\n\r\n"); err != nil {
245 t.Fatalf("Error io.WriteString() = %v", err)
248 resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
250 t.Fatalf("Error http.ReadResponse() = %v", err)
254 if got := resp.StatusCode; got != want {
255 t.Errorf("status: %v; want %v", got, want)
259 // TestH1H2HTTP10 tests that server can accept HTTP/1.0 request
260 // without Host header field
261 func TestH1H2HTTP10(t *testing.T) {
262 st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
263 w.Header().Add("request-host", r.Host)
267 if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H2HTTP10\r\n\r\n"); err != nil {
268 t.Fatalf("Error io.WriteString() = %v", err)
271 resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
273 t.Fatalf("Error http.ReadResponse() = %v", err)
276 if got, want := resp.StatusCode, 200; got != want {
277 t.Errorf("status: %v; want %v", got, want)
279 if got, want := resp.Header.Get("request-host"), st.backendHost; got != want {
280 t.Errorf("request-host: %v; want %v", got, want)
284 // TestH1H2HTTP10NoHostRewrite tests that server generates host header
285 // field using actual backend server even if --no-http-rewrite is
287 func TestH1H2HTTP10NoHostRewrite(t *testing.T) {
288 st := newServerTester([]string{"--http2-bridge", "--no-host-rewrite"}, t, func(w http.ResponseWriter, r *http.Request) {
289 w.Header().Add("request-host", r.Host)
293 if _, err := io.WriteString(st.conn, "GET / HTTP/1.0\r\nTest-Case: TestH1H2HTTP10NoHostRewrite\r\n\r\n"); err != nil {
294 t.Fatalf("Error io.WriteString() = %v", err)
297 resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
299 t.Fatalf("Error http.ReadResponse() = %v", err)
302 if got, want := resp.StatusCode, 200; got != want {
303 t.Errorf("status: %v; want %v", got, want)
305 if got, want := resp.Header.Get("request-host"), st.backendHost; got != want {
306 t.Errorf("request-host: %v; want %v", got, want)
310 // TestH1H2CrumbleCookie tests that Cookies are crumbled and assembled
311 // when forwarding to HTTP/2 backend link. go-nghttp2 server
312 // concatenates crumbled Cookies automatically, so this test is not
313 // much effective now.
314 func TestH1H2CrumbleCookie(t *testing.T) {
315 st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
316 if got, want := r.Header.Get("Cookie"), "alpha; bravo; charlie"; got != want {
317 t.Errorf("Cookie: %v; want %v", got, want)
322 res, err := st.http1(requestParam{
323 name: "TestH1H2CrumbleCookie",
324 header: []hpack.HeaderField{
325 pair("Cookie", "alpha; bravo; charlie"),
329 t.Fatalf("Error st.http1() = %v", err)
331 if got, want := res.status, 200; got != want {
332 t.Errorf("status: %v; want %v", got, want)
336 // TestH1H2GenerateVia tests that server generates Via header field to and
337 // from backend server.
338 func TestH1H2GenerateVia(t *testing.T) {
339 st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
340 if got, want := r.Header.Get("Via"), "1.1 nghttpx"; got != want {
341 t.Errorf("Via: %v; want %v", got, want)
346 res, err := st.http1(requestParam{
347 name: "TestH1H2GenerateVia",
350 t.Fatalf("Error st.http1() = %v", err)
352 if got, want := res.header.Get("Via"), "2.0 nghttpx"; got != want {
353 t.Errorf("Via: %v; want %v", got, want)
357 // TestH1H2AppendVia tests that server adds value to existing Via
358 // header field to and from backend server.
359 func TestH1H2AppendVia(t *testing.T) {
360 st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
361 if got, want := r.Header.Get("Via"), "foo, 1.1 nghttpx"; got != want {
362 t.Errorf("Via: %v; want %v", got, want)
364 w.Header().Add("Via", "bar")
368 res, err := st.http1(requestParam{
369 name: "TestH1H2AppendVia",
370 header: []hpack.HeaderField{
375 t.Fatalf("Error st.http1() = %v", err)
377 if got, want := res.header.Get("Via"), "bar, 2.0 nghttpx"; got != want {
378 t.Errorf("Via: %v; want %v", got, want)
382 // TestH1H2NoVia tests that server does not add value to existing Via
383 // header field to and from backend server.
384 func TestH1H2NoVia(t *testing.T) {
385 st := newServerTester([]string{"--http2-bridge", "--no-via"}, t, func(w http.ResponseWriter, r *http.Request) {
386 if got, want := r.Header.Get("Via"), "foo"; got != want {
387 t.Errorf("Via: %v; want %v", got, want)
389 w.Header().Add("Via", "bar")
393 res, err := st.http1(requestParam{
394 name: "TestH1H2NoVia",
395 header: []hpack.HeaderField{
400 t.Fatalf("Error st.http1() = %v", err)
402 if got, want := res.header.Get("Via"), "bar"; got != want {
403 t.Errorf("Via: %v; want %v", got, want)