github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/net/http2/transport_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 package http2 6 7 import ( 8 "bufio" 9 "bytes" 10 "context" 11 "encoding/hex" 12 "errors" 13 "flag" 14 "fmt" 15 "io" 16 "io/ioutil" 17 "log" 18 "math/rand" 19 "net" 20 "net/textproto" 21 "net/url" 22 "os" 23 "reflect" 24 "runtime" 25 "sort" 26 "strconv" 27 "strings" 28 "sync" 29 "sync/atomic" 30 "testing" 31 "time" 32 33 http "github.com/hxx258456/ccgo/gmhttp" 34 "github.com/hxx258456/ccgo/gmhttp/httptest" 35 "github.com/hxx258456/ccgo/gmhttp/httptrace" 36 tls "github.com/hxx258456/ccgo/gmtls" 37 "github.com/hxx258456/ccgo/net/http2/hpack" 38 ) 39 40 var ( 41 extNet = flag.Bool("extnet", false, "do external network tests") 42 transportHost = flag.String("transporthost", "http2.golang.org", "hostname to use for TestTransport") 43 insecure = flag.Bool("insecure", false, "insecure TLS dials") // TODO: dead code. remove? 44 ) 45 46 var tlsConfigInsecure = &tls.Config{InsecureSkipVerify: true} 47 48 var canceledCtx context.Context 49 50 func init() { 51 ctx, cancel := context.WithCancel(context.Background()) 52 cancel() 53 canceledCtx = ctx 54 } 55 56 func TestTransportExternal(t *testing.T) { 57 if !*extNet { 58 t.Skip("skipping external network test") 59 } 60 req, _ := http.NewRequest("GET", "https://"+*transportHost+"/", nil) 61 rt := &Transport{TLSClientConfig: tlsConfigInsecure} 62 res, err := rt.RoundTrip(req) 63 if err != nil { 64 t.Fatalf("%v", err) 65 } 66 res.Write(os.Stdout) 67 } 68 69 type fakeTLSConn struct { 70 net.Conn 71 } 72 73 func (c *fakeTLSConn) ConnectionState() tls.ConnectionState { 74 return tls.ConnectionState{ 75 Version: tls.VersionTLS12, 76 CipherSuite: cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 77 } 78 } 79 80 func startH2cServer(t *testing.T) net.Listener { 81 h2Server := &Server{} 82 l := newLocalListener(t) 83 go func() { 84 conn, err := l.Accept() 85 if err != nil { 86 t.Error(err) 87 return 88 } 89 h2Server.ServeConn(&fakeTLSConn{conn}, &ServeConnOpts{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 90 fmt.Fprintf(w, "Hello, %v, http: %v", r.URL.Path, r.TLS == nil) 91 })}) 92 }() 93 return l 94 } 95 96 func TestTransportH2c(t *testing.T) { 97 l := startH2cServer(t) 98 defer l.Close() 99 req, err := http.NewRequest("GET", "http://"+l.Addr().String()+"/foobar", nil) 100 if err != nil { 101 t.Fatal(err) 102 } 103 var gotConnCnt int32 104 trace := &httptrace.ClientTrace{ 105 GotConn: func(connInfo httptrace.GotConnInfo) { 106 if !connInfo.Reused { 107 atomic.AddInt32(&gotConnCnt, 1) 108 } 109 }, 110 } 111 req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) 112 tr := &Transport{ 113 AllowHTTP: true, 114 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 115 return net.Dial(network, addr) 116 }, 117 } 118 res, err := tr.RoundTrip(req) 119 if err != nil { 120 t.Fatal(err) 121 } 122 if res.ProtoMajor != 2 { 123 t.Fatal("proto not h2c") 124 } 125 body, err := ioutil.ReadAll(res.Body) 126 if err != nil { 127 t.Fatal(err) 128 } 129 if got, want := string(body), "Hello, /foobar, http: true"; got != want { 130 t.Fatalf("response got %v, want %v", got, want) 131 } 132 if got, want := gotConnCnt, int32(1); got != want { 133 t.Errorf("Too many got connections: %d", gotConnCnt) 134 } 135 } 136 137 func TestTransport(t *testing.T) { 138 const body = "sup" 139 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 140 io.WriteString(w, body) 141 }, optOnlyServer) 142 defer st.Close() 143 144 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 145 defer tr.CloseIdleConnections() 146 147 u, err := url.Parse(st.ts.URL) 148 if err != nil { 149 t.Fatal(err) 150 } 151 for i, m := range []string{"GET", ""} { 152 req := &http.Request{ 153 Method: m, 154 URL: u, 155 } 156 res, err := tr.RoundTrip(req) 157 if err != nil { 158 t.Fatalf("%d: %s", i, err) 159 } 160 161 t.Logf("%d: Got res: %+v", i, res) 162 if g, w := res.StatusCode, 200; g != w { 163 t.Errorf("%d: StatusCode = %v; want %v", i, g, w) 164 } 165 if g, w := res.Status, "200 OK"; g != w { 166 t.Errorf("%d: Status = %q; want %q", i, g, w) 167 } 168 wantHeader := http.Header{ 169 "Content-Length": []string{"3"}, 170 "Content-Type": []string{"text/plain; charset=utf-8"}, 171 "Date": []string{"XXX"}, // see cleanDate 172 } 173 cleanDate(res) 174 if !reflect.DeepEqual(res.Header, wantHeader) { 175 t.Errorf("%d: res Header = %v; want %v", i, res.Header, wantHeader) 176 } 177 if res.Request != req { 178 t.Errorf("%d: Response.Request = %p; want %p", i, res.Request, req) 179 } 180 if res.TLS == nil { 181 t.Errorf("%d: Response.TLS = nil; want non-nil", i) 182 } 183 slurp, err := ioutil.ReadAll(res.Body) 184 if err != nil { 185 t.Errorf("%d: Body read: %v", i, err) 186 } else if string(slurp) != body { 187 t.Errorf("%d: Body = %q; want %q", i, slurp, body) 188 } 189 res.Body.Close() 190 } 191 } 192 193 func testTransportReusesConns(t *testing.T, useClient, wantSame bool, modReq func(*http.Request)) { 194 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 195 io.WriteString(w, r.RemoteAddr) 196 }, optOnlyServer, func(c net.Conn, st http.ConnState) { 197 t.Logf("conn %v is now state %v", c.RemoteAddr(), st) 198 }) 199 defer st.Close() 200 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 201 if useClient { 202 tr.ConnPool = noDialClientConnPool{new(clientConnPool)} 203 } 204 defer tr.CloseIdleConnections() 205 get := func() string { 206 req, err := http.NewRequest("GET", st.ts.URL, nil) 207 if err != nil { 208 t.Fatal(err) 209 } 210 modReq(req) 211 var res *http.Response 212 if useClient { 213 c := st.ts.Client() 214 ConfigureTransports(c.Transport.(*http.Transport)) 215 res, err = c.Do(req) 216 } else { 217 res, err = tr.RoundTrip(req) 218 } 219 if err != nil { 220 t.Fatal(err) 221 } 222 defer res.Body.Close() 223 slurp, err := ioutil.ReadAll(res.Body) 224 if err != nil { 225 t.Fatalf("Body read: %v", err) 226 } 227 addr := strings.TrimSpace(string(slurp)) 228 if addr == "" { 229 t.Fatalf("didn't get an addr in response") 230 } 231 return addr 232 } 233 first := get() 234 second := get() 235 if got := first == second; got != wantSame { 236 t.Errorf("first and second responses on same connection: %v; want %v", got, wantSame) 237 } 238 } 239 240 func TestTransportReusesConns(t *testing.T) { 241 for _, test := range []struct { 242 name string 243 modReq func(*http.Request) 244 wantSame bool 245 }{{ 246 name: "ReuseConn", 247 modReq: func(*http.Request) {}, 248 wantSame: true, 249 }, { 250 name: "RequestClose", 251 modReq: func(r *http.Request) { r.Close = true }, 252 wantSame: false, 253 }, { 254 name: "ConnClose", 255 modReq: func(r *http.Request) { r.Header.Set("Connection", "close") }, 256 wantSame: false, 257 }} { 258 t.Run(test.name, func(t *testing.T) { 259 t.Run("Transport", func(t *testing.T) { 260 const useClient = false 261 testTransportReusesConns(t, useClient, test.wantSame, test.modReq) 262 }) 263 t.Run("Client", func(t *testing.T) { 264 const useClient = true 265 testTransportReusesConns(t, useClient, test.wantSame, test.modReq) 266 }) 267 }) 268 } 269 } 270 271 func TestTransportGetGotConnHooks_HTTP2Transport(t *testing.T) { 272 testTransportGetGotConnHooks(t, false) 273 } 274 func TestTransportGetGotConnHooks_Client(t *testing.T) { testTransportGetGotConnHooks(t, true) } 275 276 func testTransportGetGotConnHooks(t *testing.T, useClient bool) { 277 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 278 io.WriteString(w, r.RemoteAddr) 279 }, func(s *httptest.Server) { 280 s.EnableHTTP2 = true 281 }, optOnlyServer) 282 defer st.Close() 283 284 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 285 client := st.ts.Client() 286 ConfigureTransports(client.Transport.(*http.Transport)) 287 288 var ( 289 getConns int32 290 gotConns int32 291 ) 292 for i := 0; i < 2; i++ { 293 trace := &httptrace.ClientTrace{ 294 GetConn: func(hostport string) { 295 atomic.AddInt32(&getConns, 1) 296 }, 297 GotConn: func(connInfo httptrace.GotConnInfo) { 298 got := atomic.AddInt32(&gotConns, 1) 299 wantReused, wantWasIdle := false, false 300 if got > 1 { 301 wantReused, wantWasIdle = true, true 302 } 303 if connInfo.Reused != wantReused || connInfo.WasIdle != wantWasIdle { 304 t.Errorf("GotConn %v: Reused=%v (want %v), WasIdle=%v (want %v)", i, connInfo.Reused, wantReused, connInfo.WasIdle, wantWasIdle) 305 } 306 }, 307 } 308 req, err := http.NewRequest("GET", st.ts.URL, nil) 309 if err != nil { 310 t.Fatal(err) 311 } 312 req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) 313 314 var res *http.Response 315 if useClient { 316 res, err = client.Do(req) 317 } else { 318 res, err = tr.RoundTrip(req) 319 } 320 if err != nil { 321 t.Fatal(err) 322 } 323 res.Body.Close() 324 if get := atomic.LoadInt32(&getConns); get != int32(i+1) { 325 t.Errorf("after request %v, %v calls to GetConns: want %v", i, get, i+1) 326 } 327 if got := atomic.LoadInt32(&gotConns); got != int32(i+1) { 328 t.Errorf("after request %v, %v calls to GotConns: want %v", i, got, i+1) 329 } 330 } 331 } 332 333 type testNetConn struct { 334 net.Conn 335 closed bool 336 onClose func() 337 } 338 339 func (c *testNetConn) Close() error { 340 if !c.closed { 341 // We can call Close multiple times on the same net.Conn. 342 c.onClose() 343 } 344 c.closed = true 345 return c.Conn.Close() 346 } 347 348 // Tests that the Transport only keeps one pending dial open per destination address. 349 // https://golang.org/issue/13397 350 func TestTransportGroupsPendingDials(t *testing.T) { 351 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 352 }, optOnlyServer) 353 defer st.Close() 354 var ( 355 mu sync.Mutex 356 dialCount int 357 closeCount int 358 ) 359 tr := &Transport{ 360 TLSClientConfig: tlsConfigInsecure, 361 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 362 mu.Lock() 363 dialCount++ 364 mu.Unlock() 365 c, err := tls.Dial(network, addr, cfg) 366 return &testNetConn{ 367 Conn: c, 368 onClose: func() { 369 mu.Lock() 370 closeCount++ 371 mu.Unlock() 372 }, 373 }, err 374 }, 375 } 376 defer tr.CloseIdleConnections() 377 var wg sync.WaitGroup 378 for i := 0; i < 10; i++ { 379 wg.Add(1) 380 go func() { 381 defer wg.Done() 382 req, err := http.NewRequest("GET", st.ts.URL, nil) 383 if err != nil { 384 t.Error(err) 385 return 386 } 387 res, err := tr.RoundTrip(req) 388 if err != nil { 389 t.Error(err) 390 return 391 } 392 res.Body.Close() 393 }() 394 } 395 wg.Wait() 396 tr.CloseIdleConnections() 397 if dialCount != 1 { 398 t.Errorf("saw %d dials; want 1", dialCount) 399 } 400 if closeCount != 1 { 401 t.Errorf("saw %d closes; want 1", closeCount) 402 } 403 } 404 405 func retry(tries int, delay time.Duration, fn func() error) error { 406 var err error 407 for i := 0; i < tries; i++ { 408 err = fn() 409 if err == nil { 410 return nil 411 } 412 time.Sleep(delay) 413 } 414 return err 415 } 416 417 func TestTransportAbortClosesPipes(t *testing.T) { 418 shutdown := make(chan struct{}) 419 st := newServerTester(t, 420 func(w http.ResponseWriter, r *http.Request) { 421 w.(http.Flusher).Flush() 422 <-shutdown 423 }, 424 optOnlyServer, 425 ) 426 defer st.Close() 427 defer close(shutdown) // we must shutdown before st.Close() to avoid hanging 428 429 errCh := make(chan error) 430 go func() { 431 defer close(errCh) 432 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 433 req, err := http.NewRequest("GET", st.ts.URL, nil) 434 if err != nil { 435 errCh <- err 436 return 437 } 438 res, err := tr.RoundTrip(req) 439 if err != nil { 440 errCh <- err 441 return 442 } 443 defer res.Body.Close() 444 st.closeConn() 445 _, err = ioutil.ReadAll(res.Body) 446 if err == nil { 447 errCh <- errors.New("expected error from res.Body.Read") 448 return 449 } 450 }() 451 452 select { 453 case err := <-errCh: 454 if err != nil { 455 t.Fatal(err) 456 } 457 // deadlock? that's a bug. 458 case <-time.After(3 * time.Second): 459 t.Fatal("timeout") 460 } 461 } 462 463 // TODO: merge this with TestTransportBody to make TestTransportRequest? This 464 // could be a table-driven test with extra goodies. 465 func TestTransportPath(t *testing.T) { 466 gotc := make(chan *url.URL, 1) 467 st := newServerTester(t, 468 func(w http.ResponseWriter, r *http.Request) { 469 gotc <- r.URL 470 }, 471 optOnlyServer, 472 ) 473 defer st.Close() 474 475 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 476 defer tr.CloseIdleConnections() 477 const ( 478 path = "/testpath" 479 query = "q=1" 480 ) 481 surl := st.ts.URL + path + "?" + query 482 req, err := http.NewRequest("POST", surl, nil) 483 if err != nil { 484 t.Fatal(err) 485 } 486 c := &http.Client{Transport: tr} 487 res, err := c.Do(req) 488 if err != nil { 489 t.Fatal(err) 490 } 491 defer res.Body.Close() 492 got := <-gotc 493 if got.Path != path { 494 t.Errorf("Read Path = %q; want %q", got.Path, path) 495 } 496 if got.RawQuery != query { 497 t.Errorf("Read RawQuery = %q; want %q", got.RawQuery, query) 498 } 499 } 500 501 func randString(n int) string { 502 rnd := rand.New(rand.NewSource(int64(n))) 503 b := make([]byte, n) 504 for i := range b { 505 b[i] = byte(rnd.Intn(256)) 506 } 507 return string(b) 508 } 509 510 type panicReader struct{} 511 512 func (panicReader) Read([]byte) (int, error) { panic("unexpected Read") } 513 func (panicReader) Close() error { panic("unexpected Close") } 514 515 func TestActualContentLength(t *testing.T) { 516 tests := []struct { 517 req *http.Request 518 want int64 519 }{ 520 // Verify we don't read from Body: 521 0: { 522 req: &http.Request{Body: panicReader{}}, 523 want: -1, 524 }, 525 // nil Body means 0, regardless of ContentLength: 526 1: { 527 req: &http.Request{Body: nil, ContentLength: 5}, 528 want: 0, 529 }, 530 // ContentLength is used if set. 531 2: { 532 req: &http.Request{Body: panicReader{}, ContentLength: 5}, 533 want: 5, 534 }, 535 // http.NoBody means 0, not -1. 536 3: { 537 req: &http.Request{Body: http.NoBody}, 538 want: 0, 539 }, 540 } 541 for i, tt := range tests { 542 got := actualContentLength(tt.req) 543 if got != tt.want { 544 t.Errorf("test[%d]: got %d; want %d", i, got, tt.want) 545 } 546 } 547 } 548 549 func TestTransportBody(t *testing.T) { 550 bodyTests := []struct { 551 body string 552 noContentLen bool 553 }{ 554 {body: "some message"}, 555 {body: "some message", noContentLen: true}, 556 {body: strings.Repeat("a", 1<<20), noContentLen: true}, 557 {body: strings.Repeat("a", 1<<20)}, 558 {body: randString(16<<10 - 1)}, 559 {body: randString(16 << 10)}, 560 {body: randString(16<<10 + 1)}, 561 {body: randString(512<<10 - 1)}, 562 {body: randString(512 << 10)}, 563 {body: randString(512<<10 + 1)}, 564 {body: randString(1<<20 - 1)}, 565 {body: randString(1 << 20)}, 566 {body: randString(1<<20 + 2)}, 567 } 568 569 type reqInfo struct { 570 req *http.Request 571 slurp []byte 572 err error 573 } 574 gotc := make(chan reqInfo, 1) 575 st := newServerTester(t, 576 func(w http.ResponseWriter, r *http.Request) { 577 slurp, err := ioutil.ReadAll(r.Body) 578 if err != nil { 579 gotc <- reqInfo{err: err} 580 } else { 581 gotc <- reqInfo{req: r, slurp: slurp} 582 } 583 }, 584 optOnlyServer, 585 ) 586 defer st.Close() 587 588 for i, tt := range bodyTests { 589 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 590 defer tr.CloseIdleConnections() 591 592 var body io.Reader = strings.NewReader(tt.body) 593 if tt.noContentLen { 594 body = struct{ io.Reader }{body} // just a Reader, hiding concrete type and other methods 595 } 596 req, err := http.NewRequest("POST", st.ts.URL, body) 597 if err != nil { 598 t.Fatalf("#%d: %v", i, err) 599 } 600 c := &http.Client{Transport: tr} 601 res, err := c.Do(req) 602 if err != nil { 603 t.Fatalf("#%d: %v", i, err) 604 } 605 defer res.Body.Close() 606 ri := <-gotc 607 if ri.err != nil { 608 t.Errorf("#%d: read error: %v", i, ri.err) 609 continue 610 } 611 if got := string(ri.slurp); got != tt.body { 612 t.Errorf("#%d: Read body mismatch.\n got: %q (len %d)\nwant: %q (len %d)", i, shortString(got), len(got), shortString(tt.body), len(tt.body)) 613 } 614 wantLen := int64(len(tt.body)) 615 if tt.noContentLen && tt.body != "" { 616 wantLen = -1 617 } 618 if ri.req.ContentLength != wantLen { 619 t.Errorf("#%d. handler got ContentLength = %v; want %v", i, ri.req.ContentLength, wantLen) 620 } 621 } 622 } 623 624 func shortString(v string) string { 625 const maxLen = 100 626 if len(v) <= maxLen { 627 return v 628 } 629 return fmt.Sprintf("%v[...%d bytes omitted...]%v", v[:maxLen/2], len(v)-maxLen, v[len(v)-maxLen/2:]) 630 } 631 632 func TestTransportDialTLS(t *testing.T) { 633 var mu sync.Mutex // guards following 634 var gotReq, didDial bool 635 636 ts := newServerTester(t, 637 func(w http.ResponseWriter, r *http.Request) { 638 mu.Lock() 639 gotReq = true 640 mu.Unlock() 641 }, 642 optOnlyServer, 643 ) 644 defer ts.Close() 645 tr := &Transport{ 646 DialTLS: func(netw, addr string, cfg *tls.Config) (net.Conn, error) { 647 mu.Lock() 648 didDial = true 649 mu.Unlock() 650 cfg.InsecureSkipVerify = true 651 c, err := tls.Dial(netw, addr, cfg) 652 if err != nil { 653 return nil, err 654 } 655 return c, c.Handshake() 656 }, 657 } 658 defer tr.CloseIdleConnections() 659 client := &http.Client{Transport: tr} 660 res, err := client.Get(ts.ts.URL) 661 if err != nil { 662 t.Fatal(err) 663 } 664 res.Body.Close() 665 mu.Lock() 666 if !gotReq { 667 t.Error("didn't get request") 668 } 669 if !didDial { 670 t.Error("didn't use dial hook") 671 } 672 } 673 674 func TestConfigureTransport(t *testing.T) { 675 t1 := &http.Transport{} 676 err := ConfigureTransport(t1) 677 if err != nil { 678 t.Fatal(err) 679 } 680 if got := fmt.Sprintf("%#v", t1); !strings.Contains(got, `"h2"`) { 681 // Laziness, to avoid buildtags. 682 t.Errorf("stringification of HTTP/1 transport didn't contain \"h2\": %v", got) 683 } 684 wantNextProtos := []string{"h2", "http/1.1"} 685 if t1.TLSClientConfig == nil { 686 t.Errorf("nil t1.TLSClientConfig") 687 } else if !reflect.DeepEqual(t1.TLSClientConfig.NextProtos, wantNextProtos) { 688 t.Errorf("TLSClientConfig.NextProtos = %q; want %q", t1.TLSClientConfig.NextProtos, wantNextProtos) 689 } 690 if err := ConfigureTransport(t1); err == nil { 691 t.Error("unexpected success on second call to ConfigureTransport") 692 } 693 694 // And does it work? 695 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 696 io.WriteString(w, r.Proto) 697 }, optOnlyServer) 698 defer st.Close() 699 700 t1.TLSClientConfig.InsecureSkipVerify = true 701 c := &http.Client{Transport: t1} 702 res, err := c.Get(st.ts.URL) 703 if err != nil { 704 t.Fatal(err) 705 } 706 slurp, err := ioutil.ReadAll(res.Body) 707 if err != nil { 708 t.Fatal(err) 709 } 710 if got, want := string(slurp), "HTTP/2.0"; got != want { 711 t.Errorf("body = %q; want %q", got, want) 712 } 713 } 714 715 type capitalizeReader struct { 716 r io.Reader 717 } 718 719 func (cr capitalizeReader) Read(p []byte) (n int, err error) { 720 n, err = cr.r.Read(p) 721 for i, b := range p[:n] { 722 if b >= 'a' && b <= 'z' { 723 p[i] = b - ('a' - 'A') 724 } 725 } 726 return 727 } 728 729 type flushWriter struct { 730 w io.Writer 731 } 732 733 func (fw flushWriter) Write(p []byte) (n int, err error) { 734 n, err = fw.w.Write(p) 735 if f, ok := fw.w.(http.Flusher); ok { 736 f.Flush() 737 } 738 return 739 } 740 741 type clientTester struct { 742 t *testing.T 743 tr *Transport 744 sc, cc net.Conn // server and client conn 745 fr *Framer // server's framer 746 client func() error 747 server func() error 748 } 749 750 func newClientTester(t *testing.T) *clientTester { 751 var dialOnce struct { 752 sync.Mutex 753 dialed bool 754 } 755 ct := &clientTester{ 756 t: t, 757 } 758 ct.tr = &Transport{ 759 TLSClientConfig: tlsConfigInsecure, 760 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 761 dialOnce.Lock() 762 defer dialOnce.Unlock() 763 if dialOnce.dialed { 764 return nil, errors.New("only one dial allowed in test mode") 765 } 766 dialOnce.dialed = true 767 return ct.cc, nil 768 }, 769 } 770 771 ln := newLocalListener(t) 772 cc, err := net.Dial("tcp", ln.Addr().String()) 773 if err != nil { 774 t.Fatal(err) 775 776 } 777 sc, err := ln.Accept() 778 if err != nil { 779 t.Fatal(err) 780 } 781 ln.Close() 782 ct.cc = cc 783 ct.sc = sc 784 ct.fr = NewFramer(sc, sc) 785 return ct 786 } 787 788 func newLocalListener(t *testing.T) net.Listener { 789 ln, err := net.Listen("tcp4", "127.0.0.1:0") 790 if err == nil { 791 return ln 792 } 793 ln, err = net.Listen("tcp6", "[::1]:0") 794 if err != nil { 795 t.Fatal(err) 796 } 797 return ln 798 } 799 800 func (ct *clientTester) greet(settings ...Setting) { 801 buf := make([]byte, len(ClientPreface)) 802 _, err := io.ReadFull(ct.sc, buf) 803 if err != nil { 804 ct.t.Fatalf("reading client preface: %v", err) 805 } 806 f, err := ct.fr.ReadFrame() 807 if err != nil { 808 ct.t.Fatalf("Reading client settings frame: %v", err) 809 } 810 if sf, ok := f.(*SettingsFrame); !ok { 811 ct.t.Fatalf("Wanted client settings frame; got %v", f) 812 _ = sf // stash it away? 813 } 814 if err := ct.fr.WriteSettings(settings...); err != nil { 815 ct.t.Fatal(err) 816 } 817 if err := ct.fr.WriteSettingsAck(); err != nil { 818 ct.t.Fatal(err) 819 } 820 } 821 822 func (ct *clientTester) readNonSettingsFrame() (Frame, error) { 823 for { 824 f, err := ct.fr.ReadFrame() 825 if err != nil { 826 return nil, err 827 } 828 if _, ok := f.(*SettingsFrame); ok { 829 continue 830 } 831 return f, nil 832 } 833 } 834 835 func (ct *clientTester) cleanup() { 836 ct.tr.CloseIdleConnections() 837 838 // close both connections, ignore the error if its already closed 839 ct.sc.Close() 840 ct.cc.Close() 841 } 842 843 func (ct *clientTester) run() { 844 var errOnce sync.Once 845 var wg sync.WaitGroup 846 847 run := func(which string, fn func() error) { 848 defer wg.Done() 849 if err := fn(); err != nil { 850 errOnce.Do(func() { 851 ct.t.Errorf("%s: %v", which, err) 852 ct.cleanup() 853 }) 854 } 855 } 856 857 wg.Add(2) 858 go run("client", ct.client) 859 go run("server", ct.server) 860 wg.Wait() 861 862 errOnce.Do(ct.cleanup) // clean up if no error 863 } 864 865 func (ct *clientTester) readFrame() (Frame, error) { 866 return ct.fr.ReadFrame() 867 } 868 869 func (ct *clientTester) firstHeaders() (*HeadersFrame, error) { 870 for { 871 f, err := ct.readFrame() 872 if err != nil { 873 return nil, fmt.Errorf("ReadFrame while waiting for Headers: %v", err) 874 } 875 switch f.(type) { 876 case *WindowUpdateFrame, *SettingsFrame: 877 continue 878 } 879 hf, ok := f.(*HeadersFrame) 880 if !ok { 881 return nil, fmt.Errorf("Got %T; want HeadersFrame", f) 882 } 883 return hf, nil 884 } 885 } 886 887 type countingReader struct { 888 n *int64 889 } 890 891 func (r countingReader) Read(p []byte) (n int, err error) { 892 for i := range p { 893 p[i] = byte(i) 894 } 895 atomic.AddInt64(r.n, int64(len(p))) 896 return len(p), err 897 } 898 899 func TestTransportReqBodyAfterResponse_200(t *testing.T) { testTransportReqBodyAfterResponse(t, 200) } 900 func TestTransportReqBodyAfterResponse_403(t *testing.T) { testTransportReqBodyAfterResponse(t, 403) } 901 902 func testTransportReqBodyAfterResponse(t *testing.T, status int) { 903 const bodySize = 10 << 20 904 clientDone := make(chan struct{}) 905 ct := newClientTester(t) 906 recvLen := make(chan int64, 1) 907 ct.client = func() error { 908 defer ct.cc.(*net.TCPConn).CloseWrite() 909 if runtime.GOOS == "plan9" { 910 // CloseWrite not supported on Plan 9; Issue 17906 911 defer ct.cc.(*net.TCPConn).Close() 912 } 913 defer close(clientDone) 914 915 body := &pipe{b: new(bytes.Buffer)} 916 io.Copy(body, io.LimitReader(neverEnding('A'), bodySize/2)) 917 req, err := http.NewRequest("PUT", "https://dummy.tld/", body) 918 if err != nil { 919 return err 920 } 921 res, err := ct.tr.RoundTrip(req) 922 if err != nil { 923 return fmt.Errorf("RoundTrip: %v", err) 924 } 925 if res.StatusCode != status { 926 return fmt.Errorf("status code = %v; want %v", res.StatusCode, status) 927 } 928 io.Copy(body, io.LimitReader(neverEnding('A'), bodySize/2)) 929 body.CloseWithError(io.EOF) 930 slurp, err := ioutil.ReadAll(res.Body) 931 if err != nil { 932 return fmt.Errorf("Slurp: %v", err) 933 } 934 if len(slurp) > 0 { 935 return fmt.Errorf("unexpected body: %q", slurp) 936 } 937 res.Body.Close() 938 if status == 200 { 939 if got := <-recvLen; got != bodySize { 940 return fmt.Errorf("For 200 response, Transport wrote %d bytes; want %d", got, bodySize) 941 } 942 } else { 943 if got := <-recvLen; got == 0 || got >= bodySize { 944 return fmt.Errorf("For %d response, Transport wrote %d bytes; want (0,%d) exclusive", status, got, bodySize) 945 } 946 } 947 return nil 948 } 949 ct.server = func() error { 950 ct.greet() 951 defer close(recvLen) 952 var buf bytes.Buffer 953 enc := hpack.NewEncoder(&buf) 954 var dataRecv int64 955 var closed bool 956 for { 957 f, err := ct.fr.ReadFrame() 958 if err != nil { 959 select { 960 case <-clientDone: 961 // If the client's done, it 962 // will have reported any 963 // errors on its side. 964 return nil 965 default: 966 return err 967 } 968 } 969 //println(fmt.Sprintf("server got frame: %v", f)) 970 ended := false 971 switch f := f.(type) { 972 case *WindowUpdateFrame, *SettingsFrame: 973 case *HeadersFrame: 974 if !f.HeadersEnded() { 975 return fmt.Errorf("headers should have END_HEADERS be ended: %v", f) 976 } 977 if f.StreamEnded() { 978 return fmt.Errorf("headers contains END_STREAM unexpectedly: %v", f) 979 } 980 case *DataFrame: 981 dataLen := len(f.Data()) 982 if dataLen > 0 { 983 if dataRecv == 0 { 984 enc.WriteField(hpack.HeaderField{Name: ":status", Value: strconv.Itoa(status)}) 985 ct.fr.WriteHeaders(HeadersFrameParam{ 986 StreamID: f.StreamID, 987 EndHeaders: true, 988 EndStream: false, 989 BlockFragment: buf.Bytes(), 990 }) 991 } 992 if err := ct.fr.WriteWindowUpdate(0, uint32(dataLen)); err != nil { 993 return err 994 } 995 if err := ct.fr.WriteWindowUpdate(f.StreamID, uint32(dataLen)); err != nil { 996 return err 997 } 998 } 999 dataRecv += int64(dataLen) 1000 1001 if !closed && ((status != 200 && dataRecv > 0) || 1002 (status == 200 && f.StreamEnded())) { 1003 closed = true 1004 if err := ct.fr.WriteData(f.StreamID, true, nil); err != nil { 1005 return err 1006 } 1007 } 1008 1009 if f.StreamEnded() { 1010 ended = true 1011 } 1012 case *RSTStreamFrame: 1013 if status == 200 { 1014 return fmt.Errorf("Unexpected client frame %v", f) 1015 } 1016 ended = true 1017 default: 1018 return fmt.Errorf("Unexpected client frame %v", f) 1019 } 1020 if ended { 1021 select { 1022 case recvLen <- dataRecv: 1023 default: 1024 } 1025 } 1026 } 1027 } 1028 ct.run() 1029 } 1030 1031 // See golang.org/issue/13444 1032 func TestTransportFullDuplex(t *testing.T) { 1033 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 1034 w.WriteHeader(200) // redundant but for clarity 1035 w.(http.Flusher).Flush() 1036 io.Copy(flushWriter{w}, capitalizeReader{r.Body}) 1037 fmt.Fprintf(w, "bye.\n") 1038 }, optOnlyServer) 1039 defer st.Close() 1040 1041 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 1042 defer tr.CloseIdleConnections() 1043 c := &http.Client{Transport: tr} 1044 1045 pr, pw := io.Pipe() 1046 req, err := http.NewRequest("PUT", st.ts.URL, ioutil.NopCloser(pr)) 1047 if err != nil { 1048 t.Fatal(err) 1049 } 1050 req.ContentLength = -1 1051 res, err := c.Do(req) 1052 if err != nil { 1053 t.Fatal(err) 1054 } 1055 defer res.Body.Close() 1056 if res.StatusCode != 200 { 1057 t.Fatalf("StatusCode = %v; want %v", res.StatusCode, 200) 1058 } 1059 bs := bufio.NewScanner(res.Body) 1060 want := func(v string) { 1061 if !bs.Scan() { 1062 t.Fatalf("wanted to read %q but Scan() = false, err = %v", v, bs.Err()) 1063 } 1064 } 1065 write := func(v string) { 1066 _, err := io.WriteString(pw, v) 1067 if err != nil { 1068 t.Fatalf("pipe write: %v", err) 1069 } 1070 } 1071 write("foo\n") 1072 want("FOO") 1073 write("bar\n") 1074 want("BAR") 1075 pw.Close() 1076 want("bye.") 1077 if err := bs.Err(); err != nil { 1078 t.Fatal(err) 1079 } 1080 } 1081 1082 func TestTransportConnectRequest(t *testing.T) { 1083 gotc := make(chan *http.Request, 1) 1084 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 1085 gotc <- r 1086 }, optOnlyServer) 1087 defer st.Close() 1088 1089 u, err := url.Parse(st.ts.URL) 1090 if err != nil { 1091 t.Fatal(err) 1092 } 1093 1094 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 1095 defer tr.CloseIdleConnections() 1096 c := &http.Client{Transport: tr} 1097 1098 tests := []struct { 1099 req *http.Request 1100 want string 1101 }{ 1102 { 1103 req: &http.Request{ 1104 Method: "CONNECT", 1105 Header: http.Header{}, 1106 URL: u, 1107 }, 1108 want: u.Host, 1109 }, 1110 { 1111 req: &http.Request{ 1112 Method: "CONNECT", 1113 Header: http.Header{}, 1114 URL: u, 1115 Host: "example.com:123", 1116 }, 1117 want: "example.com:123", 1118 }, 1119 } 1120 1121 for i, tt := range tests { 1122 res, err := c.Do(tt.req) 1123 if err != nil { 1124 t.Errorf("%d. RoundTrip = %v", i, err) 1125 continue 1126 } 1127 res.Body.Close() 1128 req := <-gotc 1129 if req.Method != "CONNECT" { 1130 t.Errorf("method = %q; want CONNECT", req.Method) 1131 } 1132 if req.Host != tt.want { 1133 t.Errorf("Host = %q; want %q", req.Host, tt.want) 1134 } 1135 if req.URL.Host != tt.want { 1136 t.Errorf("URL.Host = %q; want %q", req.URL.Host, tt.want) 1137 } 1138 } 1139 } 1140 1141 type headerType int 1142 1143 const ( 1144 noHeader headerType = iota // omitted 1145 oneHeader 1146 splitHeader // broken into continuation on purpose 1147 ) 1148 1149 const ( 1150 f0 = noHeader 1151 f1 = oneHeader 1152 f2 = splitHeader 1153 d0 = false 1154 d1 = true 1155 ) 1156 1157 // Test all 36 combinations of response frame orders: 1158 // (3 ways of 100-continue) * (2 ways of headers) * (2 ways of data) * (3 ways of trailers):func TestTransportResponsePattern_00f0(t *testing.T) { testTransportResponsePattern(h0, h1, false, h0) } 1159 // Generated by http://play.golang.org/p/SScqYKJYXd 1160 func TestTransportResPattern_c0h1d0t0(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f0) } 1161 func TestTransportResPattern_c0h1d0t1(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f1) } 1162 func TestTransportResPattern_c0h1d0t2(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f2) } 1163 func TestTransportResPattern_c0h1d1t0(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f0) } 1164 func TestTransportResPattern_c0h1d1t1(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f1) } 1165 func TestTransportResPattern_c0h1d1t2(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f2) } 1166 func TestTransportResPattern_c0h2d0t0(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f0) } 1167 func TestTransportResPattern_c0h2d0t1(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f1) } 1168 func TestTransportResPattern_c0h2d0t2(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f2) } 1169 func TestTransportResPattern_c0h2d1t0(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f0) } 1170 func TestTransportResPattern_c0h2d1t1(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f1) } 1171 func TestTransportResPattern_c0h2d1t2(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f2) } 1172 func TestTransportResPattern_c1h1d0t0(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f0) } 1173 func TestTransportResPattern_c1h1d0t1(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f1) } 1174 func TestTransportResPattern_c1h1d0t2(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f2) } 1175 func TestTransportResPattern_c1h1d1t0(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f0) } 1176 func TestTransportResPattern_c1h1d1t1(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f1) } 1177 func TestTransportResPattern_c1h1d1t2(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f2) } 1178 func TestTransportResPattern_c1h2d0t0(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f0) } 1179 func TestTransportResPattern_c1h2d0t1(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f1) } 1180 func TestTransportResPattern_c1h2d0t2(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f2) } 1181 func TestTransportResPattern_c1h2d1t0(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f0) } 1182 func TestTransportResPattern_c1h2d1t1(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f1) } 1183 func TestTransportResPattern_c1h2d1t2(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f2) } 1184 func TestTransportResPattern_c2h1d0t0(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f0) } 1185 func TestTransportResPattern_c2h1d0t1(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f1) } 1186 func TestTransportResPattern_c2h1d0t2(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f2) } 1187 func TestTransportResPattern_c2h1d1t0(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f0) } 1188 func TestTransportResPattern_c2h1d1t1(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f1) } 1189 func TestTransportResPattern_c2h1d1t2(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f2) } 1190 func TestTransportResPattern_c2h2d0t0(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f0) } 1191 func TestTransportResPattern_c2h2d0t1(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f1) } 1192 func TestTransportResPattern_c2h2d0t2(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f2) } 1193 func TestTransportResPattern_c2h2d1t0(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f0) } 1194 func TestTransportResPattern_c2h2d1t1(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f1) } 1195 func TestTransportResPattern_c2h2d1t2(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f2) } 1196 1197 func testTransportResPattern(t *testing.T, expect100Continue, resHeader headerType, withData bool, trailers headerType) { 1198 const reqBody = "some request body" 1199 const resBody = "some response body" 1200 1201 if resHeader == noHeader { 1202 // TODO: test 100-continue followed by immediate 1203 // server stream reset, without headers in the middle? 1204 panic("invalid combination") 1205 } 1206 1207 ct := newClientTester(t) 1208 ct.client = func() error { 1209 req, _ := http.NewRequest("POST", "https://dummy.tld/", strings.NewReader(reqBody)) 1210 if expect100Continue != noHeader { 1211 req.Header.Set("Expect", "100-continue") 1212 } 1213 res, err := ct.tr.RoundTrip(req) 1214 if err != nil { 1215 return fmt.Errorf("RoundTrip: %v", err) 1216 } 1217 defer res.Body.Close() 1218 if res.StatusCode != 200 { 1219 return fmt.Errorf("status code = %v; want 200", res.StatusCode) 1220 } 1221 slurp, err := ioutil.ReadAll(res.Body) 1222 if err != nil { 1223 return fmt.Errorf("Slurp: %v", err) 1224 } 1225 wantBody := resBody 1226 if !withData { 1227 wantBody = "" 1228 } 1229 if string(slurp) != wantBody { 1230 return fmt.Errorf("body = %q; want %q", slurp, wantBody) 1231 } 1232 if trailers == noHeader { 1233 if len(res.Trailer) > 0 { 1234 t.Errorf("Trailer = %v; want none", res.Trailer) 1235 } 1236 } else { 1237 want := http.Header{"Some-Trailer": {"some-value"}} 1238 if !reflect.DeepEqual(res.Trailer, want) { 1239 t.Errorf("Trailer = %v; want %v", res.Trailer, want) 1240 } 1241 } 1242 return nil 1243 } 1244 ct.server = func() error { 1245 ct.greet() 1246 var buf bytes.Buffer 1247 enc := hpack.NewEncoder(&buf) 1248 1249 for { 1250 f, err := ct.fr.ReadFrame() 1251 if err != nil { 1252 return err 1253 } 1254 endStream := false 1255 send := func(mode headerType) { 1256 hbf := buf.Bytes() 1257 switch mode { 1258 case oneHeader: 1259 ct.fr.WriteHeaders(HeadersFrameParam{ 1260 StreamID: f.Header().StreamID, 1261 EndHeaders: true, 1262 EndStream: endStream, 1263 BlockFragment: hbf, 1264 }) 1265 case splitHeader: 1266 if len(hbf) < 2 { 1267 panic("too small") 1268 } 1269 ct.fr.WriteHeaders(HeadersFrameParam{ 1270 StreamID: f.Header().StreamID, 1271 EndHeaders: false, 1272 EndStream: endStream, 1273 BlockFragment: hbf[:1], 1274 }) 1275 ct.fr.WriteContinuation(f.Header().StreamID, true, hbf[1:]) 1276 default: 1277 panic("bogus mode") 1278 } 1279 } 1280 switch f := f.(type) { 1281 case *WindowUpdateFrame, *SettingsFrame: 1282 case *DataFrame: 1283 if !f.StreamEnded() { 1284 // No need to send flow control tokens. The test request body is tiny. 1285 continue 1286 } 1287 // Response headers (1+ frames; 1 or 2 in this test, but never 0) 1288 { 1289 buf.Reset() 1290 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 1291 enc.WriteField(hpack.HeaderField{Name: "x-foo", Value: "blah"}) 1292 enc.WriteField(hpack.HeaderField{Name: "x-bar", Value: "more"}) 1293 if trailers != noHeader { 1294 enc.WriteField(hpack.HeaderField{Name: "trailer", Value: "some-trailer"}) 1295 } 1296 endStream = withData == false && trailers == noHeader 1297 send(resHeader) 1298 } 1299 if withData { 1300 endStream = trailers == noHeader 1301 ct.fr.WriteData(f.StreamID, endStream, []byte(resBody)) 1302 } 1303 if trailers != noHeader { 1304 endStream = true 1305 buf.Reset() 1306 enc.WriteField(hpack.HeaderField{Name: "some-trailer", Value: "some-value"}) 1307 send(trailers) 1308 } 1309 if endStream { 1310 return nil 1311 } 1312 case *HeadersFrame: 1313 if expect100Continue != noHeader { 1314 buf.Reset() 1315 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "100"}) 1316 send(expect100Continue) 1317 } 1318 } 1319 } 1320 } 1321 ct.run() 1322 } 1323 1324 // Issue 26189, Issue 17739: ignore unknown 1xx responses 1325 func TestTransportUnknown1xx(t *testing.T) { 1326 var buf bytes.Buffer 1327 defer func() { got1xxFuncForTests = nil }() 1328 got1xxFuncForTests = func(code int, header textproto.MIMEHeader) error { 1329 fmt.Fprintf(&buf, "code=%d header=%v\n", code, header) 1330 return nil 1331 } 1332 1333 ct := newClientTester(t) 1334 ct.client = func() error { 1335 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 1336 res, err := ct.tr.RoundTrip(req) 1337 if err != nil { 1338 return fmt.Errorf("RoundTrip: %v", err) 1339 } 1340 defer res.Body.Close() 1341 if res.StatusCode != 204 { 1342 return fmt.Errorf("status code = %v; want 204", res.StatusCode) 1343 } 1344 want := `code=110 header=map[Foo-Bar:[110]] 1345 code=111 header=map[Foo-Bar:[111]] 1346 code=112 header=map[Foo-Bar:[112]] 1347 code=113 header=map[Foo-Bar:[113]] 1348 code=114 header=map[Foo-Bar:[114]] 1349 ` 1350 if got := buf.String(); got != want { 1351 t.Errorf("Got trace:\n%s\nWant:\n%s", got, want) 1352 } 1353 return nil 1354 } 1355 ct.server = func() error { 1356 ct.greet() 1357 var buf bytes.Buffer 1358 enc := hpack.NewEncoder(&buf) 1359 1360 for { 1361 f, err := ct.fr.ReadFrame() 1362 if err != nil { 1363 return err 1364 } 1365 switch f := f.(type) { 1366 case *WindowUpdateFrame, *SettingsFrame: 1367 case *HeadersFrame: 1368 for i := 110; i <= 114; i++ { 1369 buf.Reset() 1370 enc.WriteField(hpack.HeaderField{Name: ":status", Value: fmt.Sprint(i)}) 1371 enc.WriteField(hpack.HeaderField{Name: "foo-bar", Value: fmt.Sprint(i)}) 1372 ct.fr.WriteHeaders(HeadersFrameParam{ 1373 StreamID: f.StreamID, 1374 EndHeaders: true, 1375 EndStream: false, 1376 BlockFragment: buf.Bytes(), 1377 }) 1378 } 1379 buf.Reset() 1380 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "204"}) 1381 ct.fr.WriteHeaders(HeadersFrameParam{ 1382 StreamID: f.StreamID, 1383 EndHeaders: true, 1384 EndStream: false, 1385 BlockFragment: buf.Bytes(), 1386 }) 1387 return nil 1388 } 1389 } 1390 } 1391 ct.run() 1392 1393 } 1394 1395 func TestTransportReceiveUndeclaredTrailer(t *testing.T) { 1396 ct := newClientTester(t) 1397 ct.client = func() error { 1398 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 1399 res, err := ct.tr.RoundTrip(req) 1400 if err != nil { 1401 return fmt.Errorf("RoundTrip: %v", err) 1402 } 1403 defer res.Body.Close() 1404 if res.StatusCode != 200 { 1405 return fmt.Errorf("status code = %v; want 200", res.StatusCode) 1406 } 1407 slurp, err := ioutil.ReadAll(res.Body) 1408 if err != nil { 1409 return fmt.Errorf("res.Body ReadAll error = %q, %v; want %v", slurp, err, nil) 1410 } 1411 if len(slurp) > 0 { 1412 return fmt.Errorf("body = %q; want nothing", slurp) 1413 } 1414 if _, ok := res.Trailer["Some-Trailer"]; !ok { 1415 return fmt.Errorf("expected Some-Trailer") 1416 } 1417 return nil 1418 } 1419 ct.server = func() error { 1420 ct.greet() 1421 1422 var n int 1423 var hf *HeadersFrame 1424 for hf == nil && n < 10 { 1425 f, err := ct.fr.ReadFrame() 1426 if err != nil { 1427 return err 1428 } 1429 hf, _ = f.(*HeadersFrame) 1430 n++ 1431 } 1432 1433 var buf bytes.Buffer 1434 enc := hpack.NewEncoder(&buf) 1435 1436 // send headers without Trailer header 1437 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 1438 ct.fr.WriteHeaders(HeadersFrameParam{ 1439 StreamID: hf.StreamID, 1440 EndHeaders: true, 1441 EndStream: false, 1442 BlockFragment: buf.Bytes(), 1443 }) 1444 1445 // send trailers 1446 buf.Reset() 1447 enc.WriteField(hpack.HeaderField{Name: "some-trailer", Value: "I'm an undeclared Trailer!"}) 1448 ct.fr.WriteHeaders(HeadersFrameParam{ 1449 StreamID: hf.StreamID, 1450 EndHeaders: true, 1451 EndStream: true, 1452 BlockFragment: buf.Bytes(), 1453 }) 1454 return nil 1455 } 1456 ct.run() 1457 } 1458 1459 func TestTransportInvalidTrailer_Pseudo1(t *testing.T) { 1460 testTransportInvalidTrailer_Pseudo(t, oneHeader) 1461 } 1462 func TestTransportInvalidTrailer_Pseudo2(t *testing.T) { 1463 testTransportInvalidTrailer_Pseudo(t, splitHeader) 1464 } 1465 func testTransportInvalidTrailer_Pseudo(t *testing.T, trailers headerType) { 1466 testInvalidTrailer(t, trailers, pseudoHeaderError(":colon"), func(enc *hpack.Encoder) { 1467 enc.WriteField(hpack.HeaderField{Name: ":colon", Value: "foo"}) 1468 enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"}) 1469 }) 1470 } 1471 1472 func TestTransportInvalidTrailer_Capital1(t *testing.T) { 1473 testTransportInvalidTrailer_Capital(t, oneHeader) 1474 } 1475 func TestTransportInvalidTrailer_Capital2(t *testing.T) { 1476 testTransportInvalidTrailer_Capital(t, splitHeader) 1477 } 1478 func testTransportInvalidTrailer_Capital(t *testing.T, trailers headerType) { 1479 testInvalidTrailer(t, trailers, headerFieldNameError("Capital"), func(enc *hpack.Encoder) { 1480 enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"}) 1481 enc.WriteField(hpack.HeaderField{Name: "Capital", Value: "bad"}) 1482 }) 1483 } 1484 func TestTransportInvalidTrailer_EmptyFieldName(t *testing.T) { 1485 testInvalidTrailer(t, oneHeader, headerFieldNameError(""), func(enc *hpack.Encoder) { 1486 enc.WriteField(hpack.HeaderField{Name: "", Value: "bad"}) 1487 }) 1488 } 1489 func TestTransportInvalidTrailer_BinaryFieldValue(t *testing.T) { 1490 testInvalidTrailer(t, oneHeader, headerFieldValueError("has\nnewline"), func(enc *hpack.Encoder) { 1491 enc.WriteField(hpack.HeaderField{Name: "x", Value: "has\nnewline"}) 1492 }) 1493 } 1494 1495 func testInvalidTrailer(t *testing.T, trailers headerType, wantErr error, writeTrailer func(*hpack.Encoder)) { 1496 ct := newClientTester(t) 1497 ct.client = func() error { 1498 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 1499 res, err := ct.tr.RoundTrip(req) 1500 if err != nil { 1501 return fmt.Errorf("RoundTrip: %v", err) 1502 } 1503 defer res.Body.Close() 1504 if res.StatusCode != 200 { 1505 return fmt.Errorf("status code = %v; want 200", res.StatusCode) 1506 } 1507 slurp, err := ioutil.ReadAll(res.Body) 1508 se, ok := err.(StreamError) 1509 if !ok || se.Cause != wantErr { 1510 return fmt.Errorf("res.Body ReadAll error = %q, %#v; want StreamError with cause %T, %#v", slurp, err, wantErr, wantErr) 1511 } 1512 if len(slurp) > 0 { 1513 return fmt.Errorf("body = %q; want nothing", slurp) 1514 } 1515 return nil 1516 } 1517 ct.server = func() error { 1518 ct.greet() 1519 var buf bytes.Buffer 1520 enc := hpack.NewEncoder(&buf) 1521 1522 for { 1523 f, err := ct.fr.ReadFrame() 1524 if err != nil { 1525 return err 1526 } 1527 switch f := f.(type) { 1528 case *HeadersFrame: 1529 var endStream bool 1530 send := func(mode headerType) { 1531 hbf := buf.Bytes() 1532 switch mode { 1533 case oneHeader: 1534 ct.fr.WriteHeaders(HeadersFrameParam{ 1535 StreamID: f.StreamID, 1536 EndHeaders: true, 1537 EndStream: endStream, 1538 BlockFragment: hbf, 1539 }) 1540 case splitHeader: 1541 if len(hbf) < 2 { 1542 panic("too small") 1543 } 1544 ct.fr.WriteHeaders(HeadersFrameParam{ 1545 StreamID: f.StreamID, 1546 EndHeaders: false, 1547 EndStream: endStream, 1548 BlockFragment: hbf[:1], 1549 }) 1550 ct.fr.WriteContinuation(f.StreamID, true, hbf[1:]) 1551 default: 1552 panic("bogus mode") 1553 } 1554 } 1555 // Response headers (1+ frames; 1 or 2 in this test, but never 0) 1556 { 1557 buf.Reset() 1558 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 1559 enc.WriteField(hpack.HeaderField{Name: "trailer", Value: "declared"}) 1560 endStream = false 1561 send(oneHeader) 1562 } 1563 // Trailers: 1564 { 1565 endStream = true 1566 buf.Reset() 1567 writeTrailer(enc) 1568 send(trailers) 1569 } 1570 return nil 1571 } 1572 } 1573 } 1574 ct.run() 1575 } 1576 1577 // headerListSize returns the HTTP2 header list size of h. 1578 // http://httpwg.org/specs/rfc7540.html#SETTINGS_MAX_HEADER_LIST_SIZE 1579 // http://httpwg.org/specs/rfc7540.html#MaxHeaderBlock 1580 func headerListSize(h http.Header) (size uint32) { 1581 for k, vv := range h { 1582 for _, v := range vv { 1583 hf := hpack.HeaderField{Name: k, Value: v} 1584 size += hf.Size() 1585 } 1586 } 1587 return size 1588 } 1589 1590 // padHeaders adds data to an http.Header until headerListSize(h) == 1591 // limit. Due to the way header list sizes are calculated, padHeaders 1592 // cannot add fewer than len("Pad-Headers") + 32 bytes to h, and will 1593 // call t.Fatal if asked to do so. PadHeaders first reserves enough 1594 // space for an empty "Pad-Headers" key, then adds as many copies of 1595 // filler as possible. Any remaining bytes necessary to push the 1596 // header list size up to limit are added to h["Pad-Headers"]. 1597 func padHeaders(t *testing.T, h http.Header, limit uint64, filler string) { 1598 if limit > 0xffffffff { 1599 t.Fatalf("padHeaders: refusing to pad to more than 2^32-1 bytes. limit = %v", limit) 1600 } 1601 hf := hpack.HeaderField{Name: "Pad-Headers", Value: ""} 1602 minPadding := uint64(hf.Size()) 1603 size := uint64(headerListSize(h)) 1604 1605 minlimit := size + minPadding 1606 if limit < minlimit { 1607 t.Fatalf("padHeaders: limit %v < %v", limit, minlimit) 1608 } 1609 1610 // Use a fixed-width format for name so that fieldSize 1611 // remains constant. 1612 nameFmt := "Pad-Headers-%06d" 1613 hf = hpack.HeaderField{Name: fmt.Sprintf(nameFmt, 1), Value: filler} 1614 fieldSize := uint64(hf.Size()) 1615 1616 // Add as many complete filler values as possible, leaving 1617 // room for at least one empty "Pad-Headers" key. 1618 limit = limit - minPadding 1619 for i := 0; size+fieldSize < limit; i++ { 1620 name := fmt.Sprintf(nameFmt, i) 1621 h.Add(name, filler) 1622 size += fieldSize 1623 } 1624 1625 // Add enough bytes to reach limit. 1626 remain := limit - size 1627 lastValue := strings.Repeat("*", int(remain)) 1628 h.Add("Pad-Headers", lastValue) 1629 } 1630 1631 func TestPadHeaders(t *testing.T) { 1632 check := func(h http.Header, limit uint32, fillerLen int) { 1633 if h == nil { 1634 h = make(http.Header) 1635 } 1636 filler := strings.Repeat("f", fillerLen) 1637 padHeaders(t, h, uint64(limit), filler) 1638 gotSize := headerListSize(h) 1639 if gotSize != limit { 1640 t.Errorf("Got size = %v; want %v", gotSize, limit) 1641 } 1642 } 1643 // Try all possible combinations for small fillerLen and limit. 1644 hf := hpack.HeaderField{Name: "Pad-Headers", Value: ""} 1645 minLimit := hf.Size() 1646 for limit := minLimit; limit <= 128; limit++ { 1647 for fillerLen := 0; uint32(fillerLen) <= limit; fillerLen++ { 1648 check(nil, limit, fillerLen) 1649 } 1650 } 1651 1652 // Try a few tests with larger limits, plus cumulative 1653 // tests. Since these tests are cumulative, tests[i+1].limit 1654 // must be >= tests[i].limit + minLimit. See the comment on 1655 // padHeaders for more info on why the limit arg has this 1656 // restriction. 1657 tests := []struct { 1658 fillerLen int 1659 limit uint32 1660 }{ 1661 { 1662 fillerLen: 64, 1663 limit: 1024, 1664 }, 1665 { 1666 fillerLen: 1024, 1667 limit: 1286, 1668 }, 1669 { 1670 fillerLen: 256, 1671 limit: 2048, 1672 }, 1673 { 1674 fillerLen: 1024, 1675 limit: 10 * 1024, 1676 }, 1677 { 1678 fillerLen: 1023, 1679 limit: 11 * 1024, 1680 }, 1681 } 1682 h := make(http.Header) 1683 for _, tc := range tests { 1684 check(nil, tc.limit, tc.fillerLen) 1685 check(h, tc.limit, tc.fillerLen) 1686 } 1687 } 1688 1689 func TestTransportChecksRequestHeaderListSize(t *testing.T) { 1690 st := newServerTester(t, 1691 func(w http.ResponseWriter, r *http.Request) { 1692 // Consume body & force client to send 1693 // trailers before writing response. 1694 // ioutil.ReadAll returns non-nil err for 1695 // requests that attempt to send greater than 1696 // maxHeaderListSize bytes of trailers, since 1697 // those requests generate a stream reset. 1698 ioutil.ReadAll(r.Body) 1699 r.Body.Close() 1700 }, 1701 func(ts *httptest.Server) { 1702 ts.Config.MaxHeaderBytes = 16 << 10 1703 }, 1704 optOnlyServer, 1705 optQuiet, 1706 ) 1707 defer st.Close() 1708 1709 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 1710 defer tr.CloseIdleConnections() 1711 1712 checkRoundTrip := func(req *http.Request, wantErr error, desc string) { 1713 res, err := tr.RoundTrip(req) 1714 if err != wantErr { 1715 if res != nil { 1716 res.Body.Close() 1717 } 1718 t.Errorf("%v: RoundTrip err = %v; want %v", desc, err, wantErr) 1719 return 1720 } 1721 if err == nil { 1722 if res == nil { 1723 t.Errorf("%v: response nil; want non-nil.", desc) 1724 return 1725 } 1726 defer res.Body.Close() 1727 if res.StatusCode != http.StatusOK { 1728 t.Errorf("%v: response status = %v; want %v", desc, res.StatusCode, http.StatusOK) 1729 } 1730 return 1731 } 1732 if res != nil { 1733 t.Errorf("%v: RoundTrip err = %v but response non-nil", desc, err) 1734 } 1735 } 1736 headerListSizeForRequest := func(req *http.Request) (size uint64) { 1737 contentLen := actualContentLength(req) 1738 trailers, err := commaSeparatedTrailers(req) 1739 if err != nil { 1740 t.Fatalf("headerListSizeForRequest: %v", err) 1741 } 1742 cc := &ClientConn{peerMaxHeaderListSize: 0xffffffffffffffff} 1743 cc.henc = hpack.NewEncoder(&cc.hbuf) 1744 cc.mu.Lock() 1745 hdrs, err := cc.encodeHeaders(req, true, trailers, contentLen) 1746 cc.mu.Unlock() 1747 if err != nil { 1748 t.Fatalf("headerListSizeForRequest: %v", err) 1749 } 1750 hpackDec := hpack.NewDecoder(initialHeaderTableSize, func(hf hpack.HeaderField) { 1751 size += uint64(hf.Size()) 1752 }) 1753 if len(hdrs) > 0 { 1754 if _, err := hpackDec.Write(hdrs); err != nil { 1755 t.Fatalf("headerListSizeForRequest: %v", err) 1756 } 1757 } 1758 return size 1759 } 1760 // Create a new Request for each test, rather than reusing the 1761 // same Request, to avoid a race when modifying req.Headers. 1762 // See https://github.com/golang/go/issues/21316 1763 newRequest := func() *http.Request { 1764 // Body must be non-nil to enable writing trailers. 1765 body := strings.NewReader("hello") 1766 req, err := http.NewRequest("POST", st.ts.URL, body) 1767 if err != nil { 1768 t.Fatalf("newRequest: NewRequest: %v", err) 1769 } 1770 return req 1771 } 1772 1773 // Make an arbitrary request to ensure we get the server's 1774 // settings frame and initialize peerMaxHeaderListSize. 1775 req := newRequest() 1776 checkRoundTrip(req, nil, "Initial request") 1777 1778 // Get the ClientConn associated with the request and validate 1779 // peerMaxHeaderListSize. 1780 addr := authorityAddr(req.URL.Scheme, req.URL.Host) 1781 cc, err := tr.connPool().GetClientConn(req, addr) 1782 if err != nil { 1783 t.Fatalf("GetClientConn: %v", err) 1784 } 1785 cc.mu.Lock() 1786 peerSize := cc.peerMaxHeaderListSize 1787 cc.mu.Unlock() 1788 st.scMu.Lock() 1789 wantSize := uint64(st.sc.maxHeaderListSize()) 1790 st.scMu.Unlock() 1791 if peerSize != wantSize { 1792 t.Errorf("peerMaxHeaderListSize = %v; want %v", peerSize, wantSize) 1793 } 1794 1795 // Sanity check peerSize. (*serverConn) maxHeaderListSize adds 1796 // 320 bytes of padding. 1797 wantHeaderBytes := uint64(st.ts.Config.MaxHeaderBytes) + 320 1798 if peerSize != wantHeaderBytes { 1799 t.Errorf("peerMaxHeaderListSize = %v; want %v.", peerSize, wantHeaderBytes) 1800 } 1801 1802 // Pad headers & trailers, but stay under peerSize. 1803 req = newRequest() 1804 req.Header = make(http.Header) 1805 req.Trailer = make(http.Header) 1806 filler := strings.Repeat("*", 1024) 1807 padHeaders(t, req.Trailer, peerSize, filler) 1808 // cc.encodeHeaders adds some default headers to the request, 1809 // so we need to leave room for those. 1810 defaultBytes := headerListSizeForRequest(req) 1811 padHeaders(t, req.Header, peerSize-defaultBytes, filler) 1812 checkRoundTrip(req, nil, "Headers & Trailers under limit") 1813 1814 // Add enough header bytes to push us over peerSize. 1815 req = newRequest() 1816 req.Header = make(http.Header) 1817 padHeaders(t, req.Header, peerSize, filler) 1818 checkRoundTrip(req, errRequestHeaderListSize, "Headers over limit") 1819 1820 // Push trailers over the limit. 1821 req = newRequest() 1822 req.Trailer = make(http.Header) 1823 padHeaders(t, req.Trailer, peerSize+1, filler) 1824 checkRoundTrip(req, errRequestHeaderListSize, "Trailers over limit") 1825 1826 // Send headers with a single large value. 1827 req = newRequest() 1828 filler = strings.Repeat("*", int(peerSize)) 1829 req.Header = make(http.Header) 1830 req.Header.Set("Big", filler) 1831 checkRoundTrip(req, errRequestHeaderListSize, "Single large header") 1832 1833 // Send trailers with a single large value. 1834 req = newRequest() 1835 req.Trailer = make(http.Header) 1836 req.Trailer.Set("Big", filler) 1837 checkRoundTrip(req, errRequestHeaderListSize, "Single large trailer") 1838 } 1839 1840 func TestTransportChecksResponseHeaderListSize(t *testing.T) { 1841 ct := newClientTester(t) 1842 ct.client = func() error { 1843 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 1844 res, err := ct.tr.RoundTrip(req) 1845 if e, ok := err.(StreamError); ok { 1846 err = e.Cause 1847 } 1848 if err != errResponseHeaderListSize { 1849 size := int64(0) 1850 if res != nil { 1851 res.Body.Close() 1852 for k, vv := range res.Header { 1853 for _, v := range vv { 1854 size += int64(len(k)) + int64(len(v)) + 32 1855 } 1856 } 1857 } 1858 return fmt.Errorf("RoundTrip Error = %v (and %d bytes of response headers); want errResponseHeaderListSize", err, size) 1859 } 1860 return nil 1861 } 1862 ct.server = func() error { 1863 ct.greet() 1864 var buf bytes.Buffer 1865 enc := hpack.NewEncoder(&buf) 1866 1867 for { 1868 f, err := ct.fr.ReadFrame() 1869 if err != nil { 1870 return err 1871 } 1872 switch f := f.(type) { 1873 case *HeadersFrame: 1874 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 1875 large := strings.Repeat("a", 1<<10) 1876 for i := 0; i < 5042; i++ { 1877 enc.WriteField(hpack.HeaderField{Name: large, Value: large}) 1878 } 1879 if size, want := buf.Len(), 6329; size != want { 1880 // Note: this number might change if 1881 // our hpack implementation 1882 // changes. That's fine. This is 1883 // just a sanity check that our 1884 // response can fit in a single 1885 // header block fragment frame. 1886 return fmt.Errorf("encoding over 10MB of duplicate keypairs took %d bytes; expected %d", size, want) 1887 } 1888 ct.fr.WriteHeaders(HeadersFrameParam{ 1889 StreamID: f.StreamID, 1890 EndHeaders: true, 1891 EndStream: true, 1892 BlockFragment: buf.Bytes(), 1893 }) 1894 return nil 1895 } 1896 } 1897 } 1898 ct.run() 1899 } 1900 1901 func TestTransportCookieHeaderSplit(t *testing.T) { 1902 ct := newClientTester(t) 1903 ct.client = func() error { 1904 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 1905 req.Header.Add("Cookie", "a=b;c=d; e=f;") 1906 req.Header.Add("Cookie", "e=f;g=h; ") 1907 req.Header.Add("Cookie", "i=j") 1908 _, err := ct.tr.RoundTrip(req) 1909 return err 1910 } 1911 ct.server = func() error { 1912 ct.greet() 1913 for { 1914 f, err := ct.fr.ReadFrame() 1915 if err != nil { 1916 return err 1917 } 1918 switch f := f.(type) { 1919 case *HeadersFrame: 1920 dec := hpack.NewDecoder(initialHeaderTableSize, nil) 1921 hfs, err := dec.DecodeFull(f.HeaderBlockFragment()) 1922 if err != nil { 1923 return err 1924 } 1925 got := []string{} 1926 want := []string{"a=b", "c=d", "e=f", "e=f", "g=h", "i=j"} 1927 for _, hf := range hfs { 1928 if hf.Name == "cookie" { 1929 got = append(got, hf.Value) 1930 } 1931 } 1932 if !reflect.DeepEqual(got, want) { 1933 t.Errorf("Cookies = %#v, want %#v", got, want) 1934 } 1935 1936 var buf bytes.Buffer 1937 enc := hpack.NewEncoder(&buf) 1938 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 1939 ct.fr.WriteHeaders(HeadersFrameParam{ 1940 StreamID: f.StreamID, 1941 EndHeaders: true, 1942 EndStream: true, 1943 BlockFragment: buf.Bytes(), 1944 }) 1945 return nil 1946 } 1947 } 1948 } 1949 ct.run() 1950 } 1951 1952 // Test that the Transport returns a typed error from Response.Body.Read calls 1953 // when the server sends an error. (here we use a panic, since that should generate 1954 // a stream error, but others like cancel should be similar) 1955 func TestTransportBodyReadErrorType(t *testing.T) { 1956 doPanic := make(chan bool, 1) 1957 st := newServerTester(t, 1958 func(w http.ResponseWriter, r *http.Request) { 1959 w.(http.Flusher).Flush() // force headers out 1960 <-doPanic 1961 panic("boom") 1962 }, 1963 optOnlyServer, 1964 optQuiet, 1965 ) 1966 defer st.Close() 1967 1968 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 1969 defer tr.CloseIdleConnections() 1970 c := &http.Client{Transport: tr} 1971 1972 res, err := c.Get(st.ts.URL) 1973 if err != nil { 1974 t.Fatal(err) 1975 } 1976 defer res.Body.Close() 1977 doPanic <- true 1978 buf := make([]byte, 100) 1979 n, err := res.Body.Read(buf) 1980 got, ok := err.(StreamError) 1981 want := StreamError{StreamID: 0x1, Code: 0x2} 1982 if !ok || got.StreamID != want.StreamID || got.Code != want.Code { 1983 t.Errorf("Read = %v, %#v; want error %#v", n, err, want) 1984 } 1985 } 1986 1987 // golang.org/issue/13924 1988 // This used to fail after many iterations, especially with -race: 1989 // go test -v -run=TestTransportDoubleCloseOnWriteError -count=500 -race 1990 func TestTransportDoubleCloseOnWriteError(t *testing.T) { 1991 var ( 1992 mu sync.Mutex 1993 conn net.Conn // to close if set 1994 ) 1995 1996 st := newServerTester(t, 1997 func(w http.ResponseWriter, r *http.Request) { 1998 mu.Lock() 1999 defer mu.Unlock() 2000 if conn != nil { 2001 conn.Close() 2002 } 2003 }, 2004 optOnlyServer, 2005 ) 2006 defer st.Close() 2007 2008 tr := &Transport{ 2009 TLSClientConfig: tlsConfigInsecure, 2010 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 2011 tc, err := tls.Dial(network, addr, cfg) 2012 if err != nil { 2013 return nil, err 2014 } 2015 mu.Lock() 2016 defer mu.Unlock() 2017 conn = tc 2018 return tc, nil 2019 }, 2020 } 2021 defer tr.CloseIdleConnections() 2022 c := &http.Client{Transport: tr} 2023 c.Get(st.ts.URL) 2024 } 2025 2026 // Test that the http1 Transport.DisableKeepAlives option is respected 2027 // and connections are closed as soon as idle. 2028 // See golang.org/issue/14008 2029 func TestTransportDisableKeepAlives(t *testing.T) { 2030 st := newServerTester(t, 2031 func(w http.ResponseWriter, r *http.Request) { 2032 io.WriteString(w, "hi") 2033 }, 2034 optOnlyServer, 2035 ) 2036 defer st.Close() 2037 2038 connClosed := make(chan struct{}) // closed on tls.Conn.Close 2039 tr := &Transport{ 2040 t1: &http.Transport{ 2041 DisableKeepAlives: true, 2042 }, 2043 TLSClientConfig: tlsConfigInsecure, 2044 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 2045 tc, err := tls.Dial(network, addr, cfg) 2046 if err != nil { 2047 return nil, err 2048 } 2049 return ¬eCloseConn{Conn: tc, closefn: func() { close(connClosed) }}, nil 2050 }, 2051 } 2052 c := &http.Client{Transport: tr} 2053 res, err := c.Get(st.ts.URL) 2054 if err != nil { 2055 t.Fatal(err) 2056 } 2057 if _, err := ioutil.ReadAll(res.Body); err != nil { 2058 t.Fatal(err) 2059 } 2060 defer res.Body.Close() 2061 2062 select { 2063 case <-connClosed: 2064 case <-time.After(1 * time.Second): 2065 t.Errorf("timeout") 2066 } 2067 2068 } 2069 2070 // Test concurrent requests with Transport.DisableKeepAlives. We can share connections, 2071 // but when things are totally idle, it still needs to close. 2072 func TestTransportDisableKeepAlives_Concurrency(t *testing.T) { 2073 const D = 25 * time.Millisecond 2074 st := newServerTester(t, 2075 func(w http.ResponseWriter, r *http.Request) { 2076 time.Sleep(D) 2077 io.WriteString(w, "hi") 2078 }, 2079 optOnlyServer, 2080 ) 2081 defer st.Close() 2082 2083 var dials int32 2084 var conns sync.WaitGroup 2085 tr := &Transport{ 2086 t1: &http.Transport{ 2087 DisableKeepAlives: true, 2088 }, 2089 TLSClientConfig: tlsConfigInsecure, 2090 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 2091 tc, err := tls.Dial(network, addr, cfg) 2092 if err != nil { 2093 return nil, err 2094 } 2095 atomic.AddInt32(&dials, 1) 2096 conns.Add(1) 2097 return ¬eCloseConn{Conn: tc, closefn: func() { conns.Done() }}, nil 2098 }, 2099 } 2100 c := &http.Client{Transport: tr} 2101 var reqs sync.WaitGroup 2102 const N = 20 2103 for i := 0; i < N; i++ { 2104 reqs.Add(1) 2105 if i == N-1 { 2106 // For the final request, try to make all the 2107 // others close. This isn't verified in the 2108 // count, other than the Log statement, since 2109 // it's so timing dependent. This test is 2110 // really to make sure we don't interrupt a 2111 // valid request. 2112 time.Sleep(D * 2) 2113 } 2114 go func() { 2115 defer reqs.Done() 2116 res, err := c.Get(st.ts.URL) 2117 if err != nil { 2118 t.Error(err) 2119 return 2120 } 2121 if _, err := ioutil.ReadAll(res.Body); err != nil { 2122 t.Error(err) 2123 return 2124 } 2125 res.Body.Close() 2126 }() 2127 } 2128 reqs.Wait() 2129 conns.Wait() 2130 t.Logf("did %d dials, %d requests", atomic.LoadInt32(&dials), N) 2131 } 2132 2133 type noteCloseConn struct { 2134 net.Conn 2135 onceClose sync.Once 2136 closefn func() 2137 } 2138 2139 func (c *noteCloseConn) Close() error { 2140 c.onceClose.Do(c.closefn) 2141 return c.Conn.Close() 2142 } 2143 2144 func isTimeout(err error) bool { 2145 switch err := err.(type) { 2146 case nil: 2147 return false 2148 case *url.Error: 2149 return isTimeout(err.Err) 2150 case net.Error: 2151 return err.Timeout() 2152 } 2153 return false 2154 } 2155 2156 // Test that the http1 Transport.ResponseHeaderTimeout option and cancel is sent. 2157 func TestTransportResponseHeaderTimeout_NoBody(t *testing.T) { 2158 testTransportResponseHeaderTimeout(t, false) 2159 } 2160 func TestTransportResponseHeaderTimeout_Body(t *testing.T) { 2161 testTransportResponseHeaderTimeout(t, true) 2162 } 2163 2164 func testTransportResponseHeaderTimeout(t *testing.T, body bool) { 2165 ct := newClientTester(t) 2166 ct.tr.t1 = &http.Transport{ 2167 ResponseHeaderTimeout: 5 * time.Millisecond, 2168 } 2169 ct.client = func() error { 2170 c := &http.Client{Transport: ct.tr} 2171 var err error 2172 var n int64 2173 const bodySize = 4 << 20 2174 if body { 2175 _, err = c.Post("https://dummy.tld/", "text/foo", io.LimitReader(countingReader{&n}, bodySize)) 2176 } else { 2177 _, err = c.Get("https://dummy.tld/") 2178 } 2179 if !isTimeout(err) { 2180 t.Errorf("client expected timeout error; got %#v", err) 2181 } 2182 if body && n != bodySize { 2183 t.Errorf("only read %d bytes of body; want %d", n, bodySize) 2184 } 2185 return nil 2186 } 2187 ct.server = func() error { 2188 ct.greet() 2189 for { 2190 f, err := ct.fr.ReadFrame() 2191 if err != nil { 2192 t.Logf("ReadFrame: %v", err) 2193 return nil 2194 } 2195 switch f := f.(type) { 2196 case *DataFrame: 2197 dataLen := len(f.Data()) 2198 if dataLen > 0 { 2199 if err := ct.fr.WriteWindowUpdate(0, uint32(dataLen)); err != nil { 2200 return err 2201 } 2202 if err := ct.fr.WriteWindowUpdate(f.StreamID, uint32(dataLen)); err != nil { 2203 return err 2204 } 2205 } 2206 case *RSTStreamFrame: 2207 if f.StreamID == 1 && f.ErrCode == ErrCodeCancel { 2208 return nil 2209 } 2210 } 2211 } 2212 } 2213 ct.run() 2214 } 2215 2216 func TestTransportDisableCompression(t *testing.T) { 2217 const body = "sup" 2218 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2219 want := http.Header{ 2220 "User-Agent": []string{"Go-http-client/2.0"}, 2221 } 2222 if !reflect.DeepEqual(r.Header, want) { 2223 t.Errorf("request headers = %v; want %v", r.Header, want) 2224 } 2225 }, optOnlyServer) 2226 defer st.Close() 2227 2228 tr := &Transport{ 2229 TLSClientConfig: tlsConfigInsecure, 2230 t1: &http.Transport{ 2231 DisableCompression: true, 2232 }, 2233 } 2234 defer tr.CloseIdleConnections() 2235 2236 req, err := http.NewRequest("GET", st.ts.URL, nil) 2237 if err != nil { 2238 t.Fatal(err) 2239 } 2240 res, err := tr.RoundTrip(req) 2241 if err != nil { 2242 t.Fatal(err) 2243 } 2244 defer res.Body.Close() 2245 } 2246 2247 // RFC 7540 section 8.1.2.2 2248 func TestTransportRejectsConnHeaders(t *testing.T) { 2249 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2250 var got []string 2251 for k := range r.Header { 2252 got = append(got, k) 2253 } 2254 sort.Strings(got) 2255 w.Header().Set("Got-Header", strings.Join(got, ",")) 2256 }, optOnlyServer) 2257 defer st.Close() 2258 2259 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 2260 defer tr.CloseIdleConnections() 2261 2262 tests := []struct { 2263 key string 2264 value []string 2265 want string 2266 }{ 2267 { 2268 key: "Upgrade", 2269 value: []string{"anything"}, 2270 want: "ERROR: http2: invalid Upgrade request header: [\"anything\"]", 2271 }, 2272 { 2273 key: "Connection", 2274 value: []string{"foo"}, 2275 want: "ERROR: http2: invalid Connection request header: [\"foo\"]", 2276 }, 2277 { 2278 key: "Connection", 2279 value: []string{"close"}, 2280 want: "Accept-Encoding,User-Agent", 2281 }, 2282 { 2283 key: "Connection", 2284 value: []string{"CLoSe"}, 2285 want: "Accept-Encoding,User-Agent", 2286 }, 2287 { 2288 key: "Connection", 2289 value: []string{"close", "something-else"}, 2290 want: "ERROR: http2: invalid Connection request header: [\"close\" \"something-else\"]", 2291 }, 2292 { 2293 key: "Connection", 2294 value: []string{"keep-alive"}, 2295 want: "Accept-Encoding,User-Agent", 2296 }, 2297 { 2298 key: "Connection", 2299 value: []string{"Keep-ALIVE"}, 2300 want: "Accept-Encoding,User-Agent", 2301 }, 2302 { 2303 key: "Proxy-Connection", // just deleted and ignored 2304 value: []string{"keep-alive"}, 2305 want: "Accept-Encoding,User-Agent", 2306 }, 2307 { 2308 key: "Transfer-Encoding", 2309 value: []string{""}, 2310 want: "Accept-Encoding,User-Agent", 2311 }, 2312 { 2313 key: "Transfer-Encoding", 2314 value: []string{"foo"}, 2315 want: "ERROR: http2: invalid Transfer-Encoding request header: [\"foo\"]", 2316 }, 2317 { 2318 key: "Transfer-Encoding", 2319 value: []string{"chunked"}, 2320 want: "Accept-Encoding,User-Agent", 2321 }, 2322 { 2323 key: "Transfer-Encoding", 2324 value: []string{"chunKed"}, // Kelvin sign 2325 want: "ERROR: http2: invalid Transfer-Encoding request header: [\"chunKed\"]", 2326 }, 2327 { 2328 key: "Transfer-Encoding", 2329 value: []string{"chunked", "other"}, 2330 want: "ERROR: http2: invalid Transfer-Encoding request header: [\"chunked\" \"other\"]", 2331 }, 2332 { 2333 key: "Content-Length", 2334 value: []string{"123"}, 2335 want: "Accept-Encoding,User-Agent", 2336 }, 2337 { 2338 key: "Keep-Alive", 2339 value: []string{"doop"}, 2340 want: "Accept-Encoding,User-Agent", 2341 }, 2342 } 2343 2344 for _, tt := range tests { 2345 req, _ := http.NewRequest("GET", st.ts.URL, nil) 2346 req.Header[tt.key] = tt.value 2347 res, err := tr.RoundTrip(req) 2348 var got string 2349 if err != nil { 2350 got = fmt.Sprintf("ERROR: %v", err) 2351 } else { 2352 got = res.Header.Get("Got-Header") 2353 res.Body.Close() 2354 } 2355 if got != tt.want { 2356 t.Errorf("For key %q, value %q, got = %q; want %q", tt.key, tt.value, got, tt.want) 2357 } 2358 } 2359 } 2360 2361 // Reject content-length headers containing a sign. 2362 // See https://golang.org/issue/39017 2363 func TestTransportRejectsContentLengthWithSign(t *testing.T) { 2364 tests := []struct { 2365 name string 2366 cl []string 2367 wantCL string 2368 }{ 2369 { 2370 name: "proper content-length", 2371 cl: []string{"3"}, 2372 wantCL: "3", 2373 }, 2374 { 2375 name: "ignore cl with plus sign", 2376 cl: []string{"+3"}, 2377 wantCL: "", 2378 }, 2379 { 2380 name: "ignore cl with minus sign", 2381 cl: []string{"-3"}, 2382 wantCL: "", 2383 }, 2384 { 2385 name: "max int64, for safe uint64->int64 conversion", 2386 cl: []string{"9223372036854775807"}, 2387 wantCL: "9223372036854775807", 2388 }, 2389 { 2390 name: "overflows int64, so ignored", 2391 cl: []string{"9223372036854775808"}, 2392 wantCL: "", 2393 }, 2394 } 2395 2396 for _, tt := range tests { 2397 tt := tt 2398 t.Run(tt.name, func(t *testing.T) { 2399 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2400 w.Header().Set("Content-Length", tt.cl[0]) 2401 }, optOnlyServer) 2402 defer st.Close() 2403 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 2404 defer tr.CloseIdleConnections() 2405 2406 req, _ := http.NewRequest("HEAD", st.ts.URL, nil) 2407 res, err := tr.RoundTrip(req) 2408 2409 var got string 2410 if err != nil { 2411 got = fmt.Sprintf("ERROR: %v", err) 2412 } else { 2413 got = res.Header.Get("Content-Length") 2414 res.Body.Close() 2415 } 2416 2417 if got != tt.wantCL { 2418 t.Fatalf("Got: %q\nWant: %q", got, tt.wantCL) 2419 } 2420 }) 2421 } 2422 } 2423 2424 // golang.org/issue/14048 2425 func TestTransportFailsOnInvalidHeaders(t *testing.T) { 2426 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2427 var got []string 2428 for k := range r.Header { 2429 got = append(got, k) 2430 } 2431 sort.Strings(got) 2432 w.Header().Set("Got-Header", strings.Join(got, ",")) 2433 }, optOnlyServer) 2434 defer st.Close() 2435 2436 tests := [...]struct { 2437 h http.Header 2438 wantErr string 2439 }{ 2440 0: { 2441 h: http.Header{"with space": {"foo"}}, 2442 wantErr: `invalid HTTP header name "with space"`, 2443 }, 2444 1: { 2445 h: http.Header{"name": {"Брэд"}}, 2446 wantErr: "", // okay 2447 }, 2448 2: { 2449 h: http.Header{"имя": {"Brad"}}, 2450 wantErr: `invalid HTTP header name "имя"`, 2451 }, 2452 3: { 2453 h: http.Header{"foo": {"foo\x01bar"}}, 2454 wantErr: `invalid HTTP header value "foo\x01bar" for header "foo"`, 2455 }, 2456 } 2457 2458 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 2459 defer tr.CloseIdleConnections() 2460 2461 for i, tt := range tests { 2462 req, _ := http.NewRequest("GET", st.ts.URL, nil) 2463 req.Header = tt.h 2464 res, err := tr.RoundTrip(req) 2465 var bad bool 2466 if tt.wantErr == "" { 2467 if err != nil { 2468 bad = true 2469 t.Errorf("case %d: error = %v; want no error", i, err) 2470 } 2471 } else { 2472 if !strings.Contains(fmt.Sprint(err), tt.wantErr) { 2473 bad = true 2474 t.Errorf("case %d: error = %v; want error %q", i, err, tt.wantErr) 2475 } 2476 } 2477 if err == nil { 2478 if bad { 2479 t.Logf("case %d: server got headers %q", i, res.Header.Get("Got-Header")) 2480 } 2481 res.Body.Close() 2482 } 2483 } 2484 } 2485 2486 // Tests that gzipReader doesn't crash on a second Read call following 2487 // the first Read call's gzip.NewReader returning an error. 2488 func TestGzipReader_DoubleReadCrash(t *testing.T) { 2489 gz := &gzipReader{ 2490 body: ioutil.NopCloser(strings.NewReader("0123456789")), 2491 } 2492 var buf [1]byte 2493 n, err1 := gz.Read(buf[:]) 2494 if n != 0 || !strings.Contains(fmt.Sprint(err1), "invalid header") { 2495 t.Fatalf("Read = %v, %v; want 0, invalid header", n, err1) 2496 } 2497 n, err2 := gz.Read(buf[:]) 2498 if n != 0 || err2 != err1 { 2499 t.Fatalf("second Read = %v, %v; want 0, %v", n, err2, err1) 2500 } 2501 } 2502 2503 func TestTransportNewTLSConfig(t *testing.T) { 2504 tests := [...]struct { 2505 conf *tls.Config 2506 host string 2507 want *tls.Config 2508 }{ 2509 // Normal case. 2510 0: { 2511 conf: nil, 2512 host: "foo.com", 2513 want: &tls.Config{ 2514 ServerName: "foo.com", 2515 NextProtos: []string{NextProtoTLS}, 2516 }, 2517 }, 2518 2519 // User-provided name (bar.com) takes precedence: 2520 1: { 2521 conf: &tls.Config{ 2522 ServerName: "bar.com", 2523 }, 2524 host: "foo.com", 2525 want: &tls.Config{ 2526 ServerName: "bar.com", 2527 NextProtos: []string{NextProtoTLS}, 2528 }, 2529 }, 2530 2531 // NextProto is prepended: 2532 2: { 2533 conf: &tls.Config{ 2534 NextProtos: []string{"foo", "bar"}, 2535 }, 2536 host: "example.com", 2537 want: &tls.Config{ 2538 ServerName: "example.com", 2539 NextProtos: []string{NextProtoTLS, "foo", "bar"}, 2540 }, 2541 }, 2542 2543 // NextProto is not duplicated: 2544 3: { 2545 conf: &tls.Config{ 2546 NextProtos: []string{"foo", "bar", NextProtoTLS}, 2547 }, 2548 host: "example.com", 2549 want: &tls.Config{ 2550 ServerName: "example.com", 2551 NextProtos: []string{"foo", "bar", NextProtoTLS}, 2552 }, 2553 }, 2554 } 2555 for i, tt := range tests { 2556 // Ignore the session ticket keys part, which ends up populating 2557 // unexported fields in the Config: 2558 if tt.conf != nil { 2559 tt.conf.SessionTicketsDisabled = true 2560 } 2561 2562 tr := &Transport{TLSClientConfig: tt.conf} 2563 got := tr.newTLSConfig(tt.host) 2564 2565 got.SessionTicketsDisabled = false 2566 2567 if !reflect.DeepEqual(got, tt.want) { 2568 t.Errorf("%d. got %#v; want %#v", i, got, tt.want) 2569 } 2570 } 2571 } 2572 2573 // The Google GFE responds to HEAD requests with a HEADERS frame 2574 // without END_STREAM, followed by a 0-length DATA frame with 2575 // END_STREAM. Make sure we don't get confused by that. (We did.) 2576 func TestTransportReadHeadResponse(t *testing.T) { 2577 ct := newClientTester(t) 2578 clientDone := make(chan struct{}) 2579 ct.client = func() error { 2580 defer close(clientDone) 2581 req, _ := http.NewRequest("HEAD", "https://dummy.tld/", nil) 2582 res, err := ct.tr.RoundTrip(req) 2583 if err != nil { 2584 return err 2585 } 2586 if res.ContentLength != 123 { 2587 return fmt.Errorf("Content-Length = %d; want 123", res.ContentLength) 2588 } 2589 slurp, err := ioutil.ReadAll(res.Body) 2590 if err != nil { 2591 return fmt.Errorf("ReadAll: %v", err) 2592 } 2593 if len(slurp) > 0 { 2594 return fmt.Errorf("Unexpected non-empty ReadAll body: %q", slurp) 2595 } 2596 return nil 2597 } 2598 ct.server = func() error { 2599 ct.greet() 2600 for { 2601 f, err := ct.fr.ReadFrame() 2602 if err != nil { 2603 t.Logf("ReadFrame: %v", err) 2604 return nil 2605 } 2606 hf, ok := f.(*HeadersFrame) 2607 if !ok { 2608 continue 2609 } 2610 var buf bytes.Buffer 2611 enc := hpack.NewEncoder(&buf) 2612 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 2613 enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "123"}) 2614 ct.fr.WriteHeaders(HeadersFrameParam{ 2615 StreamID: hf.StreamID, 2616 EndHeaders: true, 2617 EndStream: false, // as the GFE does 2618 BlockFragment: buf.Bytes(), 2619 }) 2620 ct.fr.WriteData(hf.StreamID, true, nil) 2621 2622 <-clientDone 2623 return nil 2624 } 2625 } 2626 ct.run() 2627 } 2628 2629 func TestTransportReadHeadResponseWithBody(t *testing.T) { 2630 // This test use not valid response format. 2631 // Discarding logger output to not spam tests output. 2632 log.SetOutput(ioutil.Discard) 2633 defer log.SetOutput(os.Stderr) 2634 2635 response := "redirecting to /elsewhere" 2636 ct := newClientTester(t) 2637 clientDone := make(chan struct{}) 2638 ct.client = func() error { 2639 defer close(clientDone) 2640 req, _ := http.NewRequest("HEAD", "https://dummy.tld/", nil) 2641 res, err := ct.tr.RoundTrip(req) 2642 if err != nil { 2643 return err 2644 } 2645 if res.ContentLength != int64(len(response)) { 2646 return fmt.Errorf("Content-Length = %d; want %d", res.ContentLength, len(response)) 2647 } 2648 slurp, err := ioutil.ReadAll(res.Body) 2649 if err != nil { 2650 return fmt.Errorf("ReadAll: %v", err) 2651 } 2652 if len(slurp) > 0 { 2653 return fmt.Errorf("Unexpected non-empty ReadAll body: %q", slurp) 2654 } 2655 return nil 2656 } 2657 ct.server = func() error { 2658 ct.greet() 2659 for { 2660 f, err := ct.fr.ReadFrame() 2661 if err != nil { 2662 t.Logf("ReadFrame: %v", err) 2663 return nil 2664 } 2665 hf, ok := f.(*HeadersFrame) 2666 if !ok { 2667 continue 2668 } 2669 var buf bytes.Buffer 2670 enc := hpack.NewEncoder(&buf) 2671 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 2672 enc.WriteField(hpack.HeaderField{Name: "content-length", Value: strconv.Itoa(len(response))}) 2673 ct.fr.WriteHeaders(HeadersFrameParam{ 2674 StreamID: hf.StreamID, 2675 EndHeaders: true, 2676 EndStream: false, 2677 BlockFragment: buf.Bytes(), 2678 }) 2679 ct.fr.WriteData(hf.StreamID, true, []byte(response)) 2680 2681 <-clientDone 2682 return nil 2683 } 2684 } 2685 ct.run() 2686 } 2687 2688 type neverEnding byte 2689 2690 func (b neverEnding) Read(p []byte) (int, error) { 2691 for i := range p { 2692 p[i] = byte(b) 2693 } 2694 return len(p), nil 2695 } 2696 2697 // golang.org/issue/15425: test that a handler closing the request 2698 // body doesn't terminate the stream to the peer. (It just stops 2699 // readability from the handler's side, and eventually the client 2700 // runs out of flow control tokens) 2701 func TestTransportHandlerBodyClose(t *testing.T) { 2702 const bodySize = 10 << 20 2703 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2704 r.Body.Close() 2705 io.Copy(w, io.LimitReader(neverEnding('A'), bodySize)) 2706 }, optOnlyServer) 2707 defer st.Close() 2708 2709 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 2710 defer tr.CloseIdleConnections() 2711 2712 g0 := runtime.NumGoroutine() 2713 2714 const numReq = 10 2715 for i := 0; i < numReq; i++ { 2716 req, err := http.NewRequest("POST", st.ts.URL, struct{ io.Reader }{io.LimitReader(neverEnding('A'), bodySize)}) 2717 if err != nil { 2718 t.Fatal(err) 2719 } 2720 res, err := tr.RoundTrip(req) 2721 if err != nil { 2722 t.Fatal(err) 2723 } 2724 n, err := io.Copy(ioutil.Discard, res.Body) 2725 res.Body.Close() 2726 if n != bodySize || err != nil { 2727 t.Fatalf("req#%d: Copy = %d, %v; want %d, nil", i, n, err, bodySize) 2728 } 2729 } 2730 tr.CloseIdleConnections() 2731 2732 if !waitCondition(5*time.Second, 100*time.Millisecond, func() bool { 2733 gd := runtime.NumGoroutine() - g0 2734 return gd < numReq/2 2735 }) { 2736 t.Errorf("appeared to leak goroutines") 2737 } 2738 } 2739 2740 // https://golang.org/issue/15930 2741 func TestTransportFlowControl(t *testing.T) { 2742 const bufLen = 64 << 10 2743 var total int64 = 100 << 20 // 100MB 2744 if testing.Short() { 2745 total = 10 << 20 2746 } 2747 2748 var wrote int64 // updated atomically 2749 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2750 b := make([]byte, bufLen) 2751 for wrote < total { 2752 n, err := w.Write(b) 2753 atomic.AddInt64(&wrote, int64(n)) 2754 if err != nil { 2755 t.Errorf("ResponseWriter.Write error: %v", err) 2756 break 2757 } 2758 w.(http.Flusher).Flush() 2759 } 2760 }, optOnlyServer) 2761 2762 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 2763 defer tr.CloseIdleConnections() 2764 req, err := http.NewRequest("GET", st.ts.URL, nil) 2765 if err != nil { 2766 t.Fatal("NewRequest error:", err) 2767 } 2768 resp, err := tr.RoundTrip(req) 2769 if err != nil { 2770 t.Fatal("RoundTrip error:", err) 2771 } 2772 defer resp.Body.Close() 2773 2774 var read int64 2775 b := make([]byte, bufLen) 2776 for { 2777 n, err := resp.Body.Read(b) 2778 if err == io.EOF { 2779 break 2780 } 2781 if err != nil { 2782 t.Fatal("Read error:", err) 2783 } 2784 read += int64(n) 2785 2786 const max = transportDefaultStreamFlow 2787 if w := atomic.LoadInt64(&wrote); -max > read-w || read-w > max { 2788 t.Fatalf("Too much data inflight: server wrote %v bytes but client only received %v", w, read) 2789 } 2790 2791 // Let the server get ahead of the client. 2792 time.Sleep(1 * time.Millisecond) 2793 } 2794 } 2795 2796 // golang.org/issue/14627 -- if the server sends a GOAWAY frame, make 2797 // the Transport remember it and return it back to users (via 2798 // RoundTrip or request body reads) if needed (e.g. if the server 2799 // proceeds to close the TCP connection before the client gets its 2800 // response) 2801 func TestTransportUsesGoAwayDebugError_RoundTrip(t *testing.T) { 2802 testTransportUsesGoAwayDebugError(t, false) 2803 } 2804 2805 func TestTransportUsesGoAwayDebugError_Body(t *testing.T) { 2806 testTransportUsesGoAwayDebugError(t, true) 2807 } 2808 2809 func testTransportUsesGoAwayDebugError(t *testing.T, failMidBody bool) { 2810 ct := newClientTester(t) 2811 clientDone := make(chan struct{}) 2812 2813 const goAwayErrCode = ErrCodeHTTP11Required // arbitrary 2814 const goAwayDebugData = "some debug data" 2815 2816 ct.client = func() error { 2817 defer close(clientDone) 2818 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 2819 res, err := ct.tr.RoundTrip(req) 2820 if failMidBody { 2821 if err != nil { 2822 return fmt.Errorf("unexpected client RoundTrip error: %v", err) 2823 } 2824 _, err = io.Copy(ioutil.Discard, res.Body) 2825 res.Body.Close() 2826 } 2827 want := GoAwayError{ 2828 LastStreamID: 5, 2829 ErrCode: goAwayErrCode, 2830 DebugData: goAwayDebugData, 2831 } 2832 if !reflect.DeepEqual(err, want) { 2833 t.Errorf("RoundTrip error = %T: %#v, want %T (%#v)", err, err, want, want) 2834 } 2835 return nil 2836 } 2837 ct.server = func() error { 2838 ct.greet() 2839 for { 2840 f, err := ct.fr.ReadFrame() 2841 if err != nil { 2842 t.Logf("ReadFrame: %v", err) 2843 return nil 2844 } 2845 hf, ok := f.(*HeadersFrame) 2846 if !ok { 2847 continue 2848 } 2849 if failMidBody { 2850 var buf bytes.Buffer 2851 enc := hpack.NewEncoder(&buf) 2852 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 2853 enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "123"}) 2854 ct.fr.WriteHeaders(HeadersFrameParam{ 2855 StreamID: hf.StreamID, 2856 EndHeaders: true, 2857 EndStream: false, 2858 BlockFragment: buf.Bytes(), 2859 }) 2860 } 2861 // Write two GOAWAY frames, to test that the Transport takes 2862 // the interesting parts of both. 2863 ct.fr.WriteGoAway(5, ErrCodeNo, []byte(goAwayDebugData)) 2864 ct.fr.WriteGoAway(5, goAwayErrCode, nil) 2865 ct.sc.(*net.TCPConn).CloseWrite() 2866 if runtime.GOOS == "plan9" { 2867 // CloseWrite not supported on Plan 9; Issue 17906 2868 ct.sc.(*net.TCPConn).Close() 2869 } 2870 <-clientDone 2871 return nil 2872 } 2873 } 2874 ct.run() 2875 } 2876 2877 func testTransportReturnsUnusedFlowControl(t *testing.T, oneDataFrame bool) { 2878 ct := newClientTester(t) 2879 2880 clientClosed := make(chan struct{}) 2881 serverWroteFirstByte := make(chan struct{}) 2882 2883 ct.client = func() error { 2884 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 2885 res, err := ct.tr.RoundTrip(req) 2886 if err != nil { 2887 return err 2888 } 2889 <-serverWroteFirstByte 2890 2891 if n, err := res.Body.Read(make([]byte, 1)); err != nil || n != 1 { 2892 return fmt.Errorf("body read = %v, %v; want 1, nil", n, err) 2893 } 2894 res.Body.Close() // leaving 4999 bytes unread 2895 close(clientClosed) 2896 2897 return nil 2898 } 2899 ct.server = func() error { 2900 ct.greet() 2901 2902 var hf *HeadersFrame 2903 for { 2904 f, err := ct.fr.ReadFrame() 2905 if err != nil { 2906 return fmt.Errorf("ReadFrame while waiting for Headers: %v", err) 2907 } 2908 switch f.(type) { 2909 case *WindowUpdateFrame, *SettingsFrame: 2910 continue 2911 } 2912 var ok bool 2913 hf, ok = f.(*HeadersFrame) 2914 if !ok { 2915 return fmt.Errorf("Got %T; want HeadersFrame", f) 2916 } 2917 break 2918 } 2919 2920 var buf bytes.Buffer 2921 enc := hpack.NewEncoder(&buf) 2922 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 2923 enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "5000"}) 2924 ct.fr.WriteHeaders(HeadersFrameParam{ 2925 StreamID: hf.StreamID, 2926 EndHeaders: true, 2927 EndStream: false, 2928 BlockFragment: buf.Bytes(), 2929 }) 2930 2931 // Two cases: 2932 // - Send one DATA frame with 5000 bytes. 2933 // - Send two DATA frames with 1 and 4999 bytes each. 2934 // 2935 // In both cases, the client should consume one byte of data, 2936 // refund that byte, then refund the following 4999 bytes. 2937 // 2938 // In the second case, the server waits for the client connection to 2939 // close before seconding the second DATA frame. This tests the case 2940 // where the client receives a DATA frame after it has reset the stream. 2941 if oneDataFrame { 2942 ct.fr.WriteData(hf.StreamID, false /* don't end stream */, make([]byte, 5000)) 2943 close(serverWroteFirstByte) 2944 <-clientClosed 2945 } else { 2946 ct.fr.WriteData(hf.StreamID, false /* don't end stream */, make([]byte, 1)) 2947 close(serverWroteFirstByte) 2948 <-clientClosed 2949 ct.fr.WriteData(hf.StreamID, false /* don't end stream */, make([]byte, 4999)) 2950 } 2951 2952 waitingFor := "RSTStreamFrame" 2953 sawRST := false 2954 sawWUF := false 2955 for !sawRST && !sawWUF { 2956 f, err := ct.fr.ReadFrame() 2957 if err != nil { 2958 return fmt.Errorf("ReadFrame while waiting for %s: %v", waitingFor, err) 2959 } 2960 switch f := f.(type) { 2961 case *SettingsFrame: 2962 case *RSTStreamFrame: 2963 if sawRST { 2964 return fmt.Errorf("saw second RSTStreamFrame: %v", summarizeFrame(f)) 2965 } 2966 if f.ErrCode != ErrCodeCancel { 2967 return fmt.Errorf("Expected a RSTStreamFrame with code cancel; got %v", summarizeFrame(f)) 2968 } 2969 sawRST = true 2970 case *WindowUpdateFrame: 2971 if sawWUF { 2972 return fmt.Errorf("saw second WindowUpdateFrame: %v", summarizeFrame(f)) 2973 } 2974 if f.Increment != 4999 { 2975 return fmt.Errorf("Expected WindowUpdateFrames for 5000 bytes; got %v", summarizeFrame(f)) 2976 } 2977 sawWUF = true 2978 default: 2979 return fmt.Errorf("Unexpected frame: %v", summarizeFrame(f)) 2980 } 2981 } 2982 return nil 2983 } 2984 ct.run() 2985 } 2986 2987 // See golang.org/issue/16481 2988 func TestTransportReturnsUnusedFlowControlSingleWrite(t *testing.T) { 2989 testTransportReturnsUnusedFlowControl(t, true) 2990 } 2991 2992 // See golang.org/issue/20469 2993 func TestTransportReturnsUnusedFlowControlMultipleWrites(t *testing.T) { 2994 testTransportReturnsUnusedFlowControl(t, false) 2995 } 2996 2997 // Issue 16612: adjust flow control on open streams when transport 2998 // receives SETTINGS with INITIAL_WINDOW_SIZE from server. 2999 func TestTransportAdjustsFlowControl(t *testing.T) { 3000 ct := newClientTester(t) 3001 clientDone := make(chan struct{}) 3002 3003 const bodySize = 1 << 20 3004 3005 ct.client = func() error { 3006 defer ct.cc.(*net.TCPConn).CloseWrite() 3007 if runtime.GOOS == "plan9" { 3008 // CloseWrite not supported on Plan 9; Issue 17906 3009 defer ct.cc.(*net.TCPConn).Close() 3010 } 3011 defer close(clientDone) 3012 3013 req, _ := http.NewRequest("POST", "https://dummy.tld/", struct{ io.Reader }{io.LimitReader(neverEnding('A'), bodySize)}) 3014 res, err := ct.tr.RoundTrip(req) 3015 if err != nil { 3016 return err 3017 } 3018 res.Body.Close() 3019 return nil 3020 } 3021 ct.server = func() error { 3022 _, err := io.ReadFull(ct.sc, make([]byte, len(ClientPreface))) 3023 if err != nil { 3024 return fmt.Errorf("reading client preface: %v", err) 3025 } 3026 3027 var gotBytes int64 3028 var sentSettings bool 3029 for { 3030 f, err := ct.fr.ReadFrame() 3031 if err != nil { 3032 select { 3033 case <-clientDone: 3034 return nil 3035 default: 3036 return fmt.Errorf("ReadFrame while waiting for Headers: %v", err) 3037 } 3038 } 3039 switch f := f.(type) { 3040 case *DataFrame: 3041 gotBytes += int64(len(f.Data())) 3042 // After we've got half the client's 3043 // initial flow control window's worth 3044 // of request body data, give it just 3045 // enough flow control to finish. 3046 if gotBytes >= initialWindowSize/2 && !sentSettings { 3047 sentSettings = true 3048 3049 ct.fr.WriteSettings(Setting{ID: SettingInitialWindowSize, Val: bodySize}) 3050 ct.fr.WriteWindowUpdate(0, bodySize) 3051 ct.fr.WriteSettingsAck() 3052 } 3053 3054 if f.StreamEnded() { 3055 var buf bytes.Buffer 3056 enc := hpack.NewEncoder(&buf) 3057 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 3058 ct.fr.WriteHeaders(HeadersFrameParam{ 3059 StreamID: f.StreamID, 3060 EndHeaders: true, 3061 EndStream: true, 3062 BlockFragment: buf.Bytes(), 3063 }) 3064 } 3065 } 3066 } 3067 } 3068 ct.run() 3069 } 3070 3071 // See golang.org/issue/16556 3072 func TestTransportReturnsDataPaddingFlowControl(t *testing.T) { 3073 ct := newClientTester(t) 3074 3075 unblockClient := make(chan bool, 1) 3076 3077 ct.client = func() error { 3078 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 3079 res, err := ct.tr.RoundTrip(req) 3080 if err != nil { 3081 return err 3082 } 3083 defer res.Body.Close() 3084 <-unblockClient 3085 return nil 3086 } 3087 ct.server = func() error { 3088 ct.greet() 3089 3090 var hf *HeadersFrame 3091 for { 3092 f, err := ct.fr.ReadFrame() 3093 if err != nil { 3094 return fmt.Errorf("ReadFrame while waiting for Headers: %v", err) 3095 } 3096 switch f.(type) { 3097 case *WindowUpdateFrame, *SettingsFrame: 3098 continue 3099 } 3100 var ok bool 3101 hf, ok = f.(*HeadersFrame) 3102 if !ok { 3103 return fmt.Errorf("Got %T; want HeadersFrame", f) 3104 } 3105 break 3106 } 3107 3108 var buf bytes.Buffer 3109 enc := hpack.NewEncoder(&buf) 3110 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 3111 enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "5000"}) 3112 ct.fr.WriteHeaders(HeadersFrameParam{ 3113 StreamID: hf.StreamID, 3114 EndHeaders: true, 3115 EndStream: false, 3116 BlockFragment: buf.Bytes(), 3117 }) 3118 pad := make([]byte, 5) 3119 ct.fr.WriteDataPadded(hf.StreamID, false, make([]byte, 5000), pad) // without ending stream 3120 3121 f, err := ct.readNonSettingsFrame() 3122 if err != nil { 3123 return fmt.Errorf("ReadFrame while waiting for first WindowUpdateFrame: %v", err) 3124 } 3125 wantBack := uint32(len(pad)) + 1 // one byte for the length of the padding 3126 if wuf, ok := f.(*WindowUpdateFrame); !ok || wuf.Increment != wantBack || wuf.StreamID != 0 { 3127 return fmt.Errorf("Expected conn WindowUpdateFrame for %d bytes; got %v", wantBack, summarizeFrame(f)) 3128 } 3129 3130 f, err = ct.readNonSettingsFrame() 3131 if err != nil { 3132 return fmt.Errorf("ReadFrame while waiting for second WindowUpdateFrame: %v", err) 3133 } 3134 if wuf, ok := f.(*WindowUpdateFrame); !ok || wuf.Increment != wantBack || wuf.StreamID == 0 { 3135 return fmt.Errorf("Expected stream WindowUpdateFrame for %d bytes; got %v", wantBack, summarizeFrame(f)) 3136 } 3137 unblockClient <- true 3138 return nil 3139 } 3140 ct.run() 3141 } 3142 3143 // golang.org/issue/16572 -- RoundTrip shouldn't hang when it gets a 3144 // StreamError as a result of the response HEADERS 3145 func TestTransportReturnsErrorOnBadResponseHeaders(t *testing.T) { 3146 ct := newClientTester(t) 3147 3148 ct.client = func() error { 3149 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 3150 res, err := ct.tr.RoundTrip(req) 3151 if err == nil { 3152 res.Body.Close() 3153 return errors.New("unexpected successful GET") 3154 } 3155 want := StreamError{1, ErrCodeProtocol, headerFieldNameError(" content-type")} 3156 if !reflect.DeepEqual(want, err) { 3157 t.Errorf("RoundTrip error = %#v; want %#v", err, want) 3158 } 3159 return nil 3160 } 3161 ct.server = func() error { 3162 ct.greet() 3163 3164 hf, err := ct.firstHeaders() 3165 if err != nil { 3166 return err 3167 } 3168 3169 var buf bytes.Buffer 3170 enc := hpack.NewEncoder(&buf) 3171 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 3172 enc.WriteField(hpack.HeaderField{Name: " content-type", Value: "bogus"}) // bogus spaces 3173 ct.fr.WriteHeaders(HeadersFrameParam{ 3174 StreamID: hf.StreamID, 3175 EndHeaders: true, 3176 EndStream: false, 3177 BlockFragment: buf.Bytes(), 3178 }) 3179 3180 for { 3181 fr, err := ct.readFrame() 3182 if err != nil { 3183 return fmt.Errorf("error waiting for RST_STREAM from client: %v", err) 3184 } 3185 if _, ok := fr.(*SettingsFrame); ok { 3186 continue 3187 } 3188 if rst, ok := fr.(*RSTStreamFrame); !ok || rst.StreamID != 1 || rst.ErrCode != ErrCodeProtocol { 3189 t.Errorf("Frame = %v; want RST_STREAM for stream 1 with ErrCodeProtocol", summarizeFrame(fr)) 3190 } 3191 break 3192 } 3193 3194 return nil 3195 } 3196 ct.run() 3197 } 3198 3199 // byteAndEOFReader returns is in an io.Reader which reads one byte 3200 // (the underlying byte) and io.EOF at once in its Read call. 3201 type byteAndEOFReader byte 3202 3203 func (b byteAndEOFReader) Read(p []byte) (n int, err error) { 3204 if len(p) == 0 { 3205 panic("unexpected useless call") 3206 } 3207 p[0] = byte(b) 3208 return 1, io.EOF 3209 } 3210 3211 // Issue 16788: the Transport had a regression where it started 3212 // sending a spurious DATA frame with a duplicate END_STREAM bit after 3213 // the request body writer goroutine had already read an EOF from the 3214 // Request.Body and included the END_STREAM on a data-carrying DATA 3215 // frame. 3216 // 3217 // Notably, to trigger this, the requests need to use a Request.Body 3218 // which returns (non-0, io.EOF) and also needs to set the ContentLength 3219 // explicitly. 3220 func TestTransportBodyDoubleEndStream(t *testing.T) { 3221 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3222 // Nothing. 3223 }, optOnlyServer) 3224 defer st.Close() 3225 3226 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3227 defer tr.CloseIdleConnections() 3228 3229 for i := 0; i < 2; i++ { 3230 req, _ := http.NewRequest("POST", st.ts.URL, byteAndEOFReader('a')) 3231 req.ContentLength = 1 3232 res, err := tr.RoundTrip(req) 3233 if err != nil { 3234 t.Fatalf("failure on req %d: %v", i+1, err) 3235 } 3236 defer res.Body.Close() 3237 } 3238 } 3239 3240 // golang.org/issue/16847, golang.org/issue/19103 3241 func TestTransportRequestPathPseudo(t *testing.T) { 3242 type result struct { 3243 path string 3244 err string 3245 } 3246 tests := []struct { 3247 req *http.Request 3248 want result 3249 }{ 3250 0: { 3251 req: &http.Request{ 3252 Method: "GET", 3253 URL: &url.URL{ 3254 Host: "foo.com", 3255 Path: "/foo", 3256 }, 3257 }, 3258 want: result{path: "/foo"}, 3259 }, 3260 // In Go 1.7, we accepted paths of "//foo". 3261 // In Go 1.8, we rejected it (issue 16847). 3262 // In Go 1.9, we accepted it again (issue 19103). 3263 1: { 3264 req: &http.Request{ 3265 Method: "GET", 3266 URL: &url.URL{ 3267 Host: "foo.com", 3268 Path: "//foo", 3269 }, 3270 }, 3271 want: result{path: "//foo"}, 3272 }, 3273 3274 // Opaque with //$Matching_Hostname/path 3275 2: { 3276 req: &http.Request{ 3277 Method: "GET", 3278 URL: &url.URL{ 3279 Scheme: "https", 3280 Opaque: "//foo.com/path", 3281 Host: "foo.com", 3282 Path: "/ignored", 3283 }, 3284 }, 3285 want: result{path: "/path"}, 3286 }, 3287 3288 // Opaque with some other Request.Host instead: 3289 3: { 3290 req: &http.Request{ 3291 Method: "GET", 3292 Host: "bar.com", 3293 URL: &url.URL{ 3294 Scheme: "https", 3295 Opaque: "//bar.com/path", 3296 Host: "foo.com", 3297 Path: "/ignored", 3298 }, 3299 }, 3300 want: result{path: "/path"}, 3301 }, 3302 3303 // Opaque without the leading "//": 3304 4: { 3305 req: &http.Request{ 3306 Method: "GET", 3307 URL: &url.URL{ 3308 Opaque: "/path", 3309 Host: "foo.com", 3310 Path: "/ignored", 3311 }, 3312 }, 3313 want: result{path: "/path"}, 3314 }, 3315 3316 // Opaque we can't handle: 3317 5: { 3318 req: &http.Request{ 3319 Method: "GET", 3320 URL: &url.URL{ 3321 Scheme: "https", 3322 Opaque: "//unknown_host/path", 3323 Host: "foo.com", 3324 Path: "/ignored", 3325 }, 3326 }, 3327 want: result{err: `invalid request :path "https://unknown_host/path" from URL.Opaque = "//unknown_host/path"`}, 3328 }, 3329 3330 // A CONNECT request: 3331 6: { 3332 req: &http.Request{ 3333 Method: "CONNECT", 3334 URL: &url.URL{ 3335 Host: "foo.com", 3336 }, 3337 }, 3338 want: result{}, 3339 }, 3340 } 3341 for i, tt := range tests { 3342 cc := &ClientConn{peerMaxHeaderListSize: 0xffffffffffffffff} 3343 cc.henc = hpack.NewEncoder(&cc.hbuf) 3344 cc.mu.Lock() 3345 hdrs, err := cc.encodeHeaders(tt.req, false, "", -1) 3346 cc.mu.Unlock() 3347 var got result 3348 hpackDec := hpack.NewDecoder(initialHeaderTableSize, func(f hpack.HeaderField) { 3349 if f.Name == ":path" { 3350 got.path = f.Value 3351 } 3352 }) 3353 if err != nil { 3354 got.err = err.Error() 3355 } else if len(hdrs) > 0 { 3356 if _, err := hpackDec.Write(hdrs); err != nil { 3357 t.Errorf("%d. bogus hpack: %v", i, err) 3358 continue 3359 } 3360 } 3361 if got != tt.want { 3362 t.Errorf("%d. got %+v; want %+v", i, got, tt.want) 3363 } 3364 3365 } 3366 3367 } 3368 3369 // golang.org/issue/17071 -- don't sniff the first byte of the request body 3370 // before we've determined that the ClientConn is usable. 3371 func TestRoundTripDoesntConsumeRequestBodyEarly(t *testing.T) { 3372 const body = "foo" 3373 req, _ := http.NewRequest("POST", "http://foo.com/", ioutil.NopCloser(strings.NewReader(body))) 3374 cc := &ClientConn{ 3375 closed: true, 3376 reqHeaderMu: make(chan struct{}, 1), 3377 } 3378 _, err := cc.RoundTrip(req) 3379 if err != errClientConnUnusable { 3380 t.Fatalf("RoundTrip = %v; want errClientConnUnusable", err) 3381 } 3382 slurp, err := ioutil.ReadAll(req.Body) 3383 if err != nil { 3384 t.Errorf("ReadAll = %v", err) 3385 } 3386 if string(slurp) != body { 3387 t.Errorf("Body = %q; want %q", slurp, body) 3388 } 3389 } 3390 3391 func TestClientConnPing(t *testing.T) { 3392 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}, optOnlyServer) 3393 defer st.Close() 3394 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3395 defer tr.CloseIdleConnections() 3396 ctx := context.Background() 3397 cc, err := tr.dialClientConn(ctx, st.ts.Listener.Addr().String(), false) 3398 if err != nil { 3399 t.Fatal(err) 3400 } 3401 if err = cc.Ping(context.Background()); err != nil { 3402 t.Fatal(err) 3403 } 3404 } 3405 3406 // Issue 16974: if the server sent a DATA frame after the user 3407 // canceled the Transport's Request, the Transport previously wrote to a 3408 // closed pipe, got an error, and ended up closing the whole TCP 3409 // connection. 3410 func TestTransportCancelDataResponseRace(t *testing.T) { 3411 cancel := make(chan struct{}) 3412 clientGotError := make(chan bool, 1) 3413 3414 const msg = "Hello." 3415 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3416 if strings.Contains(r.URL.Path, "/hello") { 3417 time.Sleep(50 * time.Millisecond) 3418 io.WriteString(w, msg) 3419 return 3420 } 3421 for i := 0; i < 50; i++ { 3422 io.WriteString(w, "Some data.") 3423 w.(http.Flusher).Flush() 3424 if i == 2 { 3425 close(cancel) 3426 <-clientGotError 3427 } 3428 time.Sleep(10 * time.Millisecond) 3429 } 3430 }, optOnlyServer) 3431 defer st.Close() 3432 3433 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3434 defer tr.CloseIdleConnections() 3435 3436 c := &http.Client{Transport: tr} 3437 req, _ := http.NewRequest("GET", st.ts.URL, nil) 3438 req.Cancel = cancel 3439 res, err := c.Do(req) 3440 if err != nil { 3441 t.Fatal(err) 3442 } 3443 if _, err = io.Copy(ioutil.Discard, res.Body); err == nil { 3444 t.Fatal("unexpected success") 3445 } 3446 clientGotError <- true 3447 3448 res, err = c.Get(st.ts.URL + "/hello") 3449 if err != nil { 3450 t.Fatal(err) 3451 } 3452 slurp, err := ioutil.ReadAll(res.Body) 3453 if err != nil { 3454 t.Fatal(err) 3455 } 3456 if string(slurp) != msg { 3457 t.Errorf("Got = %q; want %q", slurp, msg) 3458 } 3459 } 3460 3461 // Issue 21316: It should be safe to reuse an http.Request after the 3462 // request has completed. 3463 func TestTransportNoRaceOnRequestObjectAfterRequestComplete(t *testing.T) { 3464 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3465 w.WriteHeader(200) 3466 io.WriteString(w, "body") 3467 }, optOnlyServer) 3468 defer st.Close() 3469 3470 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3471 defer tr.CloseIdleConnections() 3472 3473 req, _ := http.NewRequest("GET", st.ts.URL, nil) 3474 resp, err := tr.RoundTrip(req) 3475 if err != nil { 3476 t.Fatal(err) 3477 } 3478 if _, err = io.Copy(ioutil.Discard, resp.Body); err != nil { 3479 t.Fatalf("error reading response body: %v", err) 3480 } 3481 if err := resp.Body.Close(); err != nil { 3482 t.Fatalf("error closing response body: %v", err) 3483 } 3484 3485 // This access of req.Header should not race with code in the transport. 3486 req.Header = http.Header{} 3487 } 3488 3489 func TestTransportCloseAfterLostPing(t *testing.T) { 3490 clientDone := make(chan struct{}) 3491 ct := newClientTester(t) 3492 ct.tr.PingTimeout = 1 * time.Second 3493 ct.tr.ReadIdleTimeout = 1 * time.Second 3494 ct.client = func() error { 3495 defer ct.cc.(*net.TCPConn).CloseWrite() 3496 defer close(clientDone) 3497 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 3498 _, err := ct.tr.RoundTrip(req) 3499 if err == nil || !strings.Contains(err.Error(), "client connection lost") { 3500 return fmt.Errorf("expected to get error about \"connection lost\", got %v", err) 3501 } 3502 return nil 3503 } 3504 ct.server = func() error { 3505 ct.greet() 3506 <-clientDone 3507 return nil 3508 } 3509 ct.run() 3510 } 3511 3512 func TestTransportPingWriteBlocks(t *testing.T) { 3513 st := newServerTester(t, 3514 func(w http.ResponseWriter, r *http.Request) {}, 3515 optOnlyServer, 3516 ) 3517 defer st.Close() 3518 tr := &Transport{ 3519 TLSClientConfig: tlsConfigInsecure, 3520 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 3521 s, c := net.Pipe() // unbuffered, unlike a TCP conn 3522 go func() { 3523 // Read initial handshake frames. 3524 // Without this, we block indefinitely in newClientConn, 3525 // and never get to the point of sending a PING. 3526 var buf [1024]byte 3527 s.Read(buf[:]) 3528 }() 3529 return c, nil 3530 }, 3531 PingTimeout: 1 * time.Millisecond, 3532 ReadIdleTimeout: 1 * time.Millisecond, 3533 } 3534 defer tr.CloseIdleConnections() 3535 c := &http.Client{Transport: tr} 3536 _, err := c.Get(st.ts.URL) 3537 if err == nil { 3538 t.Fatalf("Get = nil, want error") 3539 } 3540 } 3541 3542 func TestTransportPingWhenReading(t *testing.T) { 3543 testCases := []struct { 3544 name string 3545 readIdleTimeout time.Duration 3546 deadline time.Duration 3547 expectedPingCount int 3548 }{ 3549 { 3550 name: "two pings", 3551 readIdleTimeout: 100 * time.Millisecond, 3552 deadline: time.Second, 3553 expectedPingCount: 2, 3554 }, 3555 { 3556 name: "zero ping", 3557 readIdleTimeout: time.Second, 3558 deadline: 200 * time.Millisecond, 3559 expectedPingCount: 0, 3560 }, 3561 { 3562 name: "0 readIdleTimeout means no ping", 3563 readIdleTimeout: 0 * time.Millisecond, 3564 deadline: 500 * time.Millisecond, 3565 expectedPingCount: 0, 3566 }, 3567 } 3568 3569 for _, tc := range testCases { 3570 tc := tc // capture range variable 3571 t.Run(tc.name, func(t *testing.T) { 3572 testTransportPingWhenReading(t, tc.readIdleTimeout, tc.deadline, tc.expectedPingCount) 3573 }) 3574 } 3575 } 3576 3577 func testTransportPingWhenReading(t *testing.T, readIdleTimeout, deadline time.Duration, expectedPingCount int) { 3578 var pingCount int 3579 ct := newClientTester(t) 3580 ct.tr.ReadIdleTimeout = readIdleTimeout 3581 3582 ctx, cancel := context.WithTimeout(context.Background(), deadline) 3583 defer cancel() 3584 ct.client = func() error { 3585 defer ct.cc.(*net.TCPConn).CloseWrite() 3586 if runtime.GOOS == "plan9" { 3587 // CloseWrite not supported on Plan 9; Issue 17906 3588 defer ct.cc.(*net.TCPConn).Close() 3589 } 3590 req, _ := http.NewRequestWithContext(ctx, "GET", "https://dummy.tld/", nil) 3591 res, err := ct.tr.RoundTrip(req) 3592 if err != nil { 3593 return fmt.Errorf("RoundTrip: %v", err) 3594 } 3595 defer res.Body.Close() 3596 if res.StatusCode != 200 { 3597 return fmt.Errorf("status code = %v; want %v", res.StatusCode, 200) 3598 } 3599 _, err = ioutil.ReadAll(res.Body) 3600 if expectedPingCount == 0 && errors.Is(ctx.Err(), context.DeadlineExceeded) { 3601 return nil 3602 } 3603 3604 cancel() 3605 return err 3606 } 3607 3608 ct.server = func() error { 3609 ct.greet() 3610 var buf bytes.Buffer 3611 enc := hpack.NewEncoder(&buf) 3612 var streamID uint32 3613 for { 3614 f, err := ct.fr.ReadFrame() 3615 if err != nil { 3616 select { 3617 case <-ctx.Done(): 3618 // If the client's done, it 3619 // will have reported any 3620 // errors on its side. 3621 return nil 3622 default: 3623 return err 3624 } 3625 } 3626 switch f := f.(type) { 3627 case *WindowUpdateFrame, *SettingsFrame: 3628 case *HeadersFrame: 3629 if !f.HeadersEnded() { 3630 return fmt.Errorf("headers should have END_HEADERS be ended: %v", f) 3631 } 3632 enc.WriteField(hpack.HeaderField{Name: ":status", Value: strconv.Itoa(200)}) 3633 ct.fr.WriteHeaders(HeadersFrameParam{ 3634 StreamID: f.StreamID, 3635 EndHeaders: true, 3636 EndStream: false, 3637 BlockFragment: buf.Bytes(), 3638 }) 3639 streamID = f.StreamID 3640 case *PingFrame: 3641 pingCount++ 3642 if pingCount == expectedPingCount { 3643 if err := ct.fr.WriteData(streamID, true, []byte("hello, this is last server data frame")); err != nil { 3644 return err 3645 } 3646 } 3647 if err := ct.fr.WritePing(true, f.Data); err != nil { 3648 return err 3649 } 3650 case *RSTStreamFrame: 3651 default: 3652 return fmt.Errorf("Unexpected client frame %v", f) 3653 } 3654 } 3655 } 3656 ct.run() 3657 } 3658 3659 func TestTransportRetryAfterGOAWAY(t *testing.T) { 3660 var dialer struct { 3661 sync.Mutex 3662 count int 3663 } 3664 ct1 := make(chan *clientTester) 3665 ct2 := make(chan *clientTester) 3666 3667 ln := newLocalListener(t) 3668 defer ln.Close() 3669 3670 tr := &Transport{ 3671 TLSClientConfig: tlsConfigInsecure, 3672 } 3673 tr.DialTLS = func(network, addr string, cfg *tls.Config) (net.Conn, error) { 3674 dialer.Lock() 3675 defer dialer.Unlock() 3676 dialer.count++ 3677 if dialer.count == 3 { 3678 return nil, errors.New("unexpected number of dials") 3679 } 3680 cc, err := net.Dial("tcp", ln.Addr().String()) 3681 if err != nil { 3682 return nil, fmt.Errorf("dial error: %v", err) 3683 } 3684 sc, err := ln.Accept() 3685 if err != nil { 3686 return nil, fmt.Errorf("accept error: %v", err) 3687 } 3688 ct := &clientTester{ 3689 t: t, 3690 tr: tr, 3691 cc: cc, 3692 sc: sc, 3693 fr: NewFramer(sc, sc), 3694 } 3695 switch dialer.count { 3696 case 1: 3697 ct1 <- ct 3698 case 2: 3699 ct2 <- ct 3700 } 3701 return cc, nil 3702 } 3703 3704 errs := make(chan error, 3) 3705 3706 // Client. 3707 go func() { 3708 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 3709 res, err := tr.RoundTrip(req) 3710 if res != nil { 3711 res.Body.Close() 3712 if got := res.Header.Get("Foo"); got != "bar" { 3713 err = fmt.Errorf("foo header = %q; want bar", got) 3714 } 3715 } 3716 if err != nil { 3717 err = fmt.Errorf("RoundTrip: %v", err) 3718 } 3719 errs <- err 3720 }() 3721 3722 connToClose := make(chan io.Closer, 2) 3723 3724 // Server for the first request. 3725 go func() { 3726 ct := <-ct1 3727 3728 connToClose <- ct.cc 3729 ct.greet() 3730 hf, err := ct.firstHeaders() 3731 if err != nil { 3732 errs <- fmt.Errorf("server1 failed reading HEADERS: %v", err) 3733 return 3734 } 3735 t.Logf("server1 got %v", hf) 3736 if err := ct.fr.WriteGoAway(0 /*max id*/, ErrCodeNo, nil); err != nil { 3737 errs <- fmt.Errorf("server1 failed writing GOAWAY: %v", err) 3738 return 3739 } 3740 errs <- nil 3741 }() 3742 3743 // Server for the second request. 3744 go func() { 3745 ct := <-ct2 3746 3747 connToClose <- ct.cc 3748 ct.greet() 3749 hf, err := ct.firstHeaders() 3750 if err != nil { 3751 errs <- fmt.Errorf("server2 failed reading HEADERS: %v", err) 3752 return 3753 } 3754 t.Logf("server2 got %v", hf) 3755 3756 var buf bytes.Buffer 3757 enc := hpack.NewEncoder(&buf) 3758 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 3759 enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"}) 3760 err = ct.fr.WriteHeaders(HeadersFrameParam{ 3761 StreamID: hf.StreamID, 3762 EndHeaders: true, 3763 EndStream: false, 3764 BlockFragment: buf.Bytes(), 3765 }) 3766 if err != nil { 3767 errs <- fmt.Errorf("server2 failed writing response HEADERS: %v", err) 3768 } else { 3769 errs <- nil 3770 } 3771 }() 3772 3773 for k := 0; k < 3; k++ { 3774 err := <-errs 3775 if err != nil { 3776 t.Error(err) 3777 } 3778 } 3779 3780 close(connToClose) 3781 for c := range connToClose { 3782 c.Close() 3783 } 3784 } 3785 3786 func TestTransportRetryAfterRefusedStream(t *testing.T) { 3787 clientDone := make(chan struct{}) 3788 ct := newClientTester(t) 3789 ct.client = func() error { 3790 defer ct.cc.(*net.TCPConn).CloseWrite() 3791 if runtime.GOOS == "plan9" { 3792 // CloseWrite not supported on Plan 9; Issue 17906 3793 defer ct.cc.(*net.TCPConn).Close() 3794 } 3795 defer close(clientDone) 3796 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 3797 resp, err := ct.tr.RoundTrip(req) 3798 if err != nil { 3799 return fmt.Errorf("RoundTrip: %v", err) 3800 } 3801 resp.Body.Close() 3802 if resp.StatusCode != 204 { 3803 return fmt.Errorf("Status = %v; want 204", resp.StatusCode) 3804 } 3805 return nil 3806 } 3807 ct.server = func() error { 3808 ct.greet() 3809 var buf bytes.Buffer 3810 enc := hpack.NewEncoder(&buf) 3811 nreq := 0 3812 3813 for { 3814 f, err := ct.fr.ReadFrame() 3815 if err != nil { 3816 select { 3817 case <-clientDone: 3818 // If the client's done, it 3819 // will have reported any 3820 // errors on its side. 3821 return nil 3822 default: 3823 return err 3824 } 3825 } 3826 switch f := f.(type) { 3827 case *WindowUpdateFrame, *SettingsFrame: 3828 case *HeadersFrame: 3829 if !f.HeadersEnded() { 3830 return fmt.Errorf("headers should have END_HEADERS be ended: %v", f) 3831 } 3832 nreq++ 3833 if nreq == 1 { 3834 ct.fr.WriteRSTStream(f.StreamID, ErrCodeRefusedStream) 3835 } else { 3836 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "204"}) 3837 ct.fr.WriteHeaders(HeadersFrameParam{ 3838 StreamID: f.StreamID, 3839 EndHeaders: true, 3840 EndStream: true, 3841 BlockFragment: buf.Bytes(), 3842 }) 3843 } 3844 default: 3845 return fmt.Errorf("Unexpected client frame %v", f) 3846 } 3847 } 3848 } 3849 ct.run() 3850 } 3851 3852 func TestTransportRetryHasLimit(t *testing.T) { 3853 // Skip in short mode because the total expected delay is 1s+2s+4s+8s+16s=29s. 3854 if testing.Short() { 3855 t.Skip("skipping long test in short mode") 3856 } 3857 clientDone := make(chan struct{}) 3858 ct := newClientTester(t) 3859 ct.client = func() error { 3860 defer ct.cc.(*net.TCPConn).CloseWrite() 3861 if runtime.GOOS == "plan9" { 3862 // CloseWrite not supported on Plan 9; Issue 17906 3863 defer ct.cc.(*net.TCPConn).Close() 3864 } 3865 defer close(clientDone) 3866 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 3867 resp, err := ct.tr.RoundTrip(req) 3868 if err == nil { 3869 return fmt.Errorf("RoundTrip expected error, got response: %+v", resp) 3870 } 3871 t.Logf("expected error, got: %v", err) 3872 return nil 3873 } 3874 ct.server = func() error { 3875 ct.greet() 3876 for { 3877 f, err := ct.fr.ReadFrame() 3878 if err != nil { 3879 select { 3880 case <-clientDone: 3881 // If the client's done, it 3882 // will have reported any 3883 // errors on its side. 3884 return nil 3885 default: 3886 return err 3887 } 3888 } 3889 switch f := f.(type) { 3890 case *WindowUpdateFrame, *SettingsFrame: 3891 case *HeadersFrame: 3892 if !f.HeadersEnded() { 3893 return fmt.Errorf("headers should have END_HEADERS be ended: %v", f) 3894 } 3895 ct.fr.WriteRSTStream(f.StreamID, ErrCodeRefusedStream) 3896 default: 3897 return fmt.Errorf("Unexpected client frame %v", f) 3898 } 3899 } 3900 } 3901 ct.run() 3902 } 3903 3904 func TestTransportResponseDataBeforeHeaders(t *testing.T) { 3905 // This test use not valid response format. 3906 // Discarding logger output to not spam tests output. 3907 log.SetOutput(ioutil.Discard) 3908 defer log.SetOutput(os.Stderr) 3909 3910 ct := newClientTester(t) 3911 ct.client = func() error { 3912 defer ct.cc.(*net.TCPConn).CloseWrite() 3913 if runtime.GOOS == "plan9" { 3914 // CloseWrite not supported on Plan 9; Issue 17906 3915 defer ct.cc.(*net.TCPConn).Close() 3916 } 3917 req := httptest.NewRequest("GET", "https://dummy.tld/", nil) 3918 // First request is normal to ensure the check is per stream and not per connection. 3919 _, err := ct.tr.RoundTrip(req) 3920 if err != nil { 3921 return fmt.Errorf("RoundTrip expected no error, got: %v", err) 3922 } 3923 // Second request returns a DATA frame with no HEADERS. 3924 resp, err := ct.tr.RoundTrip(req) 3925 if err == nil { 3926 return fmt.Errorf("RoundTrip expected error, got response: %+v", resp) 3927 } 3928 if err, ok := err.(StreamError); !ok || err.Code != ErrCodeProtocol { 3929 return fmt.Errorf("expected stream PROTOCOL_ERROR, got: %v", err) 3930 } 3931 return nil 3932 } 3933 ct.server = func() error { 3934 ct.greet() 3935 for { 3936 f, err := ct.fr.ReadFrame() 3937 if err == io.EOF { 3938 return nil 3939 } else if err != nil { 3940 return err 3941 } 3942 switch f := f.(type) { 3943 case *WindowUpdateFrame, *SettingsFrame, *RSTStreamFrame: 3944 case *HeadersFrame: 3945 switch f.StreamID { 3946 case 1: 3947 // Send a valid response to first request. 3948 var buf bytes.Buffer 3949 enc := hpack.NewEncoder(&buf) 3950 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 3951 ct.fr.WriteHeaders(HeadersFrameParam{ 3952 StreamID: f.StreamID, 3953 EndHeaders: true, 3954 EndStream: true, 3955 BlockFragment: buf.Bytes(), 3956 }) 3957 case 3: 3958 ct.fr.WriteData(f.StreamID, true, []byte("payload")) 3959 } 3960 default: 3961 return fmt.Errorf("Unexpected client frame %v", f) 3962 } 3963 } 3964 } 3965 ct.run() 3966 } 3967 3968 func TestTransportRequestsLowServerLimit(t *testing.T) { 3969 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3970 }, optOnlyServer, func(s *Server) { 3971 s.MaxConcurrentStreams = 1 3972 }) 3973 defer st.Close() 3974 3975 var ( 3976 connCountMu sync.Mutex 3977 connCount int 3978 ) 3979 tr := &Transport{ 3980 TLSClientConfig: tlsConfigInsecure, 3981 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 3982 connCountMu.Lock() 3983 defer connCountMu.Unlock() 3984 connCount++ 3985 return tls.Dial(network, addr, cfg) 3986 }, 3987 } 3988 defer tr.CloseIdleConnections() 3989 3990 const reqCount = 3 3991 for i := 0; i < reqCount; i++ { 3992 req, err := http.NewRequest("GET", st.ts.URL, nil) 3993 if err != nil { 3994 t.Fatal(err) 3995 } 3996 res, err := tr.RoundTrip(req) 3997 if err != nil { 3998 t.Fatal(err) 3999 } 4000 if got, want := res.StatusCode, 200; got != want { 4001 t.Errorf("StatusCode = %v; want %v", got, want) 4002 } 4003 if res != nil && res.Body != nil { 4004 res.Body.Close() 4005 } 4006 } 4007 4008 if connCount != 1 { 4009 t.Errorf("created %v connections for %v requests, want 1", connCount, reqCount) 4010 } 4011 } 4012 4013 // tests Transport.StrictMaxConcurrentStreams 4014 func TestTransportRequestsStallAtServerLimit(t *testing.T) { 4015 const maxConcurrent = 2 4016 4017 greet := make(chan struct{}) // server sends initial SETTINGS frame 4018 gotRequest := make(chan struct{}) // server received a request 4019 clientDone := make(chan struct{}) 4020 4021 // Collect errors from goroutines. 4022 var wg sync.WaitGroup 4023 errs := make(chan error, 100) 4024 defer func() { 4025 wg.Wait() 4026 close(errs) 4027 for err := range errs { 4028 t.Error(err) 4029 } 4030 }() 4031 4032 // We will send maxConcurrent+2 requests. This checker goroutine waits for the 4033 // following stages: 4034 // 1. The first maxConcurrent requests are received by the server. 4035 // 2. The client will cancel the next request 4036 // 3. The server is unblocked so it can service the first maxConcurrent requests 4037 // 4. The client will send the final request 4038 wg.Add(1) 4039 unblockClient := make(chan struct{}) 4040 clientRequestCancelled := make(chan struct{}) 4041 unblockServer := make(chan struct{}) 4042 go func() { 4043 defer wg.Done() 4044 // Stage 1. 4045 for k := 0; k < maxConcurrent; k++ { 4046 <-gotRequest 4047 } 4048 // Stage 2. 4049 close(unblockClient) 4050 <-clientRequestCancelled 4051 // Stage 3: give some time for the final RoundTrip call to be scheduled and 4052 // verify that the final request is not sent. 4053 time.Sleep(50 * time.Millisecond) 4054 select { 4055 case <-gotRequest: 4056 errs <- errors.New("last request did not stall") 4057 close(unblockServer) 4058 return 4059 default: 4060 } 4061 close(unblockServer) 4062 // Stage 4. 4063 <-gotRequest 4064 }() 4065 4066 ct := newClientTester(t) 4067 ct.tr.StrictMaxConcurrentStreams = true 4068 ct.client = func() error { 4069 var wg sync.WaitGroup 4070 defer func() { 4071 wg.Wait() 4072 close(clientDone) 4073 ct.cc.(*net.TCPConn).CloseWrite() 4074 if runtime.GOOS == "plan9" { 4075 // CloseWrite not supported on Plan 9; Issue 17906 4076 ct.cc.(*net.TCPConn).Close() 4077 } 4078 }() 4079 for k := 0; k < maxConcurrent+2; k++ { 4080 wg.Add(1) 4081 go func(k int) { 4082 defer wg.Done() 4083 // Don't send the second request until after receiving SETTINGS from the server 4084 // to avoid a race where we use the default SettingMaxConcurrentStreams, which 4085 // is much larger than maxConcurrent. We have to send the first request before 4086 // waiting because the first request triggers the dial and greet. 4087 if k > 0 { 4088 <-greet 4089 } 4090 // Block until maxConcurrent requests are sent before sending any more. 4091 if k >= maxConcurrent { 4092 <-unblockClient 4093 } 4094 body := newStaticCloseChecker("") 4095 req, _ := http.NewRequest("GET", fmt.Sprintf("https://dummy.tld/%d", k), body) 4096 if k == maxConcurrent { 4097 // This request will be canceled. 4098 cancel := make(chan struct{}) 4099 req.Cancel = cancel 4100 close(cancel) 4101 _, err := ct.tr.RoundTrip(req) 4102 close(clientRequestCancelled) 4103 if err == nil { 4104 errs <- fmt.Errorf("RoundTrip(%d) should have failed due to cancel", k) 4105 return 4106 } 4107 } else { 4108 resp, err := ct.tr.RoundTrip(req) 4109 if err != nil { 4110 errs <- fmt.Errorf("RoundTrip(%d): %v", k, err) 4111 return 4112 } 4113 ioutil.ReadAll(resp.Body) 4114 resp.Body.Close() 4115 if resp.StatusCode != 204 { 4116 errs <- fmt.Errorf("Status = %v; want 204", resp.StatusCode) 4117 return 4118 } 4119 } 4120 if err := body.isClosed(); err != nil { 4121 errs <- fmt.Errorf("RoundTrip(%d): %v", k, err) 4122 } 4123 }(k) 4124 } 4125 return nil 4126 } 4127 4128 ct.server = func() error { 4129 var wg sync.WaitGroup 4130 defer wg.Wait() 4131 4132 ct.greet(Setting{SettingMaxConcurrentStreams, maxConcurrent}) 4133 4134 // Server write loop. 4135 var buf bytes.Buffer 4136 enc := hpack.NewEncoder(&buf) 4137 writeResp := make(chan uint32, maxConcurrent+1) 4138 4139 wg.Add(1) 4140 go func() { 4141 defer wg.Done() 4142 <-unblockServer 4143 for id := range writeResp { 4144 buf.Reset() 4145 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "204"}) 4146 ct.fr.WriteHeaders(HeadersFrameParam{ 4147 StreamID: id, 4148 EndHeaders: true, 4149 EndStream: true, 4150 BlockFragment: buf.Bytes(), 4151 }) 4152 } 4153 }() 4154 4155 // Server read loop. 4156 var nreq int 4157 for { 4158 f, err := ct.fr.ReadFrame() 4159 if err != nil { 4160 select { 4161 case <-clientDone: 4162 // If the client's done, it will have reported any errors on its side. 4163 return nil 4164 default: 4165 return err 4166 } 4167 } 4168 switch f := f.(type) { 4169 case *WindowUpdateFrame: 4170 case *SettingsFrame: 4171 // Wait for the client SETTINGS ack until ending the greet. 4172 close(greet) 4173 case *HeadersFrame: 4174 if !f.HeadersEnded() { 4175 return fmt.Errorf("headers should have END_HEADERS be ended: %v", f) 4176 } 4177 gotRequest <- struct{}{} 4178 nreq++ 4179 writeResp <- f.StreamID 4180 if nreq == maxConcurrent+1 { 4181 close(writeResp) 4182 } 4183 case *DataFrame: 4184 default: 4185 return fmt.Errorf("Unexpected client frame %v", f) 4186 } 4187 } 4188 } 4189 4190 ct.run() 4191 } 4192 4193 func TestAuthorityAddr(t *testing.T) { 4194 tests := []struct { 4195 scheme, authority string 4196 want string 4197 }{ 4198 {"http", "foo.com", "foo.com:80"}, 4199 {"https", "foo.com", "foo.com:443"}, 4200 {"https", "foo.com:1234", "foo.com:1234"}, 4201 {"https", "1.2.3.4:1234", "1.2.3.4:1234"}, 4202 {"https", "1.2.3.4", "1.2.3.4:443"}, 4203 {"https", "[::1]:1234", "[::1]:1234"}, 4204 {"https", "[::1]", "[::1]:443"}, 4205 } 4206 for _, tt := range tests { 4207 got := authorityAddr(tt.scheme, tt.authority) 4208 if got != tt.want { 4209 t.Errorf("authorityAddr(%q, %q) = %q; want %q", tt.scheme, tt.authority, got, tt.want) 4210 } 4211 } 4212 } 4213 4214 // Issue 20448: stop allocating for DATA frames' payload after 4215 // Response.Body.Close is called. 4216 func TestTransportAllocationsAfterResponseBodyClose(t *testing.T) { 4217 megabyteZero := make([]byte, 1<<20) 4218 4219 writeErr := make(chan error, 1) 4220 4221 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 4222 w.(http.Flusher).Flush() 4223 var sum int64 4224 for i := 0; i < 100; i++ { 4225 n, err := w.Write(megabyteZero) 4226 sum += int64(n) 4227 if err != nil { 4228 writeErr <- err 4229 return 4230 } 4231 } 4232 t.Logf("wrote all %d bytes", sum) 4233 writeErr <- nil 4234 }, optOnlyServer) 4235 defer st.Close() 4236 4237 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 4238 defer tr.CloseIdleConnections() 4239 c := &http.Client{Transport: tr} 4240 res, err := c.Get(st.ts.URL) 4241 if err != nil { 4242 t.Fatal(err) 4243 } 4244 var buf [1]byte 4245 if _, err := res.Body.Read(buf[:]); err != nil { 4246 t.Error(err) 4247 } 4248 if err := res.Body.Close(); err != nil { 4249 t.Error(err) 4250 } 4251 4252 trb, ok := res.Body.(transportResponseBody) 4253 if !ok { 4254 t.Fatalf("res.Body = %T; want transportResponseBody", res.Body) 4255 } 4256 if trb.cs.bufPipe.b != nil { 4257 t.Errorf("response body pipe is still open") 4258 } 4259 4260 gotErr := <-writeErr 4261 if gotErr == nil { 4262 t.Errorf("Handler unexpectedly managed to write its entire response without getting an error") 4263 } else if gotErr != errStreamClosed { 4264 t.Errorf("Handler Write err = %v; want errStreamClosed", gotErr) 4265 } 4266 } 4267 4268 // Issue 18891: make sure Request.Body == NoBody means no DATA frame 4269 // is ever sent, even if empty. 4270 func TestTransportNoBodyMeansNoDATA(t *testing.T) { 4271 ct := newClientTester(t) 4272 4273 unblockClient := make(chan bool) 4274 4275 ct.client = func() error { 4276 req, _ := http.NewRequest("GET", "https://dummy.tld/", http.NoBody) 4277 ct.tr.RoundTrip(req) 4278 <-unblockClient 4279 return nil 4280 } 4281 ct.server = func() error { 4282 defer close(unblockClient) 4283 defer ct.cc.(*net.TCPConn).Close() 4284 ct.greet() 4285 4286 for { 4287 f, err := ct.fr.ReadFrame() 4288 if err != nil { 4289 return fmt.Errorf("ReadFrame while waiting for Headers: %v", err) 4290 } 4291 switch f := f.(type) { 4292 default: 4293 return fmt.Errorf("Got %T; want HeadersFrame", f) 4294 case *WindowUpdateFrame, *SettingsFrame: 4295 continue 4296 case *HeadersFrame: 4297 if !f.StreamEnded() { 4298 return fmt.Errorf("got headers frame without END_STREAM") 4299 } 4300 return nil 4301 } 4302 } 4303 } 4304 ct.run() 4305 } 4306 4307 func benchSimpleRoundTrip(b *testing.B, nReqHeaders, nResHeader int) { 4308 defer disableGoroutineTracking()() 4309 b.ReportAllocs() 4310 st := newServerTester(b, 4311 func(w http.ResponseWriter, r *http.Request) { 4312 for i := 0; i < nResHeader; i++ { 4313 name := fmt.Sprint("A-", i) 4314 w.Header().Set(name, "*") 4315 } 4316 }, 4317 optOnlyServer, 4318 optQuiet, 4319 ) 4320 defer st.Close() 4321 4322 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 4323 defer tr.CloseIdleConnections() 4324 4325 req, err := http.NewRequest("GET", st.ts.URL, nil) 4326 if err != nil { 4327 b.Fatal(err) 4328 } 4329 4330 for i := 0; i < nReqHeaders; i++ { 4331 name := fmt.Sprint("A-", i) 4332 req.Header.Set(name, "*") 4333 } 4334 4335 b.ResetTimer() 4336 4337 for i := 0; i < b.N; i++ { 4338 res, err := tr.RoundTrip(req) 4339 if err != nil { 4340 if res != nil { 4341 res.Body.Close() 4342 } 4343 b.Fatalf("RoundTrip err = %v; want nil", err) 4344 } 4345 res.Body.Close() 4346 if res.StatusCode != http.StatusOK { 4347 b.Fatalf("Response code = %v; want %v", res.StatusCode, http.StatusOK) 4348 } 4349 } 4350 } 4351 4352 type infiniteReader struct{} 4353 4354 func (r infiniteReader) Read(b []byte) (int, error) { 4355 return len(b), nil 4356 } 4357 4358 // Issue 20521: it is not an error to receive a response and end stream 4359 // from the server without the body being consumed. 4360 func TestTransportResponseAndResetWithoutConsumingBodyRace(t *testing.T) { 4361 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 4362 w.WriteHeader(http.StatusOK) 4363 }, optOnlyServer) 4364 defer st.Close() 4365 4366 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 4367 defer tr.CloseIdleConnections() 4368 4369 // The request body needs to be big enough to trigger flow control. 4370 req, _ := http.NewRequest("PUT", st.ts.URL, infiniteReader{}) 4371 res, err := tr.RoundTrip(req) 4372 if err != nil { 4373 t.Fatal(err) 4374 } 4375 if res.StatusCode != http.StatusOK { 4376 t.Fatalf("Response code = %v; want %v", res.StatusCode, http.StatusOK) 4377 } 4378 } 4379 4380 // Verify transport doesn't crash when receiving bogus response lacking a :status header. 4381 // Issue 22880. 4382 func TestTransportHandlesInvalidStatuslessResponse(t *testing.T) { 4383 ct := newClientTester(t) 4384 ct.client = func() error { 4385 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 4386 _, err := ct.tr.RoundTrip(req) 4387 const substr = "malformed response from server: missing status pseudo header" 4388 if !strings.Contains(fmt.Sprint(err), substr) { 4389 return fmt.Errorf("RoundTrip error = %v; want substring %q", err, substr) 4390 } 4391 return nil 4392 } 4393 ct.server = func() error { 4394 ct.greet() 4395 var buf bytes.Buffer 4396 enc := hpack.NewEncoder(&buf) 4397 4398 for { 4399 f, err := ct.fr.ReadFrame() 4400 if err != nil { 4401 return err 4402 } 4403 switch f := f.(type) { 4404 case *HeadersFrame: 4405 enc.WriteField(hpack.HeaderField{Name: "content-type", Value: "text/html"}) // no :status header 4406 ct.fr.WriteHeaders(HeadersFrameParam{ 4407 StreamID: f.StreamID, 4408 EndHeaders: true, 4409 EndStream: false, // we'll send some DATA to try to crash the transport 4410 BlockFragment: buf.Bytes(), 4411 }) 4412 ct.fr.WriteData(f.StreamID, true, []byte("payload")) 4413 return nil 4414 } 4415 } 4416 } 4417 ct.run() 4418 } 4419 4420 func BenchmarkClientRequestHeaders(b *testing.B) { 4421 b.Run(" 0 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 0, 0) }) 4422 b.Run(" 10 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 10, 0) }) 4423 b.Run(" 100 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 100, 0) }) 4424 b.Run("1000 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 1000, 0) }) 4425 } 4426 4427 func BenchmarkClientResponseHeaders(b *testing.B) { 4428 b.Run(" 0 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 0, 0) }) 4429 b.Run(" 10 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 0, 10) }) 4430 b.Run(" 100 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 0, 100) }) 4431 b.Run("1000 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 0, 1000) }) 4432 } 4433 4434 func activeStreams(cc *ClientConn) int { 4435 count := 0 4436 cc.mu.Lock() 4437 defer cc.mu.Unlock() 4438 for _, cs := range cc.streams { 4439 select { 4440 case <-cs.abort: 4441 default: 4442 count++ 4443 } 4444 } 4445 return count 4446 } 4447 4448 type closeMode int 4449 4450 const ( 4451 closeAtHeaders closeMode = iota 4452 closeAtBody 4453 shutdown 4454 shutdownCancel 4455 ) 4456 4457 // See golang.org/issue/17292 4458 func testClientConnClose(t *testing.T, closeMode closeMode) { 4459 clientDone := make(chan struct{}) 4460 defer close(clientDone) 4461 handlerDone := make(chan struct{}) 4462 closeDone := make(chan struct{}) 4463 beforeHeader := func() {} 4464 bodyWrite := func(w http.ResponseWriter) {} 4465 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 4466 defer close(handlerDone) 4467 beforeHeader() 4468 w.WriteHeader(http.StatusOK) 4469 w.(http.Flusher).Flush() 4470 bodyWrite(w) 4471 select { 4472 case <-w.(http.CloseNotifier).CloseNotify(): 4473 // client closed connection before completion 4474 if closeMode == shutdown || closeMode == shutdownCancel { 4475 t.Error("expected request to complete") 4476 } 4477 case <-clientDone: 4478 if closeMode == closeAtHeaders || closeMode == closeAtBody { 4479 t.Error("expected connection closed by client") 4480 } 4481 } 4482 }, optOnlyServer) 4483 defer st.Close() 4484 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 4485 defer tr.CloseIdleConnections() 4486 ctx := context.Background() 4487 cc, err := tr.dialClientConn(ctx, st.ts.Listener.Addr().String(), false) 4488 req, err := http.NewRequest("GET", st.ts.URL, nil) 4489 if err != nil { 4490 t.Fatal(err) 4491 } 4492 if closeMode == closeAtHeaders { 4493 beforeHeader = func() { 4494 if err := cc.Close(); err != nil { 4495 t.Error(err) 4496 } 4497 close(closeDone) 4498 } 4499 } 4500 var sendBody chan struct{} 4501 if closeMode == closeAtBody { 4502 sendBody = make(chan struct{}) 4503 bodyWrite = func(w http.ResponseWriter) { 4504 <-sendBody 4505 b := make([]byte, 32) 4506 w.Write(b) 4507 w.(http.Flusher).Flush() 4508 if err := cc.Close(); err != nil { 4509 t.Errorf("unexpected ClientConn close error: %v", err) 4510 } 4511 close(closeDone) 4512 w.Write(b) 4513 w.(http.Flusher).Flush() 4514 } 4515 } 4516 res, err := cc.RoundTrip(req) 4517 if res != nil { 4518 defer res.Body.Close() 4519 } 4520 if closeMode == closeAtHeaders { 4521 got := fmt.Sprint(err) 4522 want := "http2: client connection force closed via ClientConn.Close" 4523 if got != want { 4524 t.Fatalf("RoundTrip error = %v, want %v", got, want) 4525 } 4526 } else { 4527 if err != nil { 4528 t.Fatalf("RoundTrip: %v", err) 4529 } 4530 if got, want := activeStreams(cc), 1; got != want { 4531 t.Errorf("got %d active streams, want %d", got, want) 4532 } 4533 } 4534 switch closeMode { 4535 case shutdownCancel: 4536 if err = cc.Shutdown(canceledCtx); err != context.Canceled { 4537 t.Errorf("got %v, want %v", err, context.Canceled) 4538 } 4539 if cc.closing == false { 4540 t.Error("expected closing to be true") 4541 } 4542 if cc.CanTakeNewRequest() == true { 4543 t.Error("CanTakeNewRequest to return false") 4544 } 4545 if v, want := len(cc.streams), 1; v != want { 4546 t.Errorf("expected %d active streams, got %d", want, v) 4547 } 4548 clientDone <- struct{}{} 4549 <-handlerDone 4550 case shutdown: 4551 wait := make(chan struct{}) 4552 shutdownEnterWaitStateHook = func() { 4553 close(wait) 4554 shutdownEnterWaitStateHook = func() {} 4555 } 4556 defer func() { shutdownEnterWaitStateHook = func() {} }() 4557 shutdown := make(chan struct{}, 1) 4558 go func() { 4559 if err = cc.Shutdown(context.Background()); err != nil { 4560 t.Error(err) 4561 } 4562 close(shutdown) 4563 }() 4564 // Let the shutdown to enter wait state 4565 <-wait 4566 cc.mu.Lock() 4567 if cc.closing == false { 4568 t.Error("expected closing to be true") 4569 } 4570 cc.mu.Unlock() 4571 if cc.CanTakeNewRequest() == true { 4572 t.Error("CanTakeNewRequest to return false") 4573 } 4574 if got, want := activeStreams(cc), 1; got != want { 4575 t.Errorf("got %d active streams, want %d", got, want) 4576 } 4577 // Let the active request finish 4578 clientDone <- struct{}{} 4579 // Wait for the shutdown to end 4580 select { 4581 case <-shutdown: 4582 case <-time.After(2 * time.Second): 4583 t.Fatal("expected server connection to close") 4584 } 4585 case closeAtHeaders, closeAtBody: 4586 if closeMode == closeAtBody { 4587 go close(sendBody) 4588 if _, err := io.Copy(ioutil.Discard, res.Body); err == nil { 4589 t.Error("expected a Copy error, got nil") 4590 } 4591 } 4592 <-closeDone 4593 if got, want := activeStreams(cc), 0; got != want { 4594 t.Errorf("got %d active streams, want %d", got, want) 4595 } 4596 // wait for server to get the connection close notice 4597 select { 4598 case <-handlerDone: 4599 case <-time.After(2 * time.Second): 4600 t.Fatal("expected server connection to close") 4601 } 4602 } 4603 } 4604 4605 // The client closes the connection just after the server got the client's HEADERS 4606 // frame, but before the server sends its HEADERS response back. The expected 4607 // result is an error on RoundTrip explaining the client closed the connection. 4608 func TestClientConnCloseAtHeaders(t *testing.T) { 4609 testClientConnClose(t, closeAtHeaders) 4610 } 4611 4612 // The client closes the connection between two server's response DATA frames. 4613 // The expected behavior is a response body io read error on the client. 4614 func TestClientConnCloseAtBody(t *testing.T) { 4615 testClientConnClose(t, closeAtBody) 4616 } 4617 4618 // The client sends a GOAWAY frame before the server finished processing a request. 4619 // We expect the connection not to close until the request is completed. 4620 func TestClientConnShutdown(t *testing.T) { 4621 testClientConnClose(t, shutdown) 4622 } 4623 4624 // The client sends a GOAWAY frame before the server finishes processing a request, 4625 // but cancels the passed context before the request is completed. The expected 4626 // behavior is the client closing the connection after the context is canceled. 4627 func TestClientConnShutdownCancel(t *testing.T) { 4628 testClientConnClose(t, shutdownCancel) 4629 } 4630 4631 // Issue 25009: use Request.GetBody if present, even if it seems like 4632 // we might not need it. Apparently something else can still read from 4633 // the original request body. Data race? In any case, rewinding 4634 // unconditionally on retry is a nicer model anyway and should 4635 // simplify code in the future (after the Go 1.11 freeze) 4636 func TestTransportUsesGetBodyWhenPresent(t *testing.T) { 4637 calls := 0 4638 someBody := func() io.ReadCloser { 4639 return struct{ io.ReadCloser }{ioutil.NopCloser(bytes.NewReader(nil))} 4640 } 4641 req := &http.Request{ 4642 Body: someBody(), 4643 GetBody: func() (io.ReadCloser, error) { 4644 calls++ 4645 return someBody(), nil 4646 }, 4647 } 4648 4649 req2, err := shouldRetryRequest(req, errClientConnUnusable) 4650 if err != nil { 4651 t.Fatal(err) 4652 } 4653 if calls != 1 { 4654 t.Errorf("Calls = %d; want 1", calls) 4655 } 4656 if req2 == req { 4657 t.Error("req2 changed") 4658 } 4659 if req2 == nil { 4660 t.Fatal("req2 is nil") 4661 } 4662 if req2.Body == nil { 4663 t.Fatal("req2.Body is nil") 4664 } 4665 if req2.GetBody == nil { 4666 t.Fatal("req2.GetBody is nil") 4667 } 4668 if req2.Body == req.Body { 4669 t.Error("req2.Body unchanged") 4670 } 4671 } 4672 4673 // Issue 22891: verify that the "https" altproto we register with net/http 4674 // is a certain type: a struct with one field with our *http2.Transport in it. 4675 func TestNoDialH2RoundTripperType(t *testing.T) { 4676 t1 := new(http.Transport) 4677 t2 := new(Transport) 4678 rt := noDialH2RoundTripper{t2} 4679 if err := registerHTTPSProtocol(t1, rt); err != nil { 4680 t.Fatal(err) 4681 } 4682 rv := reflect.ValueOf(rt) 4683 if rv.Type().Kind() != reflect.Struct { 4684 t.Fatalf("kind = %v; net/http expects struct", rv.Type().Kind()) 4685 } 4686 if n := rv.Type().NumField(); n != 1 { 4687 t.Fatalf("fields = %d; net/http expects 1", n) 4688 } 4689 v := rv.Field(0) 4690 if _, ok := v.Interface().(*Transport); !ok { 4691 t.Fatalf("wrong kind %T; want *Transport", v.Interface()) 4692 } 4693 } 4694 4695 type errReader struct { 4696 body []byte 4697 err error 4698 } 4699 4700 func (r *errReader) Read(p []byte) (int, error) { 4701 if len(r.body) > 0 { 4702 n := copy(p, r.body) 4703 r.body = r.body[n:] 4704 return n, nil 4705 } 4706 return 0, r.err 4707 } 4708 4709 func testTransportBodyReadError(t *testing.T, body []byte) { 4710 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { 4711 // So far we've only seen this be flaky on Windows and Plan 9, 4712 // perhaps due to TCP behavior on shutdowns while 4713 // unread data is in flight. This test should be 4714 // fixed, but a skip is better than annoying people 4715 // for now. 4716 t.Skipf("skipping flaky test on %s; https://golang.org/issue/31260", runtime.GOOS) 4717 } 4718 clientDone := make(chan struct{}) 4719 ct := newClientTester(t) 4720 ct.client = func() error { 4721 defer ct.cc.(*net.TCPConn).CloseWrite() 4722 if runtime.GOOS == "plan9" { 4723 // CloseWrite not supported on Plan 9; Issue 17906 4724 defer ct.cc.(*net.TCPConn).Close() 4725 } 4726 defer close(clientDone) 4727 4728 checkNoStreams := func() error { 4729 cp, ok := ct.tr.connPool().(*clientConnPool) 4730 if !ok { 4731 return fmt.Errorf("conn pool is %T; want *clientConnPool", ct.tr.connPool()) 4732 } 4733 cp.mu.Lock() 4734 defer cp.mu.Unlock() 4735 conns, ok := cp.conns["dummy.tld:443"] 4736 if !ok { 4737 return fmt.Errorf("missing connection") 4738 } 4739 if len(conns) != 1 { 4740 return fmt.Errorf("conn pool size: %v; expect 1", len(conns)) 4741 } 4742 if activeStreams(conns[0]) != 0 { 4743 return fmt.Errorf("active streams count: %v; want 0", activeStreams(conns[0])) 4744 } 4745 return nil 4746 } 4747 bodyReadError := errors.New("body read error") 4748 body := &errReader{body, bodyReadError} 4749 req, err := http.NewRequest("PUT", "https://dummy.tld/", body) 4750 if err != nil { 4751 return err 4752 } 4753 _, err = ct.tr.RoundTrip(req) 4754 if err != bodyReadError { 4755 return fmt.Errorf("err = %v; want %v", err, bodyReadError) 4756 } 4757 if err = checkNoStreams(); err != nil { 4758 return err 4759 } 4760 return nil 4761 } 4762 ct.server = func() error { 4763 ct.greet() 4764 var receivedBody []byte 4765 var resetCount int 4766 for { 4767 f, err := ct.fr.ReadFrame() 4768 t.Logf("server: ReadFrame = %v, %v", f, err) 4769 if err != nil { 4770 select { 4771 case <-clientDone: 4772 // If the client's done, it 4773 // will have reported any 4774 // errors on its side. 4775 if bytes.Compare(receivedBody, body) != 0 { 4776 return fmt.Errorf("body: %q; expected %q", receivedBody, body) 4777 } 4778 if resetCount != 1 { 4779 return fmt.Errorf("stream reset count: %v; expected: 1", resetCount) 4780 } 4781 return nil 4782 default: 4783 return err 4784 } 4785 } 4786 switch f := f.(type) { 4787 case *WindowUpdateFrame, *SettingsFrame: 4788 case *HeadersFrame: 4789 case *DataFrame: 4790 receivedBody = append(receivedBody, f.Data()...) 4791 case *RSTStreamFrame: 4792 resetCount++ 4793 default: 4794 return fmt.Errorf("Unexpected client frame %v", f) 4795 } 4796 } 4797 } 4798 ct.run() 4799 } 4800 4801 func TestTransportBodyReadError_Immediately(t *testing.T) { testTransportBodyReadError(t, nil) } 4802 func TestTransportBodyReadError_Some(t *testing.T) { testTransportBodyReadError(t, []byte("123")) } 4803 4804 // Issue 32254: verify that the client sends END_STREAM flag eagerly with the last 4805 // (or in this test-case the only one) request body data frame, and does not send 4806 // extra zero-len data frames. 4807 func TestTransportBodyEagerEndStream(t *testing.T) { 4808 const reqBody = "some request body" 4809 const resBody = "some response body" 4810 4811 ct := newClientTester(t) 4812 ct.client = func() error { 4813 defer ct.cc.(*net.TCPConn).CloseWrite() 4814 if runtime.GOOS == "plan9" { 4815 // CloseWrite not supported on Plan 9; Issue 17906 4816 defer ct.cc.(*net.TCPConn).Close() 4817 } 4818 body := strings.NewReader(reqBody) 4819 req, err := http.NewRequest("PUT", "https://dummy.tld/", body) 4820 if err != nil { 4821 return err 4822 } 4823 _, err = ct.tr.RoundTrip(req) 4824 if err != nil { 4825 return err 4826 } 4827 return nil 4828 } 4829 ct.server = func() error { 4830 ct.greet() 4831 4832 for { 4833 f, err := ct.fr.ReadFrame() 4834 if err != nil { 4835 return err 4836 } 4837 4838 switch f := f.(type) { 4839 case *WindowUpdateFrame, *SettingsFrame: 4840 case *HeadersFrame: 4841 case *DataFrame: 4842 if !f.StreamEnded() { 4843 ct.fr.WriteRSTStream(f.StreamID, ErrCodeRefusedStream) 4844 return fmt.Errorf("data frame without END_STREAM %v", f) 4845 } 4846 var buf bytes.Buffer 4847 enc := hpack.NewEncoder(&buf) 4848 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 4849 ct.fr.WriteHeaders(HeadersFrameParam{ 4850 StreamID: f.Header().StreamID, 4851 EndHeaders: true, 4852 EndStream: false, 4853 BlockFragment: buf.Bytes(), 4854 }) 4855 ct.fr.WriteData(f.StreamID, true, []byte(resBody)) 4856 return nil 4857 case *RSTStreamFrame: 4858 default: 4859 return fmt.Errorf("Unexpected client frame %v", f) 4860 } 4861 } 4862 } 4863 ct.run() 4864 } 4865 4866 type chunkReader struct { 4867 chunks [][]byte 4868 } 4869 4870 func (r *chunkReader) Read(p []byte) (int, error) { 4871 if len(r.chunks) > 0 { 4872 n := copy(p, r.chunks[0]) 4873 r.chunks = r.chunks[1:] 4874 return n, nil 4875 } 4876 panic("shouldn't read this many times") 4877 } 4878 4879 // Issue 32254: if the request body is larger than the specified 4880 // content length, the client should refuse to send the extra part 4881 // and abort the stream. 4882 // 4883 // In _len3 case, the first Read() matches the expected content length 4884 // but the second read returns more data. 4885 // 4886 // In _len2 case, the first Read() exceeds the expected content length. 4887 func TestTransportBodyLargerThanSpecifiedContentLength_len3(t *testing.T) { 4888 body := &chunkReader{[][]byte{ 4889 []byte("123"), 4890 []byte("456"), 4891 }} 4892 testTransportBodyLargerThanSpecifiedContentLength(t, body, 3) 4893 } 4894 4895 func TestTransportBodyLargerThanSpecifiedContentLength_len2(t *testing.T) { 4896 body := &chunkReader{[][]byte{ 4897 []byte("123"), 4898 }} 4899 testTransportBodyLargerThanSpecifiedContentLength(t, body, 2) 4900 } 4901 4902 func testTransportBodyLargerThanSpecifiedContentLength(t *testing.T, body *chunkReader, contentLen int64) { 4903 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 4904 r.Body.Read(make([]byte, 6)) 4905 }, optOnlyServer) 4906 defer st.Close() 4907 4908 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 4909 defer tr.CloseIdleConnections() 4910 4911 req, _ := http.NewRequest("POST", st.ts.URL, body) 4912 req.ContentLength = contentLen 4913 _, err := tr.RoundTrip(req) 4914 if err != errReqBodyTooLong { 4915 t.Fatalf("expected %v, got %v", errReqBodyTooLong, err) 4916 } 4917 } 4918 4919 func TestClientConnTooIdle(t *testing.T) { 4920 tests := []struct { 4921 cc func() *ClientConn 4922 want bool 4923 }{ 4924 { 4925 func() *ClientConn { 4926 return &ClientConn{idleTimeout: 5 * time.Second, lastIdle: time.Now().Add(-10 * time.Second)} 4927 }, 4928 true, 4929 }, 4930 { 4931 func() *ClientConn { 4932 return &ClientConn{idleTimeout: 5 * time.Second, lastIdle: time.Time{}} 4933 }, 4934 false, 4935 }, 4936 { 4937 func() *ClientConn { 4938 return &ClientConn{idleTimeout: 60 * time.Second, lastIdle: time.Now().Add(-10 * time.Second)} 4939 }, 4940 false, 4941 }, 4942 { 4943 func() *ClientConn { 4944 return &ClientConn{idleTimeout: 0, lastIdle: time.Now().Add(-10 * time.Second)} 4945 }, 4946 false, 4947 }, 4948 } 4949 for i, tt := range tests { 4950 got := tt.cc().tooIdleLocked() 4951 if got != tt.want { 4952 t.Errorf("%d. got %v; want %v", i, got, tt.want) 4953 } 4954 } 4955 } 4956 4957 type fakeConnErr struct { 4958 net.Conn 4959 writeErr error 4960 closed bool 4961 } 4962 4963 func (fce *fakeConnErr) Write(b []byte) (n int, err error) { 4964 return 0, fce.writeErr 4965 } 4966 4967 func (fce *fakeConnErr) Close() error { 4968 fce.closed = true 4969 return nil 4970 } 4971 4972 // issue 39337: close the connection on a failed write 4973 func TestTransportNewClientConnCloseOnWriteError(t *testing.T) { 4974 tr := &Transport{} 4975 writeErr := errors.New("write error") 4976 fakeConn := &fakeConnErr{writeErr: writeErr} 4977 _, err := tr.NewClientConn(fakeConn) 4978 if err != writeErr { 4979 t.Fatalf("expected %v, got %v", writeErr, err) 4980 } 4981 if !fakeConn.closed { 4982 t.Error("expected closed conn") 4983 } 4984 } 4985 4986 func TestTransportRoundtripCloseOnWriteError(t *testing.T) { 4987 req, err := http.NewRequest("GET", "https://dummy.tld/", nil) 4988 if err != nil { 4989 t.Fatal(err) 4990 } 4991 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}, optOnlyServer) 4992 defer st.Close() 4993 4994 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 4995 defer tr.CloseIdleConnections() 4996 ctx := context.Background() 4997 cc, err := tr.dialClientConn(ctx, st.ts.Listener.Addr().String(), false) 4998 if err != nil { 4999 t.Fatal(err) 5000 } 5001 5002 writeErr := errors.New("write error") 5003 cc.wmu.Lock() 5004 cc.werr = writeErr 5005 cc.wmu.Unlock() 5006 5007 _, err = cc.RoundTrip(req) 5008 if err != writeErr { 5009 t.Fatalf("expected %v, got %v", writeErr, err) 5010 } 5011 5012 cc.mu.Lock() 5013 closed := cc.closed 5014 cc.mu.Unlock() 5015 if !closed { 5016 t.Fatal("expected closed") 5017 } 5018 } 5019 5020 // Issue 31192: A failed request may be retried if the body has not been read 5021 // already. If the request body has started to be sent, one must wait until it 5022 // is completed. 5023 func TestTransportBodyRewindRace(t *testing.T) { 5024 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 5025 w.Header().Set("Connection", "close") 5026 w.WriteHeader(http.StatusOK) 5027 return 5028 }, optOnlyServer) 5029 defer st.Close() 5030 5031 tr := &http.Transport{ 5032 TLSClientConfig: tlsConfigInsecure, 5033 MaxConnsPerHost: 1, 5034 } 5035 err := ConfigureTransport(tr) 5036 if err != nil { 5037 t.Fatal(err) 5038 } 5039 client := &http.Client{ 5040 Transport: tr, 5041 } 5042 5043 const clients = 50 5044 5045 var wg sync.WaitGroup 5046 wg.Add(clients) 5047 for i := 0; i < clients; i++ { 5048 req, err := http.NewRequest("POST", st.ts.URL, bytes.NewBufferString("abcdef")) 5049 if err != nil { 5050 t.Fatalf("unexpect new request error: %v", err) 5051 } 5052 5053 go func() { 5054 defer wg.Done() 5055 res, err := client.Do(req) 5056 if err == nil { 5057 res.Body.Close() 5058 } 5059 }() 5060 } 5061 5062 wg.Wait() 5063 } 5064 5065 // Issue 42498: A request with a body will never be sent if the stream is 5066 // reset prior to sending any data. 5067 func TestTransportServerResetStreamAtHeaders(t *testing.T) { 5068 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 5069 w.WriteHeader(http.StatusUnauthorized) 5070 return 5071 }, optOnlyServer) 5072 defer st.Close() 5073 5074 tr := &http.Transport{ 5075 TLSClientConfig: tlsConfigInsecure, 5076 MaxConnsPerHost: 1, 5077 ExpectContinueTimeout: 10 * time.Second, 5078 } 5079 5080 err := ConfigureTransport(tr) 5081 if err != nil { 5082 t.Fatal(err) 5083 } 5084 client := &http.Client{ 5085 Transport: tr, 5086 } 5087 5088 req, err := http.NewRequest("POST", st.ts.URL, errorReader{io.EOF}) 5089 if err != nil { 5090 t.Fatalf("unexpect new request error: %v", err) 5091 } 5092 req.ContentLength = 0 // so transport is tempted to sniff it 5093 req.Header.Set("Expect", "100-continue") 5094 res, err := client.Do(req) 5095 if err != nil { 5096 t.Fatal(err) 5097 } 5098 res.Body.Close() 5099 } 5100 5101 type trackingReader struct { 5102 rdr io.Reader 5103 wasRead uint32 5104 } 5105 5106 func (tr *trackingReader) Read(p []byte) (int, error) { 5107 atomic.StoreUint32(&tr.wasRead, 1) 5108 return tr.rdr.Read(p) 5109 } 5110 5111 func (tr *trackingReader) WasRead() bool { 5112 return atomic.LoadUint32(&tr.wasRead) != 0 5113 } 5114 5115 func TestTransportExpectContinue(t *testing.T) { 5116 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 5117 switch r.URL.Path { 5118 case "/reject": 5119 w.WriteHeader(403) 5120 default: 5121 io.Copy(io.Discard, r.Body) 5122 } 5123 }, optOnlyServer) 5124 defer st.Close() 5125 5126 tr := &http.Transport{ 5127 TLSClientConfig: tlsConfigInsecure, 5128 MaxConnsPerHost: 1, 5129 ExpectContinueTimeout: 10 * time.Second, 5130 } 5131 5132 err := ConfigureTransport(tr) 5133 if err != nil { 5134 t.Fatal(err) 5135 } 5136 client := &http.Client{ 5137 Transport: tr, 5138 } 5139 5140 testCases := []struct { 5141 Name string 5142 Path string 5143 Body *trackingReader 5144 ExpectedCode int 5145 ShouldRead bool 5146 }{ 5147 { 5148 Name: "read-all", 5149 Path: "/", 5150 Body: &trackingReader{rdr: strings.NewReader("hello")}, 5151 ExpectedCode: 200, 5152 ShouldRead: true, 5153 }, 5154 { 5155 Name: "reject", 5156 Path: "/reject", 5157 Body: &trackingReader{rdr: strings.NewReader("hello")}, 5158 ExpectedCode: 403, 5159 ShouldRead: false, 5160 }, 5161 } 5162 5163 for _, tc := range testCases { 5164 t.Run(tc.Name, func(t *testing.T) { 5165 startTime := time.Now() 5166 5167 req, err := http.NewRequest("POST", st.ts.URL+tc.Path, tc.Body) 5168 if err != nil { 5169 t.Fatal(err) 5170 } 5171 req.Header.Set("Expect", "100-continue") 5172 res, err := client.Do(req) 5173 if err != nil { 5174 t.Fatal(err) 5175 } 5176 res.Body.Close() 5177 5178 if delta := time.Since(startTime); delta >= tr.ExpectContinueTimeout { 5179 t.Error("Request didn't finish before expect continue timeout") 5180 } 5181 if res.StatusCode != tc.ExpectedCode { 5182 t.Errorf("Unexpected status code, got %d, expected %d", res.StatusCode, tc.ExpectedCode) 5183 } 5184 if tc.Body.WasRead() != tc.ShouldRead { 5185 t.Errorf("Unexpected read status, got %v, expected %v", tc.Body.WasRead(), tc.ShouldRead) 5186 } 5187 }) 5188 } 5189 } 5190 5191 type closeChecker struct { 5192 io.ReadCloser 5193 closed chan struct{} 5194 } 5195 5196 func newCloseChecker(r io.ReadCloser) *closeChecker { 5197 return &closeChecker{r, make(chan struct{})} 5198 } 5199 5200 func newStaticCloseChecker(body string) *closeChecker { 5201 return newCloseChecker(io.NopCloser(strings.NewReader("body"))) 5202 } 5203 5204 func (rc *closeChecker) Read(b []byte) (n int, err error) { 5205 select { 5206 default: 5207 case <-rc.closed: 5208 // TODO(dneil): Consider restructuring the request write to avoid reading 5209 // from the request body after closing it, and check for read-after-close here. 5210 // Currently, abortRequestBodyWrite races with writeRequestBody. 5211 return 0, errors.New("read after Body.Close") 5212 } 5213 return rc.ReadCloser.Read(b) 5214 } 5215 5216 func (rc *closeChecker) Close() error { 5217 close(rc.closed) 5218 return rc.ReadCloser.Close() 5219 } 5220 5221 func (rc *closeChecker) isClosed() error { 5222 // The RoundTrip contract says that it will close the request body, 5223 // but that it may do so in a separate goroutine. Wait a reasonable 5224 // amount of time before concluding that the body isn't being closed. 5225 timeout := time.Duration(10 * time.Second) 5226 select { 5227 case <-rc.closed: 5228 case <-time.After(timeout): 5229 return fmt.Errorf("body not closed after %v", timeout) 5230 } 5231 return nil 5232 } 5233 5234 // A blockingWriteConn is a net.Conn that blocks in Write after some number of bytes are written. 5235 type blockingWriteConn struct { 5236 net.Conn 5237 writeOnce sync.Once 5238 writec chan struct{} // closed after the write limit is reached 5239 unblockc chan struct{} // closed to unblock writes 5240 count, limit int 5241 } 5242 5243 func newBlockingWriteConn(conn net.Conn, limit int) *blockingWriteConn { 5244 return &blockingWriteConn{ 5245 Conn: conn, 5246 limit: limit, 5247 writec: make(chan struct{}), 5248 unblockc: make(chan struct{}), 5249 } 5250 } 5251 5252 // wait waits until the conn blocks writing the limit+1st byte. 5253 func (c *blockingWriteConn) wait() { 5254 <-c.writec 5255 } 5256 5257 // unblock unblocks writes to the conn. 5258 func (c *blockingWriteConn) unblock() { 5259 close(c.unblockc) 5260 } 5261 5262 func (c *blockingWriteConn) Write(b []byte) (n int, err error) { 5263 if c.count+len(b) > c.limit { 5264 c.writeOnce.Do(func() { 5265 close(c.writec) 5266 }) 5267 <-c.unblockc 5268 } 5269 n, err = c.Conn.Write(b) 5270 c.count += n 5271 return n, err 5272 } 5273 5274 // Write several requests to a ClientConn at the same time, looking for race conditions. 5275 // See golang.org/issue/48340 5276 func TestTransportFrameBufferReuse(t *testing.T) { 5277 filler := hex.EncodeToString([]byte(randString(2048))) 5278 5279 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 5280 if got, want := r.Header.Get("Big"), filler; got != want { 5281 t.Errorf(`r.Header.Get("Big") = %q, want %q`, got, want) 5282 } 5283 b, err := ioutil.ReadAll(r.Body) 5284 if err != nil { 5285 t.Errorf("error reading request body: %v", err) 5286 } 5287 if got, want := string(b), filler; got != want { 5288 t.Errorf("request body = %q, want %q", got, want) 5289 } 5290 if got, want := r.Trailer.Get("Big"), filler; got != want { 5291 t.Errorf(`r.Trailer.Get("Big") = %q, want %q`, got, want) 5292 } 5293 }, optOnlyServer) 5294 defer st.Close() 5295 5296 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 5297 defer tr.CloseIdleConnections() 5298 5299 var wg sync.WaitGroup 5300 defer wg.Wait() 5301 for i := 0; i < 10; i++ { 5302 wg.Add(1) 5303 go func() { 5304 defer wg.Done() 5305 req, err := http.NewRequest("POST", st.ts.URL, strings.NewReader(filler)) 5306 if err != nil { 5307 t.Fatal(err) 5308 } 5309 req.Header.Set("Big", filler) 5310 req.Trailer = make(http.Header) 5311 req.Trailer.Set("Big", filler) 5312 res, err := tr.RoundTrip(req) 5313 if err != nil { 5314 t.Fatal(err) 5315 } 5316 if got, want := res.StatusCode, 200; got != want { 5317 t.Errorf("StatusCode = %v; want %v", got, want) 5318 } 5319 if res != nil && res.Body != nil { 5320 res.Body.Close() 5321 } 5322 }() 5323 } 5324 5325 } 5326 5327 // Ensure that a request blocking while being written to the underlying net.Conn doesn't 5328 // block access to the ClientConn pool. Test requests blocking while writing headers, the body, 5329 // and trailers. 5330 // See golang.org/issue/32388 5331 func TestTransportBlockingRequestWrite(t *testing.T) { 5332 filler := hex.EncodeToString([]byte(randString(2048))) 5333 for _, test := range []struct { 5334 name string 5335 req func(url string) (*http.Request, error) 5336 }{{ 5337 name: "headers", 5338 req: func(url string) (*http.Request, error) { 5339 req, err := http.NewRequest("POST", url, nil) 5340 if err != nil { 5341 return nil, err 5342 } 5343 req.Header.Set("Big", filler) 5344 return req, err 5345 }, 5346 }, { 5347 name: "body", 5348 req: func(url string) (*http.Request, error) { 5349 req, err := http.NewRequest("POST", url, strings.NewReader(filler)) 5350 if err != nil { 5351 return nil, err 5352 } 5353 return req, err 5354 }, 5355 }, { 5356 name: "trailer", 5357 req: func(url string) (*http.Request, error) { 5358 req, err := http.NewRequest("POST", url, strings.NewReader("body")) 5359 if err != nil { 5360 return nil, err 5361 } 5362 req.Trailer = make(http.Header) 5363 req.Trailer.Set("Big", filler) 5364 return req, err 5365 }, 5366 }} { 5367 test := test 5368 t.Run(test.name, func(t *testing.T) { 5369 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 5370 if v := r.Header.Get("Big"); v != "" && v != filler { 5371 t.Errorf("request header mismatch") 5372 } 5373 if v, _ := io.ReadAll(r.Body); len(v) != 0 && string(v) != "body" && string(v) != filler { 5374 t.Errorf("request body mismatch\ngot: %q\nwant: %q", string(v), filler) 5375 } 5376 if v := r.Trailer.Get("Big"); v != "" && v != filler { 5377 t.Errorf("request trailer mismatch\ngot: %q\nwant: %q", string(v), filler) 5378 } 5379 }, optOnlyServer, func(s *Server) { 5380 s.MaxConcurrentStreams = 1 5381 }) 5382 defer st.Close() 5383 5384 // This Transport creates connections that block on writes after 1024 bytes. 5385 connc := make(chan *blockingWriteConn, 1) 5386 connCount := 0 5387 tr := &Transport{ 5388 TLSClientConfig: tlsConfigInsecure, 5389 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 5390 connCount++ 5391 c, err := tls.Dial(network, addr, cfg) 5392 wc := newBlockingWriteConn(c, 1024) 5393 select { 5394 case connc <- wc: 5395 default: 5396 } 5397 return wc, err 5398 }, 5399 } 5400 defer tr.CloseIdleConnections() 5401 5402 // Request 1: A small request to ensure we read the server MaxConcurrentStreams. 5403 { 5404 req, err := http.NewRequest("POST", st.ts.URL, nil) 5405 if err != nil { 5406 t.Fatal(err) 5407 } 5408 res, err := tr.RoundTrip(req) 5409 if err != nil { 5410 t.Fatal(err) 5411 } 5412 if got, want := res.StatusCode, 200; got != want { 5413 t.Errorf("StatusCode = %v; want %v", got, want) 5414 } 5415 if res != nil && res.Body != nil { 5416 res.Body.Close() 5417 } 5418 } 5419 5420 // Request 2: A large request that blocks while being written. 5421 reqc := make(chan struct{}) 5422 go func() { 5423 defer close(reqc) 5424 req, err := test.req(st.ts.URL) 5425 if err != nil { 5426 t.Error(err) 5427 return 5428 } 5429 res, _ := tr.RoundTrip(req) 5430 if res != nil && res.Body != nil { 5431 res.Body.Close() 5432 } 5433 }() 5434 conn := <-connc 5435 conn.wait() // wait for the request to block 5436 5437 // Request 3: A small request that is sent on a new connection, since request 2 5438 // is hogging the only available stream on the previous connection. 5439 { 5440 req, err := http.NewRequest("POST", st.ts.URL, nil) 5441 if err != nil { 5442 t.Fatal(err) 5443 } 5444 res, err := tr.RoundTrip(req) 5445 if err != nil { 5446 t.Fatal(err) 5447 } 5448 if got, want := res.StatusCode, 200; got != want { 5449 t.Errorf("StatusCode = %v; want %v", got, want) 5450 } 5451 if res != nil && res.Body != nil { 5452 res.Body.Close() 5453 } 5454 } 5455 5456 // Request 2 should still be blocking at this point. 5457 select { 5458 case <-reqc: 5459 t.Errorf("request 2 unexpectedly completed") 5460 default: 5461 } 5462 5463 conn.unblock() 5464 <-reqc 5465 5466 if connCount != 2 { 5467 t.Errorf("created %v connections, want 1", connCount) 5468 } 5469 }) 5470 } 5471 } 5472 5473 func TestTransportCloseRequestBody(t *testing.T) { 5474 var statusCode int 5475 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 5476 w.WriteHeader(statusCode) 5477 }, optOnlyServer) 5478 defer st.Close() 5479 5480 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 5481 defer tr.CloseIdleConnections() 5482 ctx := context.Background() 5483 cc, err := tr.dialClientConn(ctx, st.ts.Listener.Addr().String(), false) 5484 if err != nil { 5485 t.Fatal(err) 5486 } 5487 5488 for _, status := range []int{200, 401} { 5489 t.Run(fmt.Sprintf("status=%d", status), func(t *testing.T) { 5490 statusCode = status 5491 pr, pw := io.Pipe() 5492 body := newCloseChecker(pr) 5493 req, err := http.NewRequest("PUT", "https://dummy.tld/", body) 5494 if err != nil { 5495 t.Fatal(err) 5496 } 5497 res, err := cc.RoundTrip(req) 5498 if err != nil { 5499 t.Fatal(err) 5500 } 5501 res.Body.Close() 5502 pw.Close() 5503 if err := body.isClosed(); err != nil { 5504 t.Fatal(err) 5505 } 5506 }) 5507 } 5508 } 5509 5510 // collectClientsConnPool is a ClientConnPool that wraps lower and 5511 // collects what calls were made on it. 5512 type collectClientsConnPool struct { 5513 lower ClientConnPool 5514 5515 mu sync.Mutex 5516 getErrs int 5517 got []*ClientConn 5518 } 5519 5520 func (p *collectClientsConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) { 5521 cc, err := p.lower.GetClientConn(req, addr) 5522 p.mu.Lock() 5523 defer p.mu.Unlock() 5524 if err != nil { 5525 p.getErrs++ 5526 return nil, err 5527 } 5528 p.got = append(p.got, cc) 5529 return cc, nil 5530 } 5531 5532 func (p *collectClientsConnPool) MarkDead(cc *ClientConn) { 5533 p.lower.MarkDead(cc) 5534 } 5535 5536 func TestTransportRetriesOnStreamProtocolError(t *testing.T) { 5537 ct := newClientTester(t) 5538 pool := &collectClientsConnPool{ 5539 lower: &clientConnPool{t: ct.tr}, 5540 } 5541 ct.tr.ConnPool = pool 5542 5543 gotProtoError := make(chan bool, 1) 5544 ct.tr.CountError = func(errType string) { 5545 if errType == "recv_rststream_PROTOCOL_ERROR" { 5546 select { 5547 case gotProtoError <- true: 5548 default: 5549 } 5550 } 5551 } 5552 ct.client = func() error { 5553 // Start two requests. The first is a long request 5554 // that will finish after the second. The second one 5555 // will result in the protocol error. We check that 5556 // after the first one closes, the connection then 5557 // shuts down. 5558 5559 // The long, outer request. 5560 req1, _ := http.NewRequest("GET", "https://dummy.tld/long", nil) 5561 res1, err := ct.tr.RoundTrip(req1) 5562 if err != nil { 5563 return err 5564 } 5565 if got, want := res1.Header.Get("Is-Long"), "1"; got != want { 5566 return fmt.Errorf("First response's Is-Long header = %q; want %q", got, want) 5567 } 5568 5569 req, _ := http.NewRequest("POST", "https://dummy.tld/fails", nil) 5570 res, err := ct.tr.RoundTrip(req) 5571 const want = "only one dial allowed in test mode" 5572 if got := fmt.Sprint(err); got != want { 5573 t.Errorf("didn't dial again: got %#q; want %#q", got, want) 5574 } 5575 if res != nil { 5576 res.Body.Close() 5577 } 5578 select { 5579 case <-gotProtoError: 5580 default: 5581 t.Errorf("didn't get stream protocol error") 5582 } 5583 5584 if n, err := res1.Body.Read(make([]byte, 10)); err != io.EOF || n != 0 { 5585 t.Errorf("unexpected body read %v, %v", n, err) 5586 } 5587 5588 pool.mu.Lock() 5589 defer pool.mu.Unlock() 5590 if pool.getErrs != 1 { 5591 t.Errorf("pool get errors = %v; want 1", pool.getErrs) 5592 } 5593 if len(pool.got) == 2 { 5594 if pool.got[0] != pool.got[1] { 5595 t.Errorf("requests went on different connections") 5596 } 5597 cc := pool.got[0] 5598 cc.mu.Lock() 5599 if !cc.doNotReuse { 5600 t.Error("ClientConn not marked doNotReuse") 5601 } 5602 cc.mu.Unlock() 5603 5604 select { 5605 case <-cc.readerDone: 5606 case <-time.After(5 * time.Second): 5607 t.Errorf("timeout waiting for reader to be done") 5608 } 5609 } else { 5610 t.Errorf("pool get success = %v; want 2", len(pool.got)) 5611 } 5612 return nil 5613 } 5614 ct.server = func() error { 5615 ct.greet() 5616 var sentErr bool 5617 var numHeaders int 5618 var firstStreamID uint32 5619 5620 var hbuf bytes.Buffer 5621 enc := hpack.NewEncoder(&hbuf) 5622 5623 for { 5624 f, err := ct.fr.ReadFrame() 5625 if err == io.EOF { 5626 // Client hung up on us, as it should at the end. 5627 return nil 5628 } 5629 if err != nil { 5630 return nil 5631 } 5632 switch f := f.(type) { 5633 case *WindowUpdateFrame, *SettingsFrame: 5634 case *HeadersFrame: 5635 numHeaders++ 5636 if numHeaders == 1 { 5637 firstStreamID = f.StreamID 5638 hbuf.Reset() 5639 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 5640 enc.WriteField(hpack.HeaderField{Name: "is-long", Value: "1"}) 5641 ct.fr.WriteHeaders(HeadersFrameParam{ 5642 StreamID: f.StreamID, 5643 EndHeaders: true, 5644 EndStream: false, 5645 BlockFragment: hbuf.Bytes(), 5646 }) 5647 continue 5648 } 5649 if !sentErr { 5650 sentErr = true 5651 ct.fr.WriteRSTStream(f.StreamID, ErrCodeProtocol) 5652 ct.fr.WriteData(firstStreamID, true, nil) 5653 continue 5654 } 5655 } 5656 } 5657 return nil 5658 } 5659 ct.run() 5660 } 5661 5662 func TestClientConnReservations(t *testing.T) { 5663 cc := &ClientConn{ 5664 reqHeaderMu: make(chan struct{}, 1), 5665 streams: make(map[uint32]*clientStream), 5666 maxConcurrentStreams: initialMaxConcurrentStreams, 5667 nextStreamID: 1, 5668 t: &Transport{}, 5669 } 5670 cc.cond = sync.NewCond(&cc.mu) 5671 n := 0 5672 for n <= initialMaxConcurrentStreams && cc.ReserveNewRequest() { 5673 n++ 5674 } 5675 if n != initialMaxConcurrentStreams { 5676 t.Errorf("did %v reservations; want %v", n, initialMaxConcurrentStreams) 5677 } 5678 if _, err := cc.RoundTrip(new(http.Request)); !errors.Is(err, errNilRequestURL) { 5679 t.Fatalf("RoundTrip error = %v; want errNilRequestURL", err) 5680 } 5681 n2 := 0 5682 for n2 <= 5 && cc.ReserveNewRequest() { 5683 n2++ 5684 } 5685 if n2 != 1 { 5686 t.Fatalf("after one RoundTrip, did %v reservations; want 1", n2) 5687 } 5688 5689 // Use up all the reservations 5690 for i := 0; i < n; i++ { 5691 cc.RoundTrip(new(http.Request)) 5692 } 5693 5694 n2 = 0 5695 for n2 <= initialMaxConcurrentStreams && cc.ReserveNewRequest() { 5696 n2++ 5697 } 5698 if n2 != n { 5699 t.Errorf("after reset, reservations = %v; want %v", n2, n) 5700 } 5701 } 5702 5703 func TestTransportTimeoutServerHangs(t *testing.T) { 5704 clientDone := make(chan struct{}) 5705 ct := newClientTester(t) 5706 ct.client = func() error { 5707 defer ct.cc.(*net.TCPConn).CloseWrite() 5708 defer close(clientDone) 5709 5710 req, err := http.NewRequest("PUT", "https://dummy.tld/", nil) 5711 if err != nil { 5712 return err 5713 } 5714 5715 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) 5716 defer cancel() 5717 req = req.WithContext(ctx) 5718 req.Header.Add("Big", strings.Repeat("a", 1<<20)) 5719 _, err = ct.tr.RoundTrip(req) 5720 if err == nil { 5721 return errors.New("error should not be nil") 5722 } 5723 if ne, ok := err.(net.Error); !ok || !ne.Timeout() { 5724 return fmt.Errorf("error should be a net error timeout: %v", err) 5725 } 5726 return nil 5727 } 5728 ct.server = func() error { 5729 ct.greet() 5730 select { 5731 case <-time.After(5 * time.Second): 5732 case <-clientDone: 5733 } 5734 return nil 5735 } 5736 ct.run() 5737 } 5738 5739 func TestTransportContentLengthWithoutBody(t *testing.T) { 5740 contentLength := "" 5741 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 5742 w.Header().Set("Content-Length", contentLength) 5743 }, optOnlyServer) 5744 defer st.Close() 5745 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 5746 defer tr.CloseIdleConnections() 5747 5748 for _, test := range []struct { 5749 name string 5750 contentLength string 5751 wantBody string 5752 wantErr error 5753 wantContentLength int64 5754 }{ 5755 { 5756 name: "non-zero content length", 5757 contentLength: "42", 5758 wantErr: io.ErrUnexpectedEOF, 5759 wantContentLength: 42, 5760 }, 5761 { 5762 name: "zero content length", 5763 contentLength: "0", 5764 wantErr: nil, 5765 wantContentLength: 0, 5766 }, 5767 } { 5768 t.Run(test.name, func(t *testing.T) { 5769 contentLength = test.contentLength 5770 5771 req, _ := http.NewRequest("GET", st.ts.URL, nil) 5772 res, err := tr.RoundTrip(req) 5773 if err != nil { 5774 t.Fatal(err) 5775 } 5776 defer res.Body.Close() 5777 body, err := io.ReadAll(res.Body) 5778 5779 if err != test.wantErr { 5780 t.Errorf("Expected error %v, got: %v", test.wantErr, err) 5781 } 5782 if len(body) > 0 { 5783 t.Errorf("Expected empty body, got: %v", body) 5784 } 5785 if res.ContentLength != test.wantContentLength { 5786 t.Errorf("Expected content length %d, got: %d", test.wantContentLength, res.ContentLength) 5787 } 5788 }) 5789 } 5790 } 5791 5792 func TestTransportCloseResponseBodyWhileRequestBodyHangs(t *testing.T) { 5793 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 5794 w.WriteHeader(200) 5795 w.(http.Flusher).Flush() 5796 io.Copy(io.Discard, r.Body) 5797 }, optOnlyServer) 5798 defer st.Close() 5799 5800 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 5801 defer tr.CloseIdleConnections() 5802 5803 pr, pw := net.Pipe() 5804 req, err := http.NewRequest("GET", st.ts.URL, pr) 5805 if err != nil { 5806 t.Fatal(err) 5807 } 5808 res, err := tr.RoundTrip(req) 5809 if err != nil { 5810 t.Fatal(err) 5811 } 5812 // Closing the Response's Body interrupts the blocked body read. 5813 res.Body.Close() 5814 pw.Close() 5815 } 5816 5817 func TestTransport300ResponseBody(t *testing.T) { 5818 reqc := make(chan struct{}) 5819 body := []byte("response body") 5820 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 5821 w.WriteHeader(300) 5822 w.(http.Flusher).Flush() 5823 <-reqc 5824 w.Write(body) 5825 }, optOnlyServer) 5826 defer st.Close() 5827 5828 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 5829 defer tr.CloseIdleConnections() 5830 5831 pr, pw := net.Pipe() 5832 req, err := http.NewRequest("GET", st.ts.URL, pr) 5833 if err != nil { 5834 t.Fatal(err) 5835 } 5836 res, err := tr.RoundTrip(req) 5837 if err != nil { 5838 t.Fatal(err) 5839 } 5840 close(reqc) 5841 got, err := io.ReadAll(res.Body) 5842 if err != nil { 5843 t.Fatalf("error reading response body: %v", err) 5844 } 5845 if !bytes.Equal(got, body) { 5846 t.Errorf("got response body %q, want %q", string(got), string(body)) 5847 } 5848 res.Body.Close() 5849 pw.Close() 5850 } 5851 5852 func TestTransportWriteByteTimeout(t *testing.T) { 5853 st := newServerTester(t, 5854 func(w http.ResponseWriter, r *http.Request) {}, 5855 optOnlyServer, 5856 ) 5857 defer st.Close() 5858 tr := &Transport{ 5859 TLSClientConfig: tlsConfigInsecure, 5860 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 5861 _, c := net.Pipe() 5862 return c, nil 5863 }, 5864 WriteByteTimeout: 1 * time.Millisecond, 5865 } 5866 defer tr.CloseIdleConnections() 5867 c := &http.Client{Transport: tr} 5868 5869 _, err := c.Get(st.ts.URL) 5870 if !errors.Is(err, os.ErrDeadlineExceeded) { 5871 t.Fatalf("Get on unresponsive connection: got %q; want ErrDeadlineExceeded", err) 5872 } 5873 } 5874 5875 type slowWriteConn struct { 5876 net.Conn 5877 hasWriteDeadline bool 5878 } 5879 5880 func (c *slowWriteConn) SetWriteDeadline(t time.Time) error { 5881 c.hasWriteDeadline = !t.IsZero() 5882 return nil 5883 } 5884 5885 func (c *slowWriteConn) Write(b []byte) (n int, err error) { 5886 if c.hasWriteDeadline && len(b) > 1 { 5887 n, err = c.Conn.Write(b[:1]) 5888 if err != nil { 5889 return n, err 5890 } 5891 return n, fmt.Errorf("slow write: %w", os.ErrDeadlineExceeded) 5892 } 5893 return c.Conn.Write(b) 5894 } 5895 5896 func TestTransportSlowWrites(t *testing.T) { 5897 st := newServerTester(t, 5898 func(w http.ResponseWriter, r *http.Request) {}, 5899 optOnlyServer, 5900 ) 5901 defer st.Close() 5902 tr := &Transport{ 5903 TLSClientConfig: tlsConfigInsecure, 5904 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 5905 cfg.InsecureSkipVerify = true 5906 c, err := tls.Dial(network, addr, cfg) 5907 return &slowWriteConn{Conn: c}, err 5908 }, 5909 WriteByteTimeout: 1 * time.Millisecond, 5910 } 5911 defer tr.CloseIdleConnections() 5912 c := &http.Client{Transport: tr} 5913 5914 const bodySize = 1 << 20 5915 resp, err := c.Post(st.ts.URL, "text/foo", io.LimitReader(neverEnding('A'), bodySize)) 5916 if err != nil { 5917 t.Fatal(err) 5918 } 5919 resp.Body.Close() 5920 }