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