github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/src/net/http/clientserver_test.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Tests that use both the client & server, in both HTTP/1 and HTTP/2 mode. 6 7 package http_test 8 9 import ( 10 "bytes" 11 "compress/gzip" 12 "crypto/tls" 13 "fmt" 14 "io" 15 "io/ioutil" 16 "log" 17 "net" 18 . "net/http" 19 "net/http/httptest" 20 "net/http/httputil" 21 "net/url" 22 "os" 23 "reflect" 24 "runtime" 25 "sort" 26 "strings" 27 "sync" 28 "sync/atomic" 29 "testing" 30 "time" 31 ) 32 33 type clientServerTest struct { 34 t *testing.T 35 h2 bool 36 h Handler 37 ts *httptest.Server 38 tr *Transport 39 c *Client 40 } 41 42 func (t *clientServerTest) close() { 43 t.tr.CloseIdleConnections() 44 t.ts.Close() 45 } 46 47 func (t *clientServerTest) scheme() string { 48 if t.h2 { 49 return "https" 50 } 51 return "http" 52 } 53 54 const ( 55 h1Mode = false 56 h2Mode = true 57 ) 58 59 func newClientServerTest(t *testing.T, h2 bool, h Handler, opts ...interface{}) *clientServerTest { 60 cst := &clientServerTest{ 61 t: t, 62 h2: h2, 63 h: h, 64 tr: &Transport{}, 65 } 66 cst.c = &Client{Transport: cst.tr} 67 68 for _, opt := range opts { 69 switch opt := opt.(type) { 70 case func(*Transport): 71 opt(cst.tr) 72 default: 73 t.Fatalf("unhandled option type %T", opt) 74 } 75 } 76 77 if !h2 { 78 cst.ts = httptest.NewServer(h) 79 return cst 80 } 81 cst.ts = httptest.NewUnstartedServer(h) 82 ExportHttp2ConfigureServer(cst.ts.Config, nil) 83 cst.ts.TLS = cst.ts.Config.TLSConfig 84 cst.ts.StartTLS() 85 86 cst.tr.TLSClientConfig = &tls.Config{ 87 InsecureSkipVerify: true, 88 } 89 if err := ExportHttp2ConfigureTransport(cst.tr); err != nil { 90 t.Fatal(err) 91 } 92 return cst 93 } 94 95 // Testing the newClientServerTest helper itself. 96 func TestNewClientServerTest(t *testing.T) { 97 var got struct { 98 sync.Mutex 99 log []string 100 } 101 h := HandlerFunc(func(w ResponseWriter, r *Request) { 102 got.Lock() 103 defer got.Unlock() 104 got.log = append(got.log, r.Proto) 105 }) 106 for _, v := range [2]bool{false, true} { 107 cst := newClientServerTest(t, v, h) 108 if _, err := cst.c.Head(cst.ts.URL); err != nil { 109 t.Fatal(err) 110 } 111 cst.close() 112 } 113 got.Lock() // no need to unlock 114 if want := []string{"HTTP/1.1", "HTTP/2.0"}; !reflect.DeepEqual(got.log, want) { 115 t.Errorf("got %q; want %q", got.log, want) 116 } 117 } 118 119 func TestChunkedResponseHeaders_h1(t *testing.T) { testChunkedResponseHeaders(t, h1Mode) } 120 func TestChunkedResponseHeaders_h2(t *testing.T) { testChunkedResponseHeaders(t, h2Mode) } 121 122 func testChunkedResponseHeaders(t *testing.T, h2 bool) { 123 defer afterTest(t) 124 log.SetOutput(ioutil.Discard) // is noisy otherwise 125 defer log.SetOutput(os.Stderr) 126 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 127 w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted 128 w.(Flusher).Flush() 129 fmt.Fprintf(w, "I am a chunked response.") 130 })) 131 defer cst.close() 132 133 res, err := cst.c.Get(cst.ts.URL) 134 if err != nil { 135 t.Fatalf("Get error: %v", err) 136 } 137 defer res.Body.Close() 138 if g, e := res.ContentLength, int64(-1); g != e { 139 t.Errorf("expected ContentLength of %d; got %d", e, g) 140 } 141 wantTE := []string{"chunked"} 142 if h2 { 143 wantTE = nil 144 } 145 if !reflect.DeepEqual(res.TransferEncoding, wantTE) { 146 t.Errorf("TransferEncoding = %v; want %v", res.TransferEncoding, wantTE) 147 } 148 if got, haveCL := res.Header["Content-Length"]; haveCL { 149 t.Errorf("Unexpected Content-Length: %q", got) 150 } 151 } 152 153 type reqFunc func(c *Client, url string) (*Response, error) 154 155 // h12Compare is a test that compares HTTP/1 and HTTP/2 behavior 156 // against each other. 157 type h12Compare struct { 158 Handler func(ResponseWriter, *Request) // required 159 ReqFunc reqFunc // optional 160 CheckResponse func(proto string, res *Response) // optional 161 EarlyCheckResponse func(proto string, res *Response) // optional; pre-normalize 162 Opts []interface{} 163 } 164 165 func (tt h12Compare) reqFunc() reqFunc { 166 if tt.ReqFunc == nil { 167 return (*Client).Get 168 } 169 return tt.ReqFunc 170 } 171 172 func (tt h12Compare) run(t *testing.T) { 173 cst1 := newClientServerTest(t, false, HandlerFunc(tt.Handler), tt.Opts...) 174 defer cst1.close() 175 cst2 := newClientServerTest(t, true, HandlerFunc(tt.Handler), tt.Opts...) 176 defer cst2.close() 177 178 res1, err := tt.reqFunc()(cst1.c, cst1.ts.URL) 179 if err != nil { 180 t.Errorf("HTTP/1 request: %v", err) 181 return 182 } 183 res2, err := tt.reqFunc()(cst2.c, cst2.ts.URL) 184 if err != nil { 185 t.Errorf("HTTP/2 request: %v", err) 186 return 187 } 188 189 if fn := tt.EarlyCheckResponse; fn != nil { 190 fn("HTTP/1.1", res1) 191 fn("HTTP/2.0", res2) 192 } 193 194 tt.normalizeRes(t, res1, "HTTP/1.1") 195 tt.normalizeRes(t, res2, "HTTP/2.0") 196 res1body, res2body := res1.Body, res2.Body 197 198 eres1 := mostlyCopy(res1) 199 eres2 := mostlyCopy(res2) 200 if !reflect.DeepEqual(eres1, eres2) { 201 t.Errorf("Response headers to handler differed:\nhttp/1 (%v):\n\t%#v\nhttp/2 (%v):\n\t%#v", 202 cst1.ts.URL, eres1, cst2.ts.URL, eres2) 203 } 204 if !reflect.DeepEqual(res1body, res2body) { 205 t.Errorf("Response bodies to handler differed.\nhttp1: %v\nhttp2: %v\n", res1body, res2body) 206 } 207 if fn := tt.CheckResponse; fn != nil { 208 res1.Body, res2.Body = res1body, res2body 209 fn("HTTP/1.1", res1) 210 fn("HTTP/2.0", res2) 211 } 212 } 213 214 func mostlyCopy(r *Response) *Response { 215 c := *r 216 c.Body = nil 217 c.TransferEncoding = nil 218 c.TLS = nil 219 c.Request = nil 220 return &c 221 } 222 223 type slurpResult struct { 224 io.ReadCloser 225 body []byte 226 err error 227 } 228 229 func (sr slurpResult) String() string { return fmt.Sprintf("body %q; err %v", sr.body, sr.err) } 230 231 func (tt h12Compare) normalizeRes(t *testing.T, res *Response, wantProto string) { 232 if res.Proto == wantProto { 233 res.Proto, res.ProtoMajor, res.ProtoMinor = "", 0, 0 234 } else { 235 t.Errorf("got %q response; want %q", res.Proto, wantProto) 236 } 237 slurp, err := ioutil.ReadAll(res.Body) 238 239 res.Body.Close() 240 res.Body = slurpResult{ 241 ReadCloser: ioutil.NopCloser(bytes.NewReader(slurp)), 242 body: slurp, 243 err: err, 244 } 245 for i, v := range res.Header["Date"] { 246 res.Header["Date"][i] = strings.Repeat("x", len(v)) 247 } 248 if res.Request == nil { 249 t.Errorf("for %s, no request", wantProto) 250 } 251 if (res.TLS != nil) != (wantProto == "HTTP/2.0") { 252 t.Errorf("TLS set = %v; want %v", res.TLS != nil, res.TLS == nil) 253 } 254 } 255 256 // Issue 13532 257 func TestH12_HeadContentLengthNoBody(t *testing.T) { 258 h12Compare{ 259 ReqFunc: (*Client).Head, 260 Handler: func(w ResponseWriter, r *Request) { 261 }, 262 }.run(t) 263 } 264 265 func TestH12_HeadContentLengthSmallBody(t *testing.T) { 266 h12Compare{ 267 ReqFunc: (*Client).Head, 268 Handler: func(w ResponseWriter, r *Request) { 269 io.WriteString(w, "small") 270 }, 271 }.run(t) 272 } 273 274 func TestH12_HeadContentLengthLargeBody(t *testing.T) { 275 h12Compare{ 276 ReqFunc: (*Client).Head, 277 Handler: func(w ResponseWriter, r *Request) { 278 chunk := strings.Repeat("x", 512<<10) 279 for i := 0; i < 10; i++ { 280 io.WriteString(w, chunk) 281 } 282 }, 283 }.run(t) 284 } 285 286 func TestH12_200NoBody(t *testing.T) { 287 h12Compare{Handler: func(w ResponseWriter, r *Request) {}}.run(t) 288 } 289 290 func TestH2_204NoBody(t *testing.T) { testH12_noBody(t, 204) } 291 func TestH2_304NoBody(t *testing.T) { testH12_noBody(t, 304) } 292 func TestH2_404NoBody(t *testing.T) { testH12_noBody(t, 404) } 293 294 func testH12_noBody(t *testing.T, status int) { 295 h12Compare{Handler: func(w ResponseWriter, r *Request) { 296 w.WriteHeader(status) 297 }}.run(t) 298 } 299 300 func TestH12_SmallBody(t *testing.T) { 301 h12Compare{Handler: func(w ResponseWriter, r *Request) { 302 io.WriteString(w, "small body") 303 }}.run(t) 304 } 305 306 func TestH12_ExplicitContentLength(t *testing.T) { 307 h12Compare{Handler: func(w ResponseWriter, r *Request) { 308 w.Header().Set("Content-Length", "3") 309 io.WriteString(w, "foo") 310 }}.run(t) 311 } 312 313 func TestH12_FlushBeforeBody(t *testing.T) { 314 h12Compare{Handler: func(w ResponseWriter, r *Request) { 315 w.(Flusher).Flush() 316 io.WriteString(w, "foo") 317 }}.run(t) 318 } 319 320 func TestH12_FlushMidBody(t *testing.T) { 321 h12Compare{Handler: func(w ResponseWriter, r *Request) { 322 io.WriteString(w, "foo") 323 w.(Flusher).Flush() 324 io.WriteString(w, "bar") 325 }}.run(t) 326 } 327 328 func TestH12_Head_ExplicitLen(t *testing.T) { 329 h12Compare{ 330 ReqFunc: (*Client).Head, 331 Handler: func(w ResponseWriter, r *Request) { 332 if r.Method != "HEAD" { 333 t.Errorf("unexpected method %q", r.Method) 334 } 335 w.Header().Set("Content-Length", "1235") 336 }, 337 }.run(t) 338 } 339 340 func TestH12_Head_ImplicitLen(t *testing.T) { 341 h12Compare{ 342 ReqFunc: (*Client).Head, 343 Handler: func(w ResponseWriter, r *Request) { 344 if r.Method != "HEAD" { 345 t.Errorf("unexpected method %q", r.Method) 346 } 347 io.WriteString(w, "foo") 348 }, 349 }.run(t) 350 } 351 352 func TestH12_HandlerWritesTooLittle(t *testing.T) { 353 h12Compare{ 354 Handler: func(w ResponseWriter, r *Request) { 355 w.Header().Set("Content-Length", "3") 356 io.WriteString(w, "12") // one byte short 357 }, 358 CheckResponse: func(proto string, res *Response) { 359 sr, ok := res.Body.(slurpResult) 360 if !ok { 361 t.Errorf("%s body is %T; want slurpResult", proto, res.Body) 362 return 363 } 364 if sr.err != io.ErrUnexpectedEOF { 365 t.Errorf("%s read error = %v; want io.ErrUnexpectedEOF", proto, sr.err) 366 } 367 if string(sr.body) != "12" { 368 t.Errorf("%s body = %q; want %q", proto, sr.body, "12") 369 } 370 }, 371 }.run(t) 372 } 373 374 // Tests that the HTTP/1 and HTTP/2 servers prevent handlers from 375 // writing more than they declared. This test does not test whether 376 // the transport deals with too much data, though, since the server 377 // doesn't make it possible to send bogus data. For those tests, see 378 // transport_test.go (for HTTP/1) or x/net/http2/transport_test.go 379 // (for HTTP/2). 380 func TestH12_HandlerWritesTooMuch(t *testing.T) { 381 h12Compare{ 382 Handler: func(w ResponseWriter, r *Request) { 383 w.Header().Set("Content-Length", "3") 384 w.(Flusher).Flush() 385 io.WriteString(w, "123") 386 w.(Flusher).Flush() 387 n, err := io.WriteString(w, "x") // too many 388 if n > 0 || err == nil { 389 t.Errorf("for proto %q, final write = %v, %v; want 0, some error", r.Proto, n, err) 390 } 391 }, 392 }.run(t) 393 } 394 395 // Verify that both our HTTP/1 and HTTP/2 request and auto-decompress gzip. 396 // Some hosts send gzip even if you don't ask for it; see golang.org/issue/13298 397 func TestH12_AutoGzip(t *testing.T) { 398 h12Compare{ 399 Handler: func(w ResponseWriter, r *Request) { 400 if ae := r.Header.Get("Accept-Encoding"); ae != "gzip" { 401 t.Errorf("%s Accept-Encoding = %q; want gzip", r.Proto, ae) 402 } 403 w.Header().Set("Content-Encoding", "gzip") 404 gz := gzip.NewWriter(w) 405 io.WriteString(gz, "I am some gzipped content. Go go go go go go go go go go go go should compress well.") 406 gz.Close() 407 }, 408 }.run(t) 409 } 410 411 func TestH12_AutoGzip_Disabled(t *testing.T) { 412 h12Compare{ 413 Opts: []interface{}{ 414 func(tr *Transport) { tr.DisableCompression = true }, 415 }, 416 Handler: func(w ResponseWriter, r *Request) { 417 fmt.Fprintf(w, "%q", r.Header["Accept-Encoding"]) 418 if ae := r.Header.Get("Accept-Encoding"); ae != "" { 419 t.Errorf("%s Accept-Encoding = %q; want empty", r.Proto, ae) 420 } 421 }, 422 }.run(t) 423 } 424 425 // Test304Responses verifies that 304s don't declare that they're 426 // chunking in their response headers and aren't allowed to produce 427 // output. 428 func Test304Responses_h1(t *testing.T) { test304Responses(t, h1Mode) } 429 func Test304Responses_h2(t *testing.T) { test304Responses(t, h2Mode) } 430 431 func test304Responses(t *testing.T, h2 bool) { 432 defer afterTest(t) 433 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 434 w.WriteHeader(StatusNotModified) 435 _, err := w.Write([]byte("illegal body")) 436 if err != ErrBodyNotAllowed { 437 t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err) 438 } 439 })) 440 defer cst.close() 441 res, err := cst.c.Get(cst.ts.URL) 442 if err != nil { 443 t.Fatal(err) 444 } 445 if len(res.TransferEncoding) > 0 { 446 t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding) 447 } 448 body, err := ioutil.ReadAll(res.Body) 449 if err != nil { 450 t.Error(err) 451 } 452 if len(body) > 0 { 453 t.Errorf("got unexpected body %q", string(body)) 454 } 455 } 456 457 func TestH12_ServerEmptyContentLength(t *testing.T) { 458 h12Compare{ 459 Handler: func(w ResponseWriter, r *Request) { 460 w.Header()["Content-Type"] = []string{""} 461 io.WriteString(w, "<html><body>hi</body></html>") 462 }, 463 }.run(t) 464 } 465 466 func TestH12_RequestContentLength_Known_NonZero(t *testing.T) { 467 h12requestContentLength(t, func() io.Reader { return strings.NewReader("FOUR") }, 4) 468 } 469 470 func TestH12_RequestContentLength_Known_Zero(t *testing.T) { 471 h12requestContentLength(t, func() io.Reader { return strings.NewReader("") }, 0) 472 } 473 474 func TestH12_RequestContentLength_Unknown(t *testing.T) { 475 h12requestContentLength(t, func() io.Reader { return struct{ io.Reader }{strings.NewReader("Stuff")} }, -1) 476 } 477 478 func h12requestContentLength(t *testing.T, bodyfn func() io.Reader, wantLen int64) { 479 h12Compare{ 480 Handler: func(w ResponseWriter, r *Request) { 481 w.Header().Set("Got-Length", fmt.Sprint(r.ContentLength)) 482 fmt.Fprintf(w, "Req.ContentLength=%v", r.ContentLength) 483 }, 484 ReqFunc: func(c *Client, url string) (*Response, error) { 485 return c.Post(url, "text/plain", bodyfn()) 486 }, 487 CheckResponse: func(proto string, res *Response) { 488 if got, want := res.Header.Get("Got-Length"), fmt.Sprint(wantLen); got != want { 489 t.Errorf("Proto %q got length %q; want %q", proto, got, want) 490 } 491 }, 492 }.run(t) 493 } 494 495 // Tests that closing the Request.Cancel channel also while still 496 // reading the response body. Issue 13159. 497 func TestCancelRequestMidBody_h1(t *testing.T) { testCancelRequestMidBody(t, h1Mode) } 498 func TestCancelRequestMidBody_h2(t *testing.T) { testCancelRequestMidBody(t, h2Mode) } 499 func testCancelRequestMidBody(t *testing.T, h2 bool) { 500 defer afterTest(t) 501 unblock := make(chan bool) 502 didFlush := make(chan bool, 1) 503 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 504 io.WriteString(w, "Hello") 505 w.(Flusher).Flush() 506 didFlush <- true 507 <-unblock 508 io.WriteString(w, ", world.") 509 })) 510 defer cst.close() 511 defer close(unblock) 512 513 req, _ := NewRequest("GET", cst.ts.URL, nil) 514 cancel := make(chan struct{}) 515 req.Cancel = cancel 516 517 res, err := cst.c.Do(req) 518 if err != nil { 519 t.Fatal(err) 520 } 521 defer res.Body.Close() 522 <-didFlush 523 524 // Read a bit before we cancel. (Issue 13626) 525 // We should have "Hello" at least sitting there. 526 firstRead := make([]byte, 10) 527 n, err := res.Body.Read(firstRead) 528 if err != nil { 529 t.Fatal(err) 530 } 531 firstRead = firstRead[:n] 532 533 close(cancel) 534 535 rest, err := ioutil.ReadAll(res.Body) 536 all := string(firstRead) + string(rest) 537 if all != "Hello" { 538 t.Errorf("Read %q (%q + %q); want Hello", all, firstRead, rest) 539 } 540 if !reflect.DeepEqual(err, ExportErrRequestCanceled) { 541 t.Errorf("ReadAll error = %v; want %v", err, ExportErrRequestCanceled) 542 } 543 } 544 545 // Tests that clients can send trailers to a server and that the server can read them. 546 func TestTrailersClientToServer_h1(t *testing.T) { testTrailersClientToServer(t, h1Mode) } 547 func TestTrailersClientToServer_h2(t *testing.T) { testTrailersClientToServer(t, h2Mode) } 548 549 func testTrailersClientToServer(t *testing.T, h2 bool) { 550 defer afterTest(t) 551 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 552 var decl []string 553 for k := range r.Trailer { 554 decl = append(decl, k) 555 } 556 sort.Strings(decl) 557 558 slurp, err := ioutil.ReadAll(r.Body) 559 if err != nil { 560 t.Errorf("Server reading request body: %v", err) 561 } 562 if string(slurp) != "foo" { 563 t.Errorf("Server read request body %q; want foo", slurp) 564 } 565 if r.Trailer == nil { 566 io.WriteString(w, "nil Trailer") 567 } else { 568 fmt.Fprintf(w, "decl: %v, vals: %s, %s", 569 decl, 570 r.Trailer.Get("Client-Trailer-A"), 571 r.Trailer.Get("Client-Trailer-B")) 572 } 573 })) 574 defer cst.close() 575 576 var req *Request 577 req, _ = NewRequest("POST", cst.ts.URL, io.MultiReader( 578 eofReaderFunc(func() { 579 req.Trailer["Client-Trailer-A"] = []string{"valuea"} 580 }), 581 strings.NewReader("foo"), 582 eofReaderFunc(func() { 583 req.Trailer["Client-Trailer-B"] = []string{"valueb"} 584 }), 585 )) 586 req.Trailer = Header{ 587 "Client-Trailer-A": nil, // to be set later 588 "Client-Trailer-B": nil, // to be set later 589 } 590 req.ContentLength = -1 591 res, err := cst.c.Do(req) 592 if err != nil { 593 t.Fatal(err) 594 } 595 if err := wantBody(res, err, "decl: [Client-Trailer-A Client-Trailer-B], vals: valuea, valueb"); err != nil { 596 t.Error(err) 597 } 598 } 599 600 // Tests that servers send trailers to a client and that the client can read them. 601 func TestTrailersServerToClient_h1(t *testing.T) { testTrailersServerToClient(t, h1Mode, false) } 602 func TestTrailersServerToClient_h2(t *testing.T) { testTrailersServerToClient(t, h2Mode, false) } 603 func TestTrailersServerToClient_Flush_h1(t *testing.T) { testTrailersServerToClient(t, h1Mode, true) } 604 func TestTrailersServerToClient_Flush_h2(t *testing.T) { testTrailersServerToClient(t, h2Mode, true) } 605 606 func testTrailersServerToClient(t *testing.T, h2, flush bool) { 607 defer afterTest(t) 608 const body = "Some body" 609 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 610 w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B") 611 w.Header().Add("Trailer", "Server-Trailer-C") 612 613 io.WriteString(w, body) 614 if flush { 615 w.(Flusher).Flush() 616 } 617 618 // How handlers set Trailers: declare it ahead of time 619 // with the Trailer header, and then mutate the 620 // Header() of those values later, after the response 621 // has been written (we wrote to w above). 622 w.Header().Set("Server-Trailer-A", "valuea") 623 w.Header().Set("Server-Trailer-C", "valuec") // skipping B 624 w.Header().Set("Server-Trailer-NotDeclared", "should be omitted") 625 })) 626 defer cst.close() 627 628 res, err := cst.c.Get(cst.ts.URL) 629 if err != nil { 630 t.Fatal(err) 631 } 632 633 wantHeader := Header{ 634 "Content-Type": {"text/plain; charset=utf-8"}, 635 } 636 wantLen := -1 637 if h2 && !flush { 638 // In HTTP/1.1, any use of trailers forces HTTP/1.1 639 // chunking and a flush at the first write. That's 640 // unnecessary with HTTP/2's framing, so the server 641 // is able to calculate the length while still sending 642 // trailers afterwards. 643 wantLen = len(body) 644 wantHeader["Content-Length"] = []string{fmt.Sprint(wantLen)} 645 } 646 if res.ContentLength != int64(wantLen) { 647 t.Errorf("ContentLength = %v; want %v", res.ContentLength, wantLen) 648 } 649 650 delete(res.Header, "Date") // irrelevant for test 651 if !reflect.DeepEqual(res.Header, wantHeader) { 652 t.Errorf("Header = %v; want %v", res.Header, wantHeader) 653 } 654 655 if got, want := res.Trailer, (Header{ 656 "Server-Trailer-A": nil, 657 "Server-Trailer-B": nil, 658 "Server-Trailer-C": nil, 659 }); !reflect.DeepEqual(got, want) { 660 t.Errorf("Trailer before body read = %v; want %v", got, want) 661 } 662 663 if err := wantBody(res, nil, body); err != nil { 664 t.Fatal(err) 665 } 666 667 if got, want := res.Trailer, (Header{ 668 "Server-Trailer-A": {"valuea"}, 669 "Server-Trailer-B": nil, 670 "Server-Trailer-C": {"valuec"}, 671 }); !reflect.DeepEqual(got, want) { 672 t.Errorf("Trailer after body read = %v; want %v", got, want) 673 } 674 } 675 676 // Don't allow a Body.Read after Body.Close. Issue 13648. 677 func TestResponseBodyReadAfterClose_h1(t *testing.T) { testResponseBodyReadAfterClose(t, h1Mode) } 678 func TestResponseBodyReadAfterClose_h2(t *testing.T) { testResponseBodyReadAfterClose(t, h2Mode) } 679 680 func testResponseBodyReadAfterClose(t *testing.T, h2 bool) { 681 defer afterTest(t) 682 const body = "Some body" 683 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 684 io.WriteString(w, body) 685 })) 686 defer cst.close() 687 res, err := cst.c.Get(cst.ts.URL) 688 if err != nil { 689 t.Fatal(err) 690 } 691 res.Body.Close() 692 data, err := ioutil.ReadAll(res.Body) 693 if len(data) != 0 || err == nil { 694 t.Fatalf("ReadAll returned %q, %v; want error", data, err) 695 } 696 } 697 698 func TestConcurrentReadWriteReqBody_h1(t *testing.T) { testConcurrentReadWriteReqBody(t, h1Mode) } 699 func TestConcurrentReadWriteReqBody_h2(t *testing.T) { testConcurrentReadWriteReqBody(t, h2Mode) } 700 func testConcurrentReadWriteReqBody(t *testing.T, h2 bool) { 701 defer afterTest(t) 702 const reqBody = "some request body" 703 const resBody = "some response body" 704 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 705 var wg sync.WaitGroup 706 wg.Add(2) 707 didRead := make(chan bool, 1) 708 // Read in one goroutine. 709 go func() { 710 defer wg.Done() 711 data, err := ioutil.ReadAll(r.Body) 712 if string(data) != reqBody { 713 t.Errorf("Handler read %q; want %q", data, reqBody) 714 } 715 if err != nil { 716 t.Errorf("Handler Read: %v", err) 717 } 718 didRead <- true 719 }() 720 // Write in another goroutine. 721 go func() { 722 defer wg.Done() 723 if !h2 { 724 // our HTTP/1 implementation intentionally 725 // doesn't permit writes during read (mostly 726 // due to it being undefined); if that is ever 727 // relaxed, change this. 728 <-didRead 729 } 730 io.WriteString(w, resBody) 731 }() 732 wg.Wait() 733 })) 734 defer cst.close() 735 req, _ := NewRequest("POST", cst.ts.URL, strings.NewReader(reqBody)) 736 req.Header.Add("Expect", "100-continue") // just to complicate things 737 res, err := cst.c.Do(req) 738 if err != nil { 739 t.Fatal(err) 740 } 741 data, err := ioutil.ReadAll(res.Body) 742 defer res.Body.Close() 743 if err != nil { 744 t.Fatal(err) 745 } 746 if string(data) != resBody { 747 t.Errorf("read %q; want %q", data, resBody) 748 } 749 } 750 751 func TestConnectRequest_h1(t *testing.T) { testConnectRequest(t, h1Mode) } 752 func TestConnectRequest_h2(t *testing.T) { testConnectRequest(t, h2Mode) } 753 func testConnectRequest(t *testing.T, h2 bool) { 754 defer afterTest(t) 755 gotc := make(chan *Request, 1) 756 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 757 gotc <- r 758 })) 759 defer cst.close() 760 761 u, err := url.Parse(cst.ts.URL) 762 if err != nil { 763 t.Fatal(err) 764 } 765 766 tests := []struct { 767 req *Request 768 want string 769 }{ 770 { 771 req: &Request{ 772 Method: "CONNECT", 773 Header: Header{}, 774 URL: u, 775 }, 776 want: u.Host, 777 }, 778 { 779 req: &Request{ 780 Method: "CONNECT", 781 Header: Header{}, 782 URL: u, 783 Host: "example.com:123", 784 }, 785 want: "example.com:123", 786 }, 787 } 788 789 for i, tt := range tests { 790 res, err := cst.c.Do(tt.req) 791 if err != nil { 792 t.Errorf("%d. RoundTrip = %v", i, err) 793 continue 794 } 795 res.Body.Close() 796 req := <-gotc 797 if req.Method != "CONNECT" { 798 t.Errorf("method = %q; want CONNECT", req.Method) 799 } 800 if req.Host != tt.want { 801 t.Errorf("Host = %q; want %q", req.Host, tt.want) 802 } 803 if req.URL.Host != tt.want { 804 t.Errorf("URL.Host = %q; want %q", req.URL.Host, tt.want) 805 } 806 } 807 } 808 809 func TestTransportUserAgent_h1(t *testing.T) { testTransportUserAgent(t, h1Mode) } 810 func TestTransportUserAgent_h2(t *testing.T) { testTransportUserAgent(t, h2Mode) } 811 func testTransportUserAgent(t *testing.T, h2 bool) { 812 defer afterTest(t) 813 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 814 fmt.Fprintf(w, "%q", r.Header["User-Agent"]) 815 })) 816 defer cst.close() 817 818 either := func(a, b string) string { 819 if h2 { 820 return b 821 } 822 return a 823 } 824 825 tests := []struct { 826 setup func(*Request) 827 want string 828 }{ 829 { 830 func(r *Request) {}, 831 either(`["Go-http-client/1.1"]`, `["Go-http-client/2.0"]`), 832 }, 833 { 834 func(r *Request) { r.Header.Set("User-Agent", "foo/1.2.3") }, 835 `["foo/1.2.3"]`, 836 }, 837 { 838 func(r *Request) { r.Header["User-Agent"] = []string{"single", "or", "multiple"} }, 839 `["single"]`, 840 }, 841 { 842 func(r *Request) { r.Header.Set("User-Agent", "") }, 843 `[]`, 844 }, 845 { 846 func(r *Request) { r.Header["User-Agent"] = nil }, 847 `[]`, 848 }, 849 } 850 for i, tt := range tests { 851 req, _ := NewRequest("GET", cst.ts.URL, nil) 852 tt.setup(req) 853 res, err := cst.c.Do(req) 854 if err != nil { 855 t.Errorf("%d. RoundTrip = %v", i, err) 856 continue 857 } 858 slurp, err := ioutil.ReadAll(res.Body) 859 res.Body.Close() 860 if err != nil { 861 t.Errorf("%d. read body = %v", i, err) 862 continue 863 } 864 if string(slurp) != tt.want { 865 t.Errorf("%d. body mismatch.\n got: %s\nwant: %s\n", i, slurp, tt.want) 866 } 867 } 868 } 869 870 func TestStarRequestFoo_h1(t *testing.T) { testStarRequest(t, "FOO", h1Mode) } 871 func TestStarRequestFoo_h2(t *testing.T) { testStarRequest(t, "FOO", h2Mode) } 872 func TestStarRequestOptions_h1(t *testing.T) { testStarRequest(t, "OPTIONS", h1Mode) } 873 func TestStarRequestOptions_h2(t *testing.T) { testStarRequest(t, "OPTIONS", h2Mode) } 874 func testStarRequest(t *testing.T, method string, h2 bool) { 875 defer afterTest(t) 876 gotc := make(chan *Request, 1) 877 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 878 w.Header().Set("foo", "bar") 879 gotc <- r 880 w.(Flusher).Flush() 881 })) 882 defer cst.close() 883 884 u, err := url.Parse(cst.ts.URL) 885 if err != nil { 886 t.Fatal(err) 887 } 888 u.Path = "*" 889 890 req := &Request{ 891 Method: method, 892 Header: Header{}, 893 URL: u, 894 } 895 896 res, err := cst.c.Do(req) 897 if err != nil { 898 t.Fatalf("RoundTrip = %v", err) 899 } 900 res.Body.Close() 901 902 wantFoo := "bar" 903 wantLen := int64(-1) 904 if method == "OPTIONS" { 905 wantFoo = "" 906 wantLen = 0 907 } 908 if res.StatusCode != 200 { 909 t.Errorf("status code = %v; want %d", res.Status, 200) 910 } 911 if res.ContentLength != wantLen { 912 t.Errorf("content length = %v; want %d", res.ContentLength, wantLen) 913 } 914 if got := res.Header.Get("foo"); got != wantFoo { 915 t.Errorf("response \"foo\" header = %q; want %q", got, wantFoo) 916 } 917 select { 918 case req = <-gotc: 919 default: 920 req = nil 921 } 922 if req == nil { 923 if method != "OPTIONS" { 924 t.Fatalf("handler never got request") 925 } 926 return 927 } 928 if req.Method != method { 929 t.Errorf("method = %q; want %q", req.Method, method) 930 } 931 if req.URL.Path != "*" { 932 t.Errorf("URL.Path = %q; want *", req.URL.Path) 933 } 934 if req.RequestURI != "*" { 935 t.Errorf("RequestURI = %q; want *", req.RequestURI) 936 } 937 } 938 939 // Issue 13957 940 func TestTransportDiscardsUnneededConns(t *testing.T) { 941 defer afterTest(t) 942 cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) { 943 fmt.Fprintf(w, "Hello, %v", r.RemoteAddr) 944 })) 945 defer cst.close() 946 947 var numOpen, numClose int32 // atomic 948 949 tlsConfig := &tls.Config{InsecureSkipVerify: true} 950 tr := &Transport{ 951 TLSClientConfig: tlsConfig, 952 DialTLS: func(_, addr string) (net.Conn, error) { 953 time.Sleep(10 * time.Millisecond) 954 rc, err := net.Dial("tcp", addr) 955 if err != nil { 956 return nil, err 957 } 958 atomic.AddInt32(&numOpen, 1) 959 c := noteCloseConn{rc, func() { atomic.AddInt32(&numClose, 1) }} 960 return tls.Client(c, tlsConfig), nil 961 }, 962 } 963 if err := ExportHttp2ConfigureTransport(tr); err != nil { 964 t.Fatal(err) 965 } 966 defer tr.CloseIdleConnections() 967 968 c := &Client{Transport: tr} 969 970 const N = 10 971 gotBody := make(chan string, N) 972 var wg sync.WaitGroup 973 for i := 0; i < N; i++ { 974 wg.Add(1) 975 go func() { 976 defer wg.Done() 977 resp, err := c.Get(cst.ts.URL) 978 if err != nil { 979 t.Errorf("Get: %v", err) 980 return 981 } 982 defer resp.Body.Close() 983 slurp, err := ioutil.ReadAll(resp.Body) 984 if err != nil { 985 t.Error(err) 986 } 987 gotBody <- string(slurp) 988 }() 989 } 990 wg.Wait() 991 close(gotBody) 992 993 var last string 994 for got := range gotBody { 995 if last == "" { 996 last = got 997 continue 998 } 999 if got != last { 1000 t.Errorf("Response body changed: %q -> %q", last, got) 1001 } 1002 } 1003 1004 var open, close int32 1005 for i := 0; i < 150; i++ { 1006 open, close = atomic.LoadInt32(&numOpen), atomic.LoadInt32(&numClose) 1007 if open < 1 { 1008 t.Fatalf("open = %d; want at least", open) 1009 } 1010 if close == open-1 { 1011 // Success 1012 return 1013 } 1014 time.Sleep(10 * time.Millisecond) 1015 } 1016 t.Errorf("%d connections opened, %d closed; want %d to close", open, close, open-1) 1017 } 1018 1019 // tests that Transport doesn't retain a pointer to the provided request. 1020 func TestTransportGCRequest_Body_h1(t *testing.T) { testTransportGCRequest(t, h1Mode, true) } 1021 func TestTransportGCRequest_Body_h2(t *testing.T) { testTransportGCRequest(t, h2Mode, true) } 1022 func TestTransportGCRequest_NoBody_h1(t *testing.T) { testTransportGCRequest(t, h1Mode, false) } 1023 func TestTransportGCRequest_NoBody_h2(t *testing.T) { testTransportGCRequest(t, h2Mode, false) } 1024 func testTransportGCRequest(t *testing.T, h2, body bool) { 1025 defer afterTest(t) 1026 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 1027 ioutil.ReadAll(r.Body) 1028 if body { 1029 io.WriteString(w, "Hello.") 1030 } 1031 })) 1032 defer cst.close() 1033 1034 didGC := make(chan struct{}) 1035 (func() { 1036 body := strings.NewReader("some body") 1037 req, _ := NewRequest("POST", cst.ts.URL, body) 1038 runtime.SetFinalizer(req, func(*Request) { close(didGC) }) 1039 res, err := cst.c.Do(req) 1040 if err != nil { 1041 t.Fatal(err) 1042 } 1043 if _, err := ioutil.ReadAll(res.Body); err != nil { 1044 t.Fatal(err) 1045 } 1046 if err := res.Body.Close(); err != nil { 1047 t.Fatal(err) 1048 } 1049 })() 1050 timeout := time.NewTimer(5 * time.Second) 1051 defer timeout.Stop() 1052 for { 1053 select { 1054 case <-didGC: 1055 return 1056 case <-time.After(100 * time.Millisecond): 1057 runtime.GC() 1058 case <-timeout.C: 1059 t.Fatal("never saw GC of request") 1060 } 1061 } 1062 } 1063 1064 func TestTransportRejectsInvalidHeaders_h1(t *testing.T) { 1065 testTransportRejectsInvalidHeaders(t, h1Mode) 1066 } 1067 func TestTransportRejectsInvalidHeaders_h2(t *testing.T) { 1068 testTransportRejectsInvalidHeaders(t, h2Mode) 1069 } 1070 func testTransportRejectsInvalidHeaders(t *testing.T, h2 bool) { 1071 defer afterTest(t) 1072 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 1073 fmt.Fprintf(w, "Handler saw headers: %q", r.Header) 1074 })) 1075 defer cst.close() 1076 cst.tr.DisableKeepAlives = true 1077 1078 tests := []struct { 1079 key, val string 1080 ok bool 1081 }{ 1082 {"Foo", "capital-key", true}, // verify h2 allows capital keys 1083 {"Foo", "foo\x00bar", false}, // \x00 byte in value not allowed 1084 {"Foo", "two\nlines", false}, // \n byte in value not allowed 1085 {"bogus\nkey", "v", false}, // \n byte also not allowed in key 1086 {"A space", "v", false}, // spaces in keys not allowed 1087 {"имя", "v", false}, // key must be ascii 1088 {"name", "валю", true}, // value may be non-ascii 1089 {"", "v", false}, // key must be non-empty 1090 {"k", "", true}, // value may be empty 1091 } 1092 for _, tt := range tests { 1093 dialedc := make(chan bool, 1) 1094 cst.tr.Dial = func(netw, addr string) (net.Conn, error) { 1095 dialedc <- true 1096 return net.Dial(netw, addr) 1097 } 1098 req, _ := NewRequest("GET", cst.ts.URL, nil) 1099 req.Header[tt.key] = []string{tt.val} 1100 res, err := cst.c.Do(req) 1101 var body []byte 1102 if err == nil { 1103 body, _ = ioutil.ReadAll(res.Body) 1104 res.Body.Close() 1105 } 1106 var dialed bool 1107 select { 1108 case <-dialedc: 1109 dialed = true 1110 default: 1111 } 1112 1113 if !tt.ok && dialed { 1114 t.Errorf("For key %q, value %q, transport dialed. Expected local failure. Response was: (%v, %v)\nServer replied with: %s", tt.key, tt.val, res, err, body) 1115 } else if (err == nil) != tt.ok { 1116 t.Errorf("For key %q, value %q; got err = %v; want ok=%v", tt.key, tt.val, err, tt.ok) 1117 } 1118 } 1119 } 1120 1121 // Tests that we support bogus under-100 HTTP statuses, because we historically 1122 // have. This might change at some point, but not yet in Go 1.6. 1123 func TestBogusStatusWorks_h1(t *testing.T) { testBogusStatusWorks(t, h1Mode) } 1124 func TestBogusStatusWorks_h2(t *testing.T) { testBogusStatusWorks(t, h2Mode) } 1125 func testBogusStatusWorks(t *testing.T, h2 bool) { 1126 defer afterTest(t) 1127 const code = 7 1128 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 1129 w.WriteHeader(code) 1130 })) 1131 defer cst.close() 1132 1133 res, err := cst.c.Get(cst.ts.URL) 1134 if err != nil { 1135 t.Fatal(err) 1136 } 1137 if res.StatusCode != code { 1138 t.Errorf("StatusCode = %d; want %d", res.StatusCode, code) 1139 } 1140 } 1141 1142 func TestInterruptWithPanic_h1(t *testing.T) { testInterruptWithPanic(t, h1Mode) } 1143 func TestInterruptWithPanic_h2(t *testing.T) { testInterruptWithPanic(t, h2Mode) } 1144 func testInterruptWithPanic(t *testing.T, h2 bool) { 1145 log.SetOutput(ioutil.Discard) // is noisy otherwise 1146 defer log.SetOutput(os.Stderr) 1147 1148 const msg = "hello" 1149 defer afterTest(t) 1150 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 1151 io.WriteString(w, msg) 1152 w.(Flusher).Flush() 1153 panic("no more") 1154 })) 1155 defer cst.close() 1156 res, err := cst.c.Get(cst.ts.URL) 1157 if err != nil { 1158 t.Fatal(err) 1159 } 1160 defer res.Body.Close() 1161 slurp, err := ioutil.ReadAll(res.Body) 1162 if string(slurp) != msg { 1163 t.Errorf("client read %q; want %q", slurp, msg) 1164 } 1165 if err == nil { 1166 t.Errorf("client read all successfully; want some error") 1167 } 1168 } 1169 1170 // Issue 15366 1171 func TestH12_AutoGzipWithDumpResponse(t *testing.T) { 1172 h12Compare{ 1173 Handler: func(w ResponseWriter, r *Request) { 1174 h := w.Header() 1175 h.Set("Content-Encoding", "gzip") 1176 h.Set("Content-Length", "23") 1177 h.Set("Connection", "keep-alive") 1178 io.WriteString(w, "\x1f\x8b\b\x00\x00\x00\x00\x00\x00\x00s\xf3\xf7\a\x00\xab'\xd4\x1a\x03\x00\x00\x00") 1179 }, 1180 EarlyCheckResponse: func(proto string, res *Response) { 1181 if !res.Uncompressed { 1182 t.Errorf("%s: expected Uncompressed to be set", proto) 1183 } 1184 dump, err := httputil.DumpResponse(res, true) 1185 if err != nil { 1186 t.Errorf("%s: DumpResponse: %v", proto, err) 1187 return 1188 } 1189 if strings.Contains(string(dump), "Connection: close") { 1190 t.Errorf("%s: should not see \"Connection: close\" in dump; got:\n%s", proto, dump) 1191 } 1192 if !strings.Contains(string(dump), "FOO") { 1193 t.Errorf("%s: should see \"FOO\" in response; got:\n%s", proto, dump) 1194 } 1195 }, 1196 }.run(t) 1197 } 1198 1199 // Issue 14607 1200 func TestCloseIdleConnections_h1(t *testing.T) { testCloseIdleConnections(t, h1Mode) } 1201 func TestCloseIdleConnections_h2(t *testing.T) { testCloseIdleConnections(t, h2Mode) } 1202 func testCloseIdleConnections(t *testing.T, h2 bool) { 1203 defer afterTest(t) 1204 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 1205 w.Header().Set("X-Addr", r.RemoteAddr) 1206 })) 1207 defer cst.close() 1208 get := func() string { 1209 res, err := cst.c.Get(cst.ts.URL) 1210 if err != nil { 1211 t.Fatal(err) 1212 } 1213 res.Body.Close() 1214 v := res.Header.Get("X-Addr") 1215 if v == "" { 1216 t.Fatal("didn't get X-Addr") 1217 } 1218 return v 1219 } 1220 a1 := get() 1221 cst.tr.CloseIdleConnections() 1222 a2 := get() 1223 if a1 == a2 { 1224 t.Errorf("didn't close connection") 1225 } 1226 } 1227 1228 type noteCloseConn struct { 1229 net.Conn 1230 closeFunc func() 1231 } 1232 1233 func (x noteCloseConn) Close() error { 1234 x.closeFunc() 1235 return x.Conn.Close() 1236 }