github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/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 "crypto/tls" 12 "errors" 13 "flag" 14 "fmt" 15 "io" 16 "io/ioutil" 17 "log" 18 "math/rand" 19 "net" 20 "net/http" 21 "net/http/httptest" 22 "net/http/httptrace" 23 "net/textproto" 24 "net/url" 25 "os" 26 "reflect" 27 "runtime" 28 "sort" 29 "strconv" 30 "strings" 31 "sync" 32 "sync/atomic" 33 "testing" 34 "time" 35 36 "github.com/Andyfoo/golang/x/net/http2/hpack" 37 ) 38 39 var ( 40 extNet = flag.Bool("extnet", false, "do external network tests") 41 transportHost = flag.String("transporthost", "http2.golang.org", "hostname to use for TestTransport") 42 insecure = flag.Bool("insecure", false, "insecure TLS dials") // TODO: dead code. remove? 43 ) 44 45 var tlsConfigInsecure = &tls.Config{InsecureSkipVerify: true} 46 47 var canceledCtx context.Context 48 49 func init() { 50 ctx, cancel := context.WithCancel(context.Background()) 51 cancel() 52 canceledCtx = ctx 53 } 54 55 func TestTransportExternal(t *testing.T) { 56 if !*extNet { 57 t.Skip("skipping external network test") 58 } 59 req, _ := http.NewRequest("GET", "https://"+*transportHost+"/", nil) 60 rt := &Transport{TLSClientConfig: tlsConfigInsecure} 61 res, err := rt.RoundTrip(req) 62 if err != nil { 63 t.Fatalf("%v", err) 64 } 65 res.Write(os.Stdout) 66 } 67 68 type fakeTLSConn struct { 69 net.Conn 70 } 71 72 func (c *fakeTLSConn) ConnectionState() tls.ConnectionState { 73 return tls.ConnectionState{ 74 Version: tls.VersionTLS12, 75 CipherSuite: cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 76 } 77 } 78 79 func startH2cServer(t *testing.T) net.Listener { 80 h2Server := &Server{} 81 l := newLocalListener(t) 82 go func() { 83 conn, err := l.Accept() 84 if err != nil { 85 t.Error(err) 86 return 87 } 88 h2Server.ServeConn(&fakeTLSConn{conn}, &ServeConnOpts{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 89 fmt.Fprintf(w, "Hello, %v, http: %v", r.URL.Path, r.TLS == nil) 90 })}) 91 }() 92 return l 93 } 94 95 func TestTransportH2c(t *testing.T) { 96 l := startH2cServer(t) 97 defer l.Close() 98 req, err := http.NewRequest("GET", "http://"+l.Addr().String()+"/foobar", nil) 99 if err != nil { 100 t.Fatal(err) 101 } 102 var gotConnCnt int32 103 trace := &httptrace.ClientTrace{ 104 GotConn: func(connInfo httptrace.GotConnInfo) { 105 if !connInfo.Reused { 106 atomic.AddInt32(&gotConnCnt, 1) 107 } 108 }, 109 } 110 req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) 111 tr := &Transport{ 112 AllowHTTP: true, 113 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 114 return net.Dial(network, addr) 115 }, 116 } 117 res, err := tr.RoundTrip(req) 118 if err != nil { 119 t.Fatal(err) 120 } 121 if res.ProtoMajor != 2 { 122 t.Fatal("proto not h2c") 123 } 124 body, err := ioutil.ReadAll(res.Body) 125 if err != nil { 126 t.Fatal(err) 127 } 128 if got, want := string(body), "Hello, /foobar, http: true"; got != want { 129 t.Fatalf("response got %v, want %v", got, want) 130 } 131 if got, want := gotConnCnt, int32(1); got != want { 132 t.Errorf("Too many got connections: %d", gotConnCnt) 133 } 134 } 135 136 func TestTransport(t *testing.T) { 137 const body = "sup" 138 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 139 io.WriteString(w, body) 140 }, optOnlyServer) 141 defer st.Close() 142 143 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 144 defer tr.CloseIdleConnections() 145 146 u, err := url.Parse(st.ts.URL) 147 if err != nil { 148 t.Fatal(err) 149 } 150 for i, m := range []string{"GET", ""} { 151 req := &http.Request{ 152 Method: m, 153 URL: u, 154 } 155 res, err := tr.RoundTrip(req) 156 if err != nil { 157 t.Fatalf("%d: %s", i, err) 158 } 159 160 t.Logf("%d: Got res: %+v", i, res) 161 if g, w := res.StatusCode, 200; g != w { 162 t.Errorf("%d: StatusCode = %v; want %v", i, g, w) 163 } 164 if g, w := res.Status, "200 OK"; g != w { 165 t.Errorf("%d: Status = %q; want %q", i, g, w) 166 } 167 wantHeader := http.Header{ 168 "Content-Length": []string{"3"}, 169 "Content-Type": []string{"text/plain; charset=utf-8"}, 170 "Date": []string{"XXX"}, // see cleanDate 171 } 172 cleanDate(res) 173 if !reflect.DeepEqual(res.Header, wantHeader) { 174 t.Errorf("%d: res Header = %v; want %v", i, res.Header, wantHeader) 175 } 176 if res.Request != req { 177 t.Errorf("%d: Response.Request = %p; want %p", i, res.Request, req) 178 } 179 if res.TLS == nil { 180 t.Errorf("%d: Response.TLS = nil; want non-nil", i) 181 } 182 slurp, err := ioutil.ReadAll(res.Body) 183 if err != nil { 184 t.Errorf("%d: Body read: %v", i, err) 185 } else if string(slurp) != body { 186 t.Errorf("%d: Body = %q; want %q", i, slurp, body) 187 } 188 res.Body.Close() 189 } 190 } 191 192 func onSameConn(t *testing.T, modReq func(*http.Request)) bool { 193 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 194 io.WriteString(w, r.RemoteAddr) 195 }, optOnlyServer, func(c net.Conn, st http.ConnState) { 196 t.Logf("conn %v is now state %v", c.RemoteAddr(), st) 197 }) 198 defer st.Close() 199 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 200 defer tr.CloseIdleConnections() 201 get := func() string { 202 req, err := http.NewRequest("GET", st.ts.URL, nil) 203 if err != nil { 204 t.Fatal(err) 205 } 206 modReq(req) 207 res, err := tr.RoundTrip(req) 208 if err != nil { 209 t.Fatal(err) 210 } 211 defer res.Body.Close() 212 slurp, err := ioutil.ReadAll(res.Body) 213 if err != nil { 214 t.Fatalf("Body read: %v", err) 215 } 216 addr := strings.TrimSpace(string(slurp)) 217 if addr == "" { 218 t.Fatalf("didn't get an addr in response") 219 } 220 return addr 221 } 222 first := get() 223 second := get() 224 return first == second 225 } 226 227 func TestTransportReusesConns(t *testing.T) { 228 if !onSameConn(t, func(*http.Request) {}) { 229 t.Errorf("first and second responses were on different connections") 230 } 231 } 232 233 func TestTransportReusesConn_RequestClose(t *testing.T) { 234 if onSameConn(t, func(r *http.Request) { r.Close = true }) { 235 t.Errorf("first and second responses were not on different connections") 236 } 237 } 238 239 func TestTransportReusesConn_ConnClose(t *testing.T) { 240 if onSameConn(t, func(r *http.Request) { r.Header.Set("Connection", "close") }) { 241 t.Errorf("first and second responses were not on different connections") 242 } 243 } 244 245 // Tests that the Transport only keeps one pending dial open per destination address. 246 // https://golang.org/issue/13397 247 func TestTransportGroupsPendingDials(t *testing.T) { 248 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 249 io.WriteString(w, r.RemoteAddr) 250 }, optOnlyServer) 251 defer st.Close() 252 tr := &Transport{ 253 TLSClientConfig: tlsConfigInsecure, 254 } 255 defer tr.CloseIdleConnections() 256 var ( 257 mu sync.Mutex 258 dials = map[string]int{} 259 ) 260 var gotConnCnt int32 261 trace := &httptrace.ClientTrace{ 262 GotConn: func(connInfo httptrace.GotConnInfo) { 263 if !connInfo.Reused { 264 atomic.AddInt32(&gotConnCnt, 1) 265 } 266 }, 267 } 268 var wg sync.WaitGroup 269 for i := 0; i < 10; i++ { 270 wg.Add(1) 271 go func() { 272 defer wg.Done() 273 req, err := http.NewRequest("GET", st.ts.URL, nil) 274 if err != nil { 275 t.Error(err) 276 return 277 } 278 req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) 279 res, err := tr.RoundTrip(req) 280 if err != nil { 281 t.Error(err) 282 return 283 } 284 defer res.Body.Close() 285 slurp, err := ioutil.ReadAll(res.Body) 286 if err != nil { 287 t.Errorf("Body read: %v", err) 288 } 289 addr := strings.TrimSpace(string(slurp)) 290 if addr == "" { 291 t.Errorf("didn't get an addr in response") 292 } 293 mu.Lock() 294 dials[addr]++ 295 mu.Unlock() 296 }() 297 } 298 wg.Wait() 299 if len(dials) != 1 { 300 t.Errorf("saw %d dials; want 1: %v", len(dials), dials) 301 } 302 tr.CloseIdleConnections() 303 if err := retry(50, 10*time.Millisecond, func() error { 304 cp, ok := tr.connPool().(*clientConnPool) 305 if !ok { 306 return fmt.Errorf("Conn pool is %T; want *clientConnPool", tr.connPool()) 307 } 308 cp.mu.Lock() 309 defer cp.mu.Unlock() 310 if len(cp.dialing) != 0 { 311 return fmt.Errorf("dialing map = %v; want empty", cp.dialing) 312 } 313 if len(cp.conns) != 0 { 314 return fmt.Errorf("conns = %v; want empty", cp.conns) 315 } 316 if len(cp.keys) != 0 { 317 return fmt.Errorf("keys = %v; want empty", cp.keys) 318 } 319 return nil 320 }); err != nil { 321 t.Errorf("State of pool after CloseIdleConnections: %v", err) 322 } 323 if got, want := gotConnCnt, int32(1); got != want { 324 t.Errorf("Too many got connections: %d", gotConnCnt) 325 } 326 } 327 328 func retry(tries int, delay time.Duration, fn func() error) error { 329 var err error 330 for i := 0; i < tries; i++ { 331 err = fn() 332 if err == nil { 333 return nil 334 } 335 time.Sleep(delay) 336 } 337 return err 338 } 339 340 func TestTransportAbortClosesPipes(t *testing.T) { 341 shutdown := make(chan struct{}) 342 st := newServerTester(t, 343 func(w http.ResponseWriter, r *http.Request) { 344 w.(http.Flusher).Flush() 345 <-shutdown 346 }, 347 optOnlyServer, 348 ) 349 defer st.Close() 350 defer close(shutdown) // we must shutdown before st.Close() to avoid hanging 351 352 done := make(chan struct{}) 353 requestMade := make(chan struct{}) 354 go func() { 355 defer close(done) 356 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 357 req, err := http.NewRequest("GET", st.ts.URL, nil) 358 if err != nil { 359 t.Fatal(err) 360 } 361 res, err := tr.RoundTrip(req) 362 if err != nil { 363 t.Fatal(err) 364 } 365 defer res.Body.Close() 366 close(requestMade) 367 _, err = ioutil.ReadAll(res.Body) 368 if err == nil { 369 t.Error("expected error from res.Body.Read") 370 } 371 }() 372 373 <-requestMade 374 // Now force the serve loop to end, via closing the connection. 375 st.closeConn() 376 // deadlock? that's a bug. 377 select { 378 case <-done: 379 case <-time.After(3 * time.Second): 380 t.Fatal("timeout") 381 } 382 } 383 384 // TODO: merge this with TestTransportBody to make TestTransportRequest? This 385 // could be a table-driven test with extra goodies. 386 func TestTransportPath(t *testing.T) { 387 gotc := make(chan *url.URL, 1) 388 st := newServerTester(t, 389 func(w http.ResponseWriter, r *http.Request) { 390 gotc <- r.URL 391 }, 392 optOnlyServer, 393 ) 394 defer st.Close() 395 396 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 397 defer tr.CloseIdleConnections() 398 const ( 399 path = "/testpath" 400 query = "q=1" 401 ) 402 surl := st.ts.URL + path + "?" + query 403 req, err := http.NewRequest("POST", surl, nil) 404 if err != nil { 405 t.Fatal(err) 406 } 407 c := &http.Client{Transport: tr} 408 res, err := c.Do(req) 409 if err != nil { 410 t.Fatal(err) 411 } 412 defer res.Body.Close() 413 got := <-gotc 414 if got.Path != path { 415 t.Errorf("Read Path = %q; want %q", got.Path, path) 416 } 417 if got.RawQuery != query { 418 t.Errorf("Read RawQuery = %q; want %q", got.RawQuery, query) 419 } 420 } 421 422 func randString(n int) string { 423 rnd := rand.New(rand.NewSource(int64(n))) 424 b := make([]byte, n) 425 for i := range b { 426 b[i] = byte(rnd.Intn(256)) 427 } 428 return string(b) 429 } 430 431 type panicReader struct{} 432 433 func (panicReader) Read([]byte) (int, error) { panic("unexpected Read") } 434 func (panicReader) Close() error { panic("unexpected Close") } 435 436 func TestActualContentLength(t *testing.T) { 437 tests := []struct { 438 req *http.Request 439 want int64 440 }{ 441 // Verify we don't read from Body: 442 0: { 443 req: &http.Request{Body: panicReader{}}, 444 want: -1, 445 }, 446 // nil Body means 0, regardless of ContentLength: 447 1: { 448 req: &http.Request{Body: nil, ContentLength: 5}, 449 want: 0, 450 }, 451 // ContentLength is used if set. 452 2: { 453 req: &http.Request{Body: panicReader{}, ContentLength: 5}, 454 want: 5, 455 }, 456 // http.NoBody means 0, not -1. 457 3: { 458 req: &http.Request{Body: http.NoBody}, 459 want: 0, 460 }, 461 } 462 for i, tt := range tests { 463 got := actualContentLength(tt.req) 464 if got != tt.want { 465 t.Errorf("test[%d]: got %d; want %d", i, got, tt.want) 466 } 467 } 468 } 469 470 func TestTransportBody(t *testing.T) { 471 bodyTests := []struct { 472 body string 473 noContentLen bool 474 }{ 475 {body: "some message"}, 476 {body: "some message", noContentLen: true}, 477 {body: strings.Repeat("a", 1<<20), noContentLen: true}, 478 {body: strings.Repeat("a", 1<<20)}, 479 {body: randString(16<<10 - 1)}, 480 {body: randString(16 << 10)}, 481 {body: randString(16<<10 + 1)}, 482 {body: randString(512<<10 - 1)}, 483 {body: randString(512 << 10)}, 484 {body: randString(512<<10 + 1)}, 485 {body: randString(1<<20 - 1)}, 486 {body: randString(1 << 20)}, 487 {body: randString(1<<20 + 2)}, 488 } 489 490 type reqInfo struct { 491 req *http.Request 492 slurp []byte 493 err error 494 } 495 gotc := make(chan reqInfo, 1) 496 st := newServerTester(t, 497 func(w http.ResponseWriter, r *http.Request) { 498 slurp, err := ioutil.ReadAll(r.Body) 499 if err != nil { 500 gotc <- reqInfo{err: err} 501 } else { 502 gotc <- reqInfo{req: r, slurp: slurp} 503 } 504 }, 505 optOnlyServer, 506 ) 507 defer st.Close() 508 509 for i, tt := range bodyTests { 510 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 511 defer tr.CloseIdleConnections() 512 513 var body io.Reader = strings.NewReader(tt.body) 514 if tt.noContentLen { 515 body = struct{ io.Reader }{body} // just a Reader, hiding concrete type and other methods 516 } 517 req, err := http.NewRequest("POST", st.ts.URL, body) 518 if err != nil { 519 t.Fatalf("#%d: %v", i, err) 520 } 521 c := &http.Client{Transport: tr} 522 res, err := c.Do(req) 523 if err != nil { 524 t.Fatalf("#%d: %v", i, err) 525 } 526 defer res.Body.Close() 527 ri := <-gotc 528 if ri.err != nil { 529 t.Errorf("#%d: read error: %v", i, ri.err) 530 continue 531 } 532 if got := string(ri.slurp); got != tt.body { 533 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)) 534 } 535 wantLen := int64(len(tt.body)) 536 if tt.noContentLen && tt.body != "" { 537 wantLen = -1 538 } 539 if ri.req.ContentLength != wantLen { 540 t.Errorf("#%d. handler got ContentLength = %v; want %v", i, ri.req.ContentLength, wantLen) 541 } 542 } 543 } 544 545 func shortString(v string) string { 546 const maxLen = 100 547 if len(v) <= maxLen { 548 return v 549 } 550 return fmt.Sprintf("%v[...%d bytes omitted...]%v", v[:maxLen/2], len(v)-maxLen, v[len(v)-maxLen/2:]) 551 } 552 553 func TestTransportDialTLS(t *testing.T) { 554 var mu sync.Mutex // guards following 555 var gotReq, didDial bool 556 557 ts := newServerTester(t, 558 func(w http.ResponseWriter, r *http.Request) { 559 mu.Lock() 560 gotReq = true 561 mu.Unlock() 562 }, 563 optOnlyServer, 564 ) 565 defer ts.Close() 566 tr := &Transport{ 567 DialTLS: func(netw, addr string, cfg *tls.Config) (net.Conn, error) { 568 mu.Lock() 569 didDial = true 570 mu.Unlock() 571 cfg.InsecureSkipVerify = true 572 c, err := tls.Dial(netw, addr, cfg) 573 if err != nil { 574 return nil, err 575 } 576 return c, c.Handshake() 577 }, 578 } 579 defer tr.CloseIdleConnections() 580 client := &http.Client{Transport: tr} 581 res, err := client.Get(ts.ts.URL) 582 if err != nil { 583 t.Fatal(err) 584 } 585 res.Body.Close() 586 mu.Lock() 587 if !gotReq { 588 t.Error("didn't get request") 589 } 590 if !didDial { 591 t.Error("didn't use dial hook") 592 } 593 } 594 595 func TestConfigureTransport(t *testing.T) { 596 t1 := &http.Transport{} 597 err := ConfigureTransport(t1) 598 if err != nil { 599 t.Fatal(err) 600 } 601 if got := fmt.Sprintf("%#v", t1); !strings.Contains(got, `"h2"`) { 602 // Laziness, to avoid buildtags. 603 t.Errorf("stringification of HTTP/1 transport didn't contain \"h2\": %v", got) 604 } 605 wantNextProtos := []string{"h2", "http/1.1"} 606 if t1.TLSClientConfig == nil { 607 t.Errorf("nil t1.TLSClientConfig") 608 } else if !reflect.DeepEqual(t1.TLSClientConfig.NextProtos, wantNextProtos) { 609 t.Errorf("TLSClientConfig.NextProtos = %q; want %q", t1.TLSClientConfig.NextProtos, wantNextProtos) 610 } 611 if err := ConfigureTransport(t1); err == nil { 612 t.Error("unexpected success on second call to ConfigureTransport") 613 } 614 615 // And does it work? 616 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 617 io.WriteString(w, r.Proto) 618 }, optOnlyServer) 619 defer st.Close() 620 621 t1.TLSClientConfig.InsecureSkipVerify = true 622 c := &http.Client{Transport: t1} 623 res, err := c.Get(st.ts.URL) 624 if err != nil { 625 t.Fatal(err) 626 } 627 slurp, err := ioutil.ReadAll(res.Body) 628 if err != nil { 629 t.Fatal(err) 630 } 631 if got, want := string(slurp), "HTTP/2.0"; got != want { 632 t.Errorf("body = %q; want %q", got, want) 633 } 634 } 635 636 type capitalizeReader struct { 637 r io.Reader 638 } 639 640 func (cr capitalizeReader) Read(p []byte) (n int, err error) { 641 n, err = cr.r.Read(p) 642 for i, b := range p[:n] { 643 if b >= 'a' && b <= 'z' { 644 p[i] = b - ('a' - 'A') 645 } 646 } 647 return 648 } 649 650 type flushWriter struct { 651 w io.Writer 652 } 653 654 func (fw flushWriter) Write(p []byte) (n int, err error) { 655 n, err = fw.w.Write(p) 656 if f, ok := fw.w.(http.Flusher); ok { 657 f.Flush() 658 } 659 return 660 } 661 662 type clientTester struct { 663 t *testing.T 664 tr *Transport 665 sc, cc net.Conn // server and client conn 666 fr *Framer // server's framer 667 client func() error 668 server func() error 669 } 670 671 func newClientTester(t *testing.T) *clientTester { 672 var dialOnce struct { 673 sync.Mutex 674 dialed bool 675 } 676 ct := &clientTester{ 677 t: t, 678 } 679 ct.tr = &Transport{ 680 TLSClientConfig: tlsConfigInsecure, 681 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 682 dialOnce.Lock() 683 defer dialOnce.Unlock() 684 if dialOnce.dialed { 685 return nil, errors.New("only one dial allowed in test mode") 686 } 687 dialOnce.dialed = true 688 return ct.cc, nil 689 }, 690 } 691 692 ln := newLocalListener(t) 693 cc, err := net.Dial("tcp", ln.Addr().String()) 694 if err != nil { 695 t.Fatal(err) 696 697 } 698 sc, err := ln.Accept() 699 if err != nil { 700 t.Fatal(err) 701 } 702 ln.Close() 703 ct.cc = cc 704 ct.sc = sc 705 ct.fr = NewFramer(sc, sc) 706 return ct 707 } 708 709 func newLocalListener(t *testing.T) net.Listener { 710 ln, err := net.Listen("tcp4", "127.0.0.1:0") 711 if err == nil { 712 return ln 713 } 714 ln, err = net.Listen("tcp6", "[::1]:0") 715 if err != nil { 716 t.Fatal(err) 717 } 718 return ln 719 } 720 721 func (ct *clientTester) greet(settings ...Setting) { 722 buf := make([]byte, len(ClientPreface)) 723 _, err := io.ReadFull(ct.sc, buf) 724 if err != nil { 725 ct.t.Fatalf("reading client preface: %v", err) 726 } 727 f, err := ct.fr.ReadFrame() 728 if err != nil { 729 ct.t.Fatalf("Reading client settings frame: %v", err) 730 } 731 if sf, ok := f.(*SettingsFrame); !ok { 732 ct.t.Fatalf("Wanted client settings frame; got %v", f) 733 _ = sf // stash it away? 734 } 735 if err := ct.fr.WriteSettings(settings...); err != nil { 736 ct.t.Fatal(err) 737 } 738 if err := ct.fr.WriteSettingsAck(); err != nil { 739 ct.t.Fatal(err) 740 } 741 } 742 743 func (ct *clientTester) readNonSettingsFrame() (Frame, error) { 744 for { 745 f, err := ct.fr.ReadFrame() 746 if err != nil { 747 return nil, err 748 } 749 if _, ok := f.(*SettingsFrame); ok { 750 continue 751 } 752 return f, nil 753 } 754 } 755 756 func (ct *clientTester) cleanup() { 757 ct.tr.CloseIdleConnections() 758 } 759 760 func (ct *clientTester) run() { 761 errc := make(chan error, 2) 762 ct.start("client", errc, ct.client) 763 ct.start("server", errc, ct.server) 764 defer ct.cleanup() 765 for i := 0; i < 2; i++ { 766 if err := <-errc; err != nil { 767 ct.t.Error(err) 768 return 769 } 770 } 771 } 772 773 func (ct *clientTester) start(which string, errc chan<- error, fn func() error) { 774 go func() { 775 finished := false 776 var err error 777 defer func() { 778 if !finished { 779 err = fmt.Errorf("%s goroutine didn't finish.", which) 780 } else if err != nil { 781 err = fmt.Errorf("%s: %v", which, err) 782 } 783 errc <- err 784 }() 785 err = fn() 786 finished = true 787 }() 788 } 789 790 func (ct *clientTester) readFrame() (Frame, error) { 791 return readFrameTimeout(ct.fr, 2*time.Second) 792 } 793 794 func (ct *clientTester) firstHeaders() (*HeadersFrame, error) { 795 for { 796 f, err := ct.readFrame() 797 if err != nil { 798 return nil, fmt.Errorf("ReadFrame while waiting for Headers: %v", err) 799 } 800 switch f.(type) { 801 case *WindowUpdateFrame, *SettingsFrame: 802 continue 803 } 804 hf, ok := f.(*HeadersFrame) 805 if !ok { 806 return nil, fmt.Errorf("Got %T; want HeadersFrame", f) 807 } 808 return hf, nil 809 } 810 } 811 812 type countingReader struct { 813 n *int64 814 } 815 816 func (r countingReader) Read(p []byte) (n int, err error) { 817 for i := range p { 818 p[i] = byte(i) 819 } 820 atomic.AddInt64(r.n, int64(len(p))) 821 return len(p), err 822 } 823 824 func TestTransportReqBodyAfterResponse_200(t *testing.T) { testTransportReqBodyAfterResponse(t, 200) } 825 func TestTransportReqBodyAfterResponse_403(t *testing.T) { testTransportReqBodyAfterResponse(t, 403) } 826 827 func testTransportReqBodyAfterResponse(t *testing.T, status int) { 828 const bodySize = 10 << 20 829 clientDone := make(chan struct{}) 830 ct := newClientTester(t) 831 ct.client = func() error { 832 defer ct.cc.(*net.TCPConn).CloseWrite() 833 defer close(clientDone) 834 835 var n int64 // atomic 836 req, err := http.NewRequest("PUT", "https://dummy.tld/", io.LimitReader(countingReader{&n}, bodySize)) 837 if err != nil { 838 return err 839 } 840 res, err := ct.tr.RoundTrip(req) 841 if err != nil { 842 return fmt.Errorf("RoundTrip: %v", err) 843 } 844 defer res.Body.Close() 845 if res.StatusCode != status { 846 return fmt.Errorf("status code = %v; want %v", res.StatusCode, status) 847 } 848 slurp, err := ioutil.ReadAll(res.Body) 849 if err != nil { 850 return fmt.Errorf("Slurp: %v", err) 851 } 852 if len(slurp) > 0 { 853 return fmt.Errorf("unexpected body: %q", slurp) 854 } 855 if status == 200 { 856 if got := atomic.LoadInt64(&n); got != bodySize { 857 return fmt.Errorf("For 200 response, Transport wrote %d bytes; want %d", got, bodySize) 858 } 859 } else { 860 if got := atomic.LoadInt64(&n); got == 0 || got >= bodySize { 861 return fmt.Errorf("For %d response, Transport wrote %d bytes; want (0,%d) exclusive", status, got, bodySize) 862 } 863 } 864 return nil 865 } 866 ct.server = func() error { 867 ct.greet() 868 var buf bytes.Buffer 869 enc := hpack.NewEncoder(&buf) 870 var dataRecv int64 871 var closed bool 872 for { 873 f, err := ct.fr.ReadFrame() 874 if err != nil { 875 select { 876 case <-clientDone: 877 // If the client's done, it 878 // will have reported any 879 // errors on its side. 880 return nil 881 default: 882 return err 883 } 884 } 885 //println(fmt.Sprintf("server got frame: %v", f)) 886 switch f := f.(type) { 887 case *WindowUpdateFrame, *SettingsFrame: 888 case *HeadersFrame: 889 if !f.HeadersEnded() { 890 return fmt.Errorf("headers should have END_HEADERS be ended: %v", f) 891 } 892 if f.StreamEnded() { 893 return fmt.Errorf("headers contains END_STREAM unexpectedly: %v", f) 894 } 895 case *DataFrame: 896 dataLen := len(f.Data()) 897 if dataLen > 0 { 898 if dataRecv == 0 { 899 enc.WriteField(hpack.HeaderField{Name: ":status", Value: strconv.Itoa(status)}) 900 ct.fr.WriteHeaders(HeadersFrameParam{ 901 StreamID: f.StreamID, 902 EndHeaders: true, 903 EndStream: false, 904 BlockFragment: buf.Bytes(), 905 }) 906 } 907 if err := ct.fr.WriteWindowUpdate(0, uint32(dataLen)); err != nil { 908 return err 909 } 910 if err := ct.fr.WriteWindowUpdate(f.StreamID, uint32(dataLen)); err != nil { 911 return err 912 } 913 } 914 dataRecv += int64(dataLen) 915 916 if !closed && ((status != 200 && dataRecv > 0) || 917 (status == 200 && dataRecv == bodySize)) { 918 closed = true 919 if err := ct.fr.WriteData(f.StreamID, true, nil); err != nil { 920 return err 921 } 922 } 923 default: 924 return fmt.Errorf("Unexpected client frame %v", f) 925 } 926 } 927 } 928 ct.run() 929 } 930 931 // See golang.org/issue/13444 932 func TestTransportFullDuplex(t *testing.T) { 933 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 934 w.WriteHeader(200) // redundant but for clarity 935 w.(http.Flusher).Flush() 936 io.Copy(flushWriter{w}, capitalizeReader{r.Body}) 937 fmt.Fprintf(w, "bye.\n") 938 }, optOnlyServer) 939 defer st.Close() 940 941 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 942 defer tr.CloseIdleConnections() 943 c := &http.Client{Transport: tr} 944 945 pr, pw := io.Pipe() 946 req, err := http.NewRequest("PUT", st.ts.URL, ioutil.NopCloser(pr)) 947 if err != nil { 948 t.Fatal(err) 949 } 950 req.ContentLength = -1 951 res, err := c.Do(req) 952 if err != nil { 953 t.Fatal(err) 954 } 955 defer res.Body.Close() 956 if res.StatusCode != 200 { 957 t.Fatalf("StatusCode = %v; want %v", res.StatusCode, 200) 958 } 959 bs := bufio.NewScanner(res.Body) 960 want := func(v string) { 961 if !bs.Scan() { 962 t.Fatalf("wanted to read %q but Scan() = false, err = %v", v, bs.Err()) 963 } 964 } 965 write := func(v string) { 966 _, err := io.WriteString(pw, v) 967 if err != nil { 968 t.Fatalf("pipe write: %v", err) 969 } 970 } 971 write("foo\n") 972 want("FOO") 973 write("bar\n") 974 want("BAR") 975 pw.Close() 976 want("bye.") 977 if err := bs.Err(); err != nil { 978 t.Fatal(err) 979 } 980 } 981 982 func TestTransportConnectRequest(t *testing.T) { 983 gotc := make(chan *http.Request, 1) 984 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 985 gotc <- r 986 }, optOnlyServer) 987 defer st.Close() 988 989 u, err := url.Parse(st.ts.URL) 990 if err != nil { 991 t.Fatal(err) 992 } 993 994 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 995 defer tr.CloseIdleConnections() 996 c := &http.Client{Transport: tr} 997 998 tests := []struct { 999 req *http.Request 1000 want string 1001 }{ 1002 { 1003 req: &http.Request{ 1004 Method: "CONNECT", 1005 Header: http.Header{}, 1006 URL: u, 1007 }, 1008 want: u.Host, 1009 }, 1010 { 1011 req: &http.Request{ 1012 Method: "CONNECT", 1013 Header: http.Header{}, 1014 URL: u, 1015 Host: "example.com:123", 1016 }, 1017 want: "example.com:123", 1018 }, 1019 } 1020 1021 for i, tt := range tests { 1022 res, err := c.Do(tt.req) 1023 if err != nil { 1024 t.Errorf("%d. RoundTrip = %v", i, err) 1025 continue 1026 } 1027 res.Body.Close() 1028 req := <-gotc 1029 if req.Method != "CONNECT" { 1030 t.Errorf("method = %q; want CONNECT", req.Method) 1031 } 1032 if req.Host != tt.want { 1033 t.Errorf("Host = %q; want %q", req.Host, tt.want) 1034 } 1035 if req.URL.Host != tt.want { 1036 t.Errorf("URL.Host = %q; want %q", req.URL.Host, tt.want) 1037 } 1038 } 1039 } 1040 1041 type headerType int 1042 1043 const ( 1044 noHeader headerType = iota // omitted 1045 oneHeader 1046 splitHeader // broken into continuation on purpose 1047 ) 1048 1049 const ( 1050 f0 = noHeader 1051 f1 = oneHeader 1052 f2 = splitHeader 1053 d0 = false 1054 d1 = true 1055 ) 1056 1057 // Test all 36 combinations of response frame orders: 1058 // (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) } 1059 // Generated by http://play.golang.org/p/SScqYKJYXd 1060 func TestTransportResPattern_c0h1d0t0(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f0) } 1061 func TestTransportResPattern_c0h1d0t1(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f1) } 1062 func TestTransportResPattern_c0h1d0t2(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f2) } 1063 func TestTransportResPattern_c0h1d1t0(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f0) } 1064 func TestTransportResPattern_c0h1d1t1(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f1) } 1065 func TestTransportResPattern_c0h1d1t2(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f2) } 1066 func TestTransportResPattern_c0h2d0t0(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f0) } 1067 func TestTransportResPattern_c0h2d0t1(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f1) } 1068 func TestTransportResPattern_c0h2d0t2(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f2) } 1069 func TestTransportResPattern_c0h2d1t0(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f0) } 1070 func TestTransportResPattern_c0h2d1t1(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f1) } 1071 func TestTransportResPattern_c0h2d1t2(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f2) } 1072 func TestTransportResPattern_c1h1d0t0(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f0) } 1073 func TestTransportResPattern_c1h1d0t1(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f1) } 1074 func TestTransportResPattern_c1h1d0t2(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f2) } 1075 func TestTransportResPattern_c1h1d1t0(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f0) } 1076 func TestTransportResPattern_c1h1d1t1(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f1) } 1077 func TestTransportResPattern_c1h1d1t2(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f2) } 1078 func TestTransportResPattern_c1h2d0t0(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f0) } 1079 func TestTransportResPattern_c1h2d0t1(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f1) } 1080 func TestTransportResPattern_c1h2d0t2(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f2) } 1081 func TestTransportResPattern_c1h2d1t0(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f0) } 1082 func TestTransportResPattern_c1h2d1t1(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f1) } 1083 func TestTransportResPattern_c1h2d1t2(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f2) } 1084 func TestTransportResPattern_c2h1d0t0(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f0) } 1085 func TestTransportResPattern_c2h1d0t1(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f1) } 1086 func TestTransportResPattern_c2h1d0t2(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f2) } 1087 func TestTransportResPattern_c2h1d1t0(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f0) } 1088 func TestTransportResPattern_c2h1d1t1(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f1) } 1089 func TestTransportResPattern_c2h1d1t2(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f2) } 1090 func TestTransportResPattern_c2h2d0t0(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f0) } 1091 func TestTransportResPattern_c2h2d0t1(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f1) } 1092 func TestTransportResPattern_c2h2d0t2(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f2) } 1093 func TestTransportResPattern_c2h2d1t0(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f0) } 1094 func TestTransportResPattern_c2h2d1t1(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f1) } 1095 func TestTransportResPattern_c2h2d1t2(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f2) } 1096 1097 func testTransportResPattern(t *testing.T, expect100Continue, resHeader headerType, withData bool, trailers headerType) { 1098 const reqBody = "some request body" 1099 const resBody = "some response body" 1100 1101 if resHeader == noHeader { 1102 // TODO: test 100-continue followed by immediate 1103 // server stream reset, without headers in the middle? 1104 panic("invalid combination") 1105 } 1106 1107 ct := newClientTester(t) 1108 ct.client = func() error { 1109 req, _ := http.NewRequest("POST", "https://dummy.tld/", strings.NewReader(reqBody)) 1110 if expect100Continue != noHeader { 1111 req.Header.Set("Expect", "100-continue") 1112 } 1113 res, err := ct.tr.RoundTrip(req) 1114 if err != nil { 1115 return fmt.Errorf("RoundTrip: %v", err) 1116 } 1117 defer res.Body.Close() 1118 if res.StatusCode != 200 { 1119 return fmt.Errorf("status code = %v; want 200", res.StatusCode) 1120 } 1121 slurp, err := ioutil.ReadAll(res.Body) 1122 if err != nil { 1123 return fmt.Errorf("Slurp: %v", err) 1124 } 1125 wantBody := resBody 1126 if !withData { 1127 wantBody = "" 1128 } 1129 if string(slurp) != wantBody { 1130 return fmt.Errorf("body = %q; want %q", slurp, wantBody) 1131 } 1132 if trailers == noHeader { 1133 if len(res.Trailer) > 0 { 1134 t.Errorf("Trailer = %v; want none", res.Trailer) 1135 } 1136 } else { 1137 want := http.Header{"Some-Trailer": {"some-value"}} 1138 if !reflect.DeepEqual(res.Trailer, want) { 1139 t.Errorf("Trailer = %v; want %v", res.Trailer, want) 1140 } 1141 } 1142 return nil 1143 } 1144 ct.server = func() error { 1145 ct.greet() 1146 var buf bytes.Buffer 1147 enc := hpack.NewEncoder(&buf) 1148 1149 for { 1150 f, err := ct.fr.ReadFrame() 1151 if err != nil { 1152 return err 1153 } 1154 endStream := false 1155 send := func(mode headerType) { 1156 hbf := buf.Bytes() 1157 switch mode { 1158 case oneHeader: 1159 ct.fr.WriteHeaders(HeadersFrameParam{ 1160 StreamID: f.Header().StreamID, 1161 EndHeaders: true, 1162 EndStream: endStream, 1163 BlockFragment: hbf, 1164 }) 1165 case splitHeader: 1166 if len(hbf) < 2 { 1167 panic("too small") 1168 } 1169 ct.fr.WriteHeaders(HeadersFrameParam{ 1170 StreamID: f.Header().StreamID, 1171 EndHeaders: false, 1172 EndStream: endStream, 1173 BlockFragment: hbf[:1], 1174 }) 1175 ct.fr.WriteContinuation(f.Header().StreamID, true, hbf[1:]) 1176 default: 1177 panic("bogus mode") 1178 } 1179 } 1180 switch f := f.(type) { 1181 case *WindowUpdateFrame, *SettingsFrame: 1182 case *DataFrame: 1183 if !f.StreamEnded() { 1184 // No need to send flow control tokens. The test request body is tiny. 1185 continue 1186 } 1187 // Response headers (1+ frames; 1 or 2 in this test, but never 0) 1188 { 1189 buf.Reset() 1190 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 1191 enc.WriteField(hpack.HeaderField{Name: "x-foo", Value: "blah"}) 1192 enc.WriteField(hpack.HeaderField{Name: "x-bar", Value: "more"}) 1193 if trailers != noHeader { 1194 enc.WriteField(hpack.HeaderField{Name: "trailer", Value: "some-trailer"}) 1195 } 1196 endStream = withData == false && trailers == noHeader 1197 send(resHeader) 1198 } 1199 if withData { 1200 endStream = trailers == noHeader 1201 ct.fr.WriteData(f.StreamID, endStream, []byte(resBody)) 1202 } 1203 if trailers != noHeader { 1204 endStream = true 1205 buf.Reset() 1206 enc.WriteField(hpack.HeaderField{Name: "some-trailer", Value: "some-value"}) 1207 send(trailers) 1208 } 1209 if endStream { 1210 return nil 1211 } 1212 case *HeadersFrame: 1213 if expect100Continue != noHeader { 1214 buf.Reset() 1215 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "100"}) 1216 send(expect100Continue) 1217 } 1218 } 1219 } 1220 } 1221 ct.run() 1222 } 1223 1224 // Issue 26189, Issue 17739: ignore unknown 1xx responses 1225 func TestTransportUnknown1xx(t *testing.T) { 1226 var buf bytes.Buffer 1227 defer func() { got1xxFuncForTests = nil }() 1228 got1xxFuncForTests = func(code int, header textproto.MIMEHeader) error { 1229 fmt.Fprintf(&buf, "code=%d header=%v\n", code, header) 1230 return nil 1231 } 1232 1233 ct := newClientTester(t) 1234 ct.client = func() error { 1235 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 1236 res, err := ct.tr.RoundTrip(req) 1237 if err != nil { 1238 return fmt.Errorf("RoundTrip: %v", err) 1239 } 1240 defer res.Body.Close() 1241 if res.StatusCode != 204 { 1242 return fmt.Errorf("status code = %v; want 204", res.StatusCode) 1243 } 1244 want := `code=110 header=map[Foo-Bar:[110]] 1245 code=111 header=map[Foo-Bar:[111]] 1246 code=112 header=map[Foo-Bar:[112]] 1247 code=113 header=map[Foo-Bar:[113]] 1248 code=114 header=map[Foo-Bar:[114]] 1249 ` 1250 if got := buf.String(); got != want { 1251 t.Errorf("Got trace:\n%s\nWant:\n%s", got, want) 1252 } 1253 return nil 1254 } 1255 ct.server = func() error { 1256 ct.greet() 1257 var buf bytes.Buffer 1258 enc := hpack.NewEncoder(&buf) 1259 1260 for { 1261 f, err := ct.fr.ReadFrame() 1262 if err != nil { 1263 return err 1264 } 1265 switch f := f.(type) { 1266 case *WindowUpdateFrame, *SettingsFrame: 1267 case *HeadersFrame: 1268 for i := 110; i <= 114; i++ { 1269 buf.Reset() 1270 enc.WriteField(hpack.HeaderField{Name: ":status", Value: fmt.Sprint(i)}) 1271 enc.WriteField(hpack.HeaderField{Name: "foo-bar", Value: fmt.Sprint(i)}) 1272 ct.fr.WriteHeaders(HeadersFrameParam{ 1273 StreamID: f.StreamID, 1274 EndHeaders: true, 1275 EndStream: false, 1276 BlockFragment: buf.Bytes(), 1277 }) 1278 } 1279 buf.Reset() 1280 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "204"}) 1281 ct.fr.WriteHeaders(HeadersFrameParam{ 1282 StreamID: f.StreamID, 1283 EndHeaders: true, 1284 EndStream: false, 1285 BlockFragment: buf.Bytes(), 1286 }) 1287 return nil 1288 } 1289 } 1290 } 1291 ct.run() 1292 1293 } 1294 1295 func TestTransportReceiveUndeclaredTrailer(t *testing.T) { 1296 ct := newClientTester(t) 1297 ct.client = func() error { 1298 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 1299 res, err := ct.tr.RoundTrip(req) 1300 if err != nil { 1301 return fmt.Errorf("RoundTrip: %v", err) 1302 } 1303 defer res.Body.Close() 1304 if res.StatusCode != 200 { 1305 return fmt.Errorf("status code = %v; want 200", res.StatusCode) 1306 } 1307 slurp, err := ioutil.ReadAll(res.Body) 1308 if err != nil { 1309 return fmt.Errorf("res.Body ReadAll error = %q, %v; want %v", slurp, err, nil) 1310 } 1311 if len(slurp) > 0 { 1312 return fmt.Errorf("body = %q; want nothing", slurp) 1313 } 1314 if _, ok := res.Trailer["Some-Trailer"]; !ok { 1315 return fmt.Errorf("expected Some-Trailer") 1316 } 1317 return nil 1318 } 1319 ct.server = func() error { 1320 ct.greet() 1321 1322 var n int 1323 var hf *HeadersFrame 1324 for hf == nil && n < 10 { 1325 f, err := ct.fr.ReadFrame() 1326 if err != nil { 1327 return err 1328 } 1329 hf, _ = f.(*HeadersFrame) 1330 n++ 1331 } 1332 1333 var buf bytes.Buffer 1334 enc := hpack.NewEncoder(&buf) 1335 1336 // send headers without Trailer header 1337 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 1338 ct.fr.WriteHeaders(HeadersFrameParam{ 1339 StreamID: hf.StreamID, 1340 EndHeaders: true, 1341 EndStream: false, 1342 BlockFragment: buf.Bytes(), 1343 }) 1344 1345 // send trailers 1346 buf.Reset() 1347 enc.WriteField(hpack.HeaderField{Name: "some-trailer", Value: "I'm an undeclared Trailer!"}) 1348 ct.fr.WriteHeaders(HeadersFrameParam{ 1349 StreamID: hf.StreamID, 1350 EndHeaders: true, 1351 EndStream: true, 1352 BlockFragment: buf.Bytes(), 1353 }) 1354 return nil 1355 } 1356 ct.run() 1357 } 1358 1359 func TestTransportInvalidTrailer_Pseudo1(t *testing.T) { 1360 testTransportInvalidTrailer_Pseudo(t, oneHeader) 1361 } 1362 func TestTransportInvalidTrailer_Pseudo2(t *testing.T) { 1363 testTransportInvalidTrailer_Pseudo(t, splitHeader) 1364 } 1365 func testTransportInvalidTrailer_Pseudo(t *testing.T, trailers headerType) { 1366 testInvalidTrailer(t, trailers, pseudoHeaderError(":colon"), func(enc *hpack.Encoder) { 1367 enc.WriteField(hpack.HeaderField{Name: ":colon", Value: "foo"}) 1368 enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"}) 1369 }) 1370 } 1371 1372 func TestTransportInvalidTrailer_Capital1(t *testing.T) { 1373 testTransportInvalidTrailer_Capital(t, oneHeader) 1374 } 1375 func TestTransportInvalidTrailer_Capital2(t *testing.T) { 1376 testTransportInvalidTrailer_Capital(t, splitHeader) 1377 } 1378 func testTransportInvalidTrailer_Capital(t *testing.T, trailers headerType) { 1379 testInvalidTrailer(t, trailers, headerFieldNameError("Capital"), func(enc *hpack.Encoder) { 1380 enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"}) 1381 enc.WriteField(hpack.HeaderField{Name: "Capital", Value: "bad"}) 1382 }) 1383 } 1384 func TestTransportInvalidTrailer_EmptyFieldName(t *testing.T) { 1385 testInvalidTrailer(t, oneHeader, headerFieldNameError(""), func(enc *hpack.Encoder) { 1386 enc.WriteField(hpack.HeaderField{Name: "", Value: "bad"}) 1387 }) 1388 } 1389 func TestTransportInvalidTrailer_BinaryFieldValue(t *testing.T) { 1390 testInvalidTrailer(t, oneHeader, headerFieldValueError("has\nnewline"), func(enc *hpack.Encoder) { 1391 enc.WriteField(hpack.HeaderField{Name: "x", Value: "has\nnewline"}) 1392 }) 1393 } 1394 1395 func testInvalidTrailer(t *testing.T, trailers headerType, wantErr error, writeTrailer func(*hpack.Encoder)) { 1396 ct := newClientTester(t) 1397 ct.client = func() error { 1398 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 1399 res, err := ct.tr.RoundTrip(req) 1400 if err != nil { 1401 return fmt.Errorf("RoundTrip: %v", err) 1402 } 1403 defer res.Body.Close() 1404 if res.StatusCode != 200 { 1405 return fmt.Errorf("status code = %v; want 200", res.StatusCode) 1406 } 1407 slurp, err := ioutil.ReadAll(res.Body) 1408 se, ok := err.(StreamError) 1409 if !ok || se.Cause != wantErr { 1410 return fmt.Errorf("res.Body ReadAll error = %q, %#v; want StreamError with cause %T, %#v", slurp, err, wantErr, wantErr) 1411 } 1412 if len(slurp) > 0 { 1413 return fmt.Errorf("body = %q; want nothing", slurp) 1414 } 1415 return nil 1416 } 1417 ct.server = func() error { 1418 ct.greet() 1419 var buf bytes.Buffer 1420 enc := hpack.NewEncoder(&buf) 1421 1422 for { 1423 f, err := ct.fr.ReadFrame() 1424 if err != nil { 1425 return err 1426 } 1427 switch f := f.(type) { 1428 case *HeadersFrame: 1429 var endStream bool 1430 send := func(mode headerType) { 1431 hbf := buf.Bytes() 1432 switch mode { 1433 case oneHeader: 1434 ct.fr.WriteHeaders(HeadersFrameParam{ 1435 StreamID: f.StreamID, 1436 EndHeaders: true, 1437 EndStream: endStream, 1438 BlockFragment: hbf, 1439 }) 1440 case splitHeader: 1441 if len(hbf) < 2 { 1442 panic("too small") 1443 } 1444 ct.fr.WriteHeaders(HeadersFrameParam{ 1445 StreamID: f.StreamID, 1446 EndHeaders: false, 1447 EndStream: endStream, 1448 BlockFragment: hbf[:1], 1449 }) 1450 ct.fr.WriteContinuation(f.StreamID, true, hbf[1:]) 1451 default: 1452 panic("bogus mode") 1453 } 1454 } 1455 // Response headers (1+ frames; 1 or 2 in this test, but never 0) 1456 { 1457 buf.Reset() 1458 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 1459 enc.WriteField(hpack.HeaderField{Name: "trailer", Value: "declared"}) 1460 endStream = false 1461 send(oneHeader) 1462 } 1463 // Trailers: 1464 { 1465 endStream = true 1466 buf.Reset() 1467 writeTrailer(enc) 1468 send(trailers) 1469 } 1470 return nil 1471 } 1472 } 1473 } 1474 ct.run() 1475 } 1476 1477 // headerListSize returns the HTTP2 header list size of h. 1478 // http://httpwg.org/specs/rfc7540.html#SETTINGS_MAX_HEADER_LIST_SIZE 1479 // http://httpwg.org/specs/rfc7540.html#MaxHeaderBlock 1480 func headerListSize(h http.Header) (size uint32) { 1481 for k, vv := range h { 1482 for _, v := range vv { 1483 hf := hpack.HeaderField{Name: k, Value: v} 1484 size += hf.Size() 1485 } 1486 } 1487 return size 1488 } 1489 1490 // padHeaders adds data to an http.Header until headerListSize(h) == 1491 // limit. Due to the way header list sizes are calculated, padHeaders 1492 // cannot add fewer than len("Pad-Headers") + 32 bytes to h, and will 1493 // call t.Fatal if asked to do so. PadHeaders first reserves enough 1494 // space for an empty "Pad-Headers" key, then adds as many copies of 1495 // filler as possible. Any remaining bytes necessary to push the 1496 // header list size up to limit are added to h["Pad-Headers"]. 1497 func padHeaders(t *testing.T, h http.Header, limit uint64, filler string) { 1498 if limit > 0xffffffff { 1499 t.Fatalf("padHeaders: refusing to pad to more than 2^32-1 bytes. limit = %v", limit) 1500 } 1501 hf := hpack.HeaderField{Name: "Pad-Headers", Value: ""} 1502 minPadding := uint64(hf.Size()) 1503 size := uint64(headerListSize(h)) 1504 1505 minlimit := size + minPadding 1506 if limit < minlimit { 1507 t.Fatalf("padHeaders: limit %v < %v", limit, minlimit) 1508 } 1509 1510 // Use a fixed-width format for name so that fieldSize 1511 // remains constant. 1512 nameFmt := "Pad-Headers-%06d" 1513 hf = hpack.HeaderField{Name: fmt.Sprintf(nameFmt, 1), Value: filler} 1514 fieldSize := uint64(hf.Size()) 1515 1516 // Add as many complete filler values as possible, leaving 1517 // room for at least one empty "Pad-Headers" key. 1518 limit = limit - minPadding 1519 for i := 0; size+fieldSize < limit; i++ { 1520 name := fmt.Sprintf(nameFmt, i) 1521 h.Add(name, filler) 1522 size += fieldSize 1523 } 1524 1525 // Add enough bytes to reach limit. 1526 remain := limit - size 1527 lastValue := strings.Repeat("*", int(remain)) 1528 h.Add("Pad-Headers", lastValue) 1529 } 1530 1531 func TestPadHeaders(t *testing.T) { 1532 check := func(h http.Header, limit uint32, fillerLen int) { 1533 if h == nil { 1534 h = make(http.Header) 1535 } 1536 filler := strings.Repeat("f", fillerLen) 1537 padHeaders(t, h, uint64(limit), filler) 1538 gotSize := headerListSize(h) 1539 if gotSize != limit { 1540 t.Errorf("Got size = %v; want %v", gotSize, limit) 1541 } 1542 } 1543 // Try all possible combinations for small fillerLen and limit. 1544 hf := hpack.HeaderField{Name: "Pad-Headers", Value: ""} 1545 minLimit := hf.Size() 1546 for limit := minLimit; limit <= 128; limit++ { 1547 for fillerLen := 0; uint32(fillerLen) <= limit; fillerLen++ { 1548 check(nil, limit, fillerLen) 1549 } 1550 } 1551 1552 // Try a few tests with larger limits, plus cumulative 1553 // tests. Since these tests are cumulative, tests[i+1].limit 1554 // must be >= tests[i].limit + minLimit. See the comment on 1555 // padHeaders for more info on why the limit arg has this 1556 // restriction. 1557 tests := []struct { 1558 fillerLen int 1559 limit uint32 1560 }{ 1561 { 1562 fillerLen: 64, 1563 limit: 1024, 1564 }, 1565 { 1566 fillerLen: 1024, 1567 limit: 1286, 1568 }, 1569 { 1570 fillerLen: 256, 1571 limit: 2048, 1572 }, 1573 { 1574 fillerLen: 1024, 1575 limit: 10 * 1024, 1576 }, 1577 { 1578 fillerLen: 1023, 1579 limit: 11 * 1024, 1580 }, 1581 } 1582 h := make(http.Header) 1583 for _, tc := range tests { 1584 check(nil, tc.limit, tc.fillerLen) 1585 check(h, tc.limit, tc.fillerLen) 1586 } 1587 } 1588 1589 func TestTransportChecksRequestHeaderListSize(t *testing.T) { 1590 st := newServerTester(t, 1591 func(w http.ResponseWriter, r *http.Request) { 1592 // Consume body & force client to send 1593 // trailers before writing response. 1594 // ioutil.ReadAll returns non-nil err for 1595 // requests that attempt to send greater than 1596 // maxHeaderListSize bytes of trailers, since 1597 // those requests generate a stream reset. 1598 ioutil.ReadAll(r.Body) 1599 r.Body.Close() 1600 }, 1601 func(ts *httptest.Server) { 1602 ts.Config.MaxHeaderBytes = 16 << 10 1603 }, 1604 optOnlyServer, 1605 optQuiet, 1606 ) 1607 defer st.Close() 1608 1609 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 1610 defer tr.CloseIdleConnections() 1611 1612 checkRoundTrip := func(req *http.Request, wantErr error, desc string) { 1613 res, err := tr.RoundTrip(req) 1614 if err != wantErr { 1615 if res != nil { 1616 res.Body.Close() 1617 } 1618 t.Errorf("%v: RoundTrip err = %v; want %v", desc, err, wantErr) 1619 return 1620 } 1621 if err == nil { 1622 if res == nil { 1623 t.Errorf("%v: response nil; want non-nil.", desc) 1624 return 1625 } 1626 defer res.Body.Close() 1627 if res.StatusCode != http.StatusOK { 1628 t.Errorf("%v: response status = %v; want %v", desc, res.StatusCode, http.StatusOK) 1629 } 1630 return 1631 } 1632 if res != nil { 1633 t.Errorf("%v: RoundTrip err = %v but response non-nil", desc, err) 1634 } 1635 } 1636 headerListSizeForRequest := func(req *http.Request) (size uint64) { 1637 contentLen := actualContentLength(req) 1638 trailers, err := commaSeparatedTrailers(req) 1639 if err != nil { 1640 t.Fatalf("headerListSizeForRequest: %v", err) 1641 } 1642 cc := &ClientConn{peerMaxHeaderListSize: 0xffffffffffffffff} 1643 cc.henc = hpack.NewEncoder(&cc.hbuf) 1644 cc.mu.Lock() 1645 hdrs, err := cc.encodeHeaders(req, true, trailers, contentLen) 1646 cc.mu.Unlock() 1647 if err != nil { 1648 t.Fatalf("headerListSizeForRequest: %v", err) 1649 } 1650 hpackDec := hpack.NewDecoder(initialHeaderTableSize, func(hf hpack.HeaderField) { 1651 size += uint64(hf.Size()) 1652 }) 1653 if len(hdrs) > 0 { 1654 if _, err := hpackDec.Write(hdrs); err != nil { 1655 t.Fatalf("headerListSizeForRequest: %v", err) 1656 } 1657 } 1658 return size 1659 } 1660 // Create a new Request for each test, rather than reusing the 1661 // same Request, to avoid a race when modifying req.Headers. 1662 // See https://github.com/golang/go/issues/21316 1663 newRequest := func() *http.Request { 1664 // Body must be non-nil to enable writing trailers. 1665 body := strings.NewReader("hello") 1666 req, err := http.NewRequest("POST", st.ts.URL, body) 1667 if err != nil { 1668 t.Fatalf("newRequest: NewRequest: %v", err) 1669 } 1670 return req 1671 } 1672 1673 // Make an arbitrary request to ensure we get the server's 1674 // settings frame and initialize peerMaxHeaderListSize. 1675 req := newRequest() 1676 checkRoundTrip(req, nil, "Initial request") 1677 1678 // Get the ClientConn associated with the request and validate 1679 // peerMaxHeaderListSize. 1680 addr := authorityAddr(req.URL.Scheme, req.URL.Host) 1681 cc, err := tr.connPool().GetClientConn(req, addr) 1682 if err != nil { 1683 t.Fatalf("GetClientConn: %v", err) 1684 } 1685 cc.mu.Lock() 1686 peerSize := cc.peerMaxHeaderListSize 1687 cc.mu.Unlock() 1688 st.scMu.Lock() 1689 wantSize := uint64(st.sc.maxHeaderListSize()) 1690 st.scMu.Unlock() 1691 if peerSize != wantSize { 1692 t.Errorf("peerMaxHeaderListSize = %v; want %v", peerSize, wantSize) 1693 } 1694 1695 // Sanity check peerSize. (*serverConn) maxHeaderListSize adds 1696 // 320 bytes of padding. 1697 wantHeaderBytes := uint64(st.ts.Config.MaxHeaderBytes) + 320 1698 if peerSize != wantHeaderBytes { 1699 t.Errorf("peerMaxHeaderListSize = %v; want %v.", peerSize, wantHeaderBytes) 1700 } 1701 1702 // Pad headers & trailers, but stay under peerSize. 1703 req = newRequest() 1704 req.Header = make(http.Header) 1705 req.Trailer = make(http.Header) 1706 filler := strings.Repeat("*", 1024) 1707 padHeaders(t, req.Trailer, peerSize, filler) 1708 // cc.encodeHeaders adds some default headers to the request, 1709 // so we need to leave room for those. 1710 defaultBytes := headerListSizeForRequest(req) 1711 padHeaders(t, req.Header, peerSize-defaultBytes, filler) 1712 checkRoundTrip(req, nil, "Headers & Trailers under limit") 1713 1714 // Add enough header bytes to push us over peerSize. 1715 req = newRequest() 1716 req.Header = make(http.Header) 1717 padHeaders(t, req.Header, peerSize, filler) 1718 checkRoundTrip(req, errRequestHeaderListSize, "Headers over limit") 1719 1720 // Push trailers over the limit. 1721 req = newRequest() 1722 req.Trailer = make(http.Header) 1723 padHeaders(t, req.Trailer, peerSize+1, filler) 1724 checkRoundTrip(req, errRequestHeaderListSize, "Trailers over limit") 1725 1726 // Send headers with a single large value. 1727 req = newRequest() 1728 filler = strings.Repeat("*", int(peerSize)) 1729 req.Header = make(http.Header) 1730 req.Header.Set("Big", filler) 1731 checkRoundTrip(req, errRequestHeaderListSize, "Single large header") 1732 1733 // Send trailers with a single large value. 1734 req = newRequest() 1735 req.Trailer = make(http.Header) 1736 req.Trailer.Set("Big", filler) 1737 checkRoundTrip(req, errRequestHeaderListSize, "Single large trailer") 1738 } 1739 1740 func TestTransportChecksResponseHeaderListSize(t *testing.T) { 1741 ct := newClientTester(t) 1742 ct.client = func() error { 1743 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 1744 res, err := ct.tr.RoundTrip(req) 1745 if err != errResponseHeaderListSize { 1746 if res != nil { 1747 res.Body.Close() 1748 } 1749 size := int64(0) 1750 for k, vv := range res.Header { 1751 for _, v := range vv { 1752 size += int64(len(k)) + int64(len(v)) + 32 1753 } 1754 } 1755 return fmt.Errorf("RoundTrip Error = %v (and %d bytes of response headers); want errResponseHeaderListSize", err, size) 1756 } 1757 return nil 1758 } 1759 ct.server = func() error { 1760 ct.greet() 1761 var buf bytes.Buffer 1762 enc := hpack.NewEncoder(&buf) 1763 1764 for { 1765 f, err := ct.fr.ReadFrame() 1766 if err != nil { 1767 return err 1768 } 1769 switch f := f.(type) { 1770 case *HeadersFrame: 1771 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 1772 large := strings.Repeat("a", 1<<10) 1773 for i := 0; i < 5042; i++ { 1774 enc.WriteField(hpack.HeaderField{Name: large, Value: large}) 1775 } 1776 if size, want := buf.Len(), 6329; size != want { 1777 // Note: this number might change if 1778 // our hpack implementation 1779 // changes. That's fine. This is 1780 // just a sanity check that our 1781 // response can fit in a single 1782 // header block fragment frame. 1783 return fmt.Errorf("encoding over 10MB of duplicate keypairs took %d bytes; expected %d", size, want) 1784 } 1785 ct.fr.WriteHeaders(HeadersFrameParam{ 1786 StreamID: f.StreamID, 1787 EndHeaders: true, 1788 EndStream: true, 1789 BlockFragment: buf.Bytes(), 1790 }) 1791 return nil 1792 } 1793 } 1794 } 1795 ct.run() 1796 } 1797 1798 // Test that the Transport returns a typed error from Response.Body.Read calls 1799 // when the server sends an error. (here we use a panic, since that should generate 1800 // a stream error, but others like cancel should be similar) 1801 func TestTransportBodyReadErrorType(t *testing.T) { 1802 doPanic := make(chan bool, 1) 1803 st := newServerTester(t, 1804 func(w http.ResponseWriter, r *http.Request) { 1805 w.(http.Flusher).Flush() // force headers out 1806 <-doPanic 1807 panic("boom") 1808 }, 1809 optOnlyServer, 1810 optQuiet, 1811 ) 1812 defer st.Close() 1813 1814 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 1815 defer tr.CloseIdleConnections() 1816 c := &http.Client{Transport: tr} 1817 1818 res, err := c.Get(st.ts.URL) 1819 if err != nil { 1820 t.Fatal(err) 1821 } 1822 defer res.Body.Close() 1823 doPanic <- true 1824 buf := make([]byte, 100) 1825 n, err := res.Body.Read(buf) 1826 want := StreamError{StreamID: 0x1, Code: 0x2} 1827 if !reflect.DeepEqual(want, err) { 1828 t.Errorf("Read = %v, %#v; want error %#v", n, err, want) 1829 } 1830 } 1831 1832 // golang.org/issue/13924 1833 // This used to fail after many iterations, especially with -race: 1834 // go test -v -run=TestTransportDoubleCloseOnWriteError -count=500 -race 1835 func TestTransportDoubleCloseOnWriteError(t *testing.T) { 1836 var ( 1837 mu sync.Mutex 1838 conn net.Conn // to close if set 1839 ) 1840 1841 st := newServerTester(t, 1842 func(w http.ResponseWriter, r *http.Request) { 1843 mu.Lock() 1844 defer mu.Unlock() 1845 if conn != nil { 1846 conn.Close() 1847 } 1848 }, 1849 optOnlyServer, 1850 ) 1851 defer st.Close() 1852 1853 tr := &Transport{ 1854 TLSClientConfig: tlsConfigInsecure, 1855 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 1856 tc, err := tls.Dial(network, addr, cfg) 1857 if err != nil { 1858 return nil, err 1859 } 1860 mu.Lock() 1861 defer mu.Unlock() 1862 conn = tc 1863 return tc, nil 1864 }, 1865 } 1866 defer tr.CloseIdleConnections() 1867 c := &http.Client{Transport: tr} 1868 c.Get(st.ts.URL) 1869 } 1870 1871 // Test that the http1 Transport.DisableKeepAlives option is respected 1872 // and connections are closed as soon as idle. 1873 // See golang.org/issue/14008 1874 func TestTransportDisableKeepAlives(t *testing.T) { 1875 st := newServerTester(t, 1876 func(w http.ResponseWriter, r *http.Request) { 1877 io.WriteString(w, "hi") 1878 }, 1879 optOnlyServer, 1880 ) 1881 defer st.Close() 1882 1883 connClosed := make(chan struct{}) // closed on tls.Conn.Close 1884 tr := &Transport{ 1885 t1: &http.Transport{ 1886 DisableKeepAlives: true, 1887 }, 1888 TLSClientConfig: tlsConfigInsecure, 1889 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 1890 tc, err := tls.Dial(network, addr, cfg) 1891 if err != nil { 1892 return nil, err 1893 } 1894 return ¬eCloseConn{Conn: tc, closefn: func() { close(connClosed) }}, nil 1895 }, 1896 } 1897 c := &http.Client{Transport: tr} 1898 res, err := c.Get(st.ts.URL) 1899 if err != nil { 1900 t.Fatal(err) 1901 } 1902 if _, err := ioutil.ReadAll(res.Body); err != nil { 1903 t.Fatal(err) 1904 } 1905 defer res.Body.Close() 1906 1907 select { 1908 case <-connClosed: 1909 case <-time.After(1 * time.Second): 1910 t.Errorf("timeout") 1911 } 1912 1913 } 1914 1915 // Test concurrent requests with Transport.DisableKeepAlives. We can share connections, 1916 // but when things are totally idle, it still needs to close. 1917 func TestTransportDisableKeepAlives_Concurrency(t *testing.T) { 1918 const D = 25 * time.Millisecond 1919 st := newServerTester(t, 1920 func(w http.ResponseWriter, r *http.Request) { 1921 time.Sleep(D) 1922 io.WriteString(w, "hi") 1923 }, 1924 optOnlyServer, 1925 ) 1926 defer st.Close() 1927 1928 var dials int32 1929 var conns sync.WaitGroup 1930 tr := &Transport{ 1931 t1: &http.Transport{ 1932 DisableKeepAlives: true, 1933 }, 1934 TLSClientConfig: tlsConfigInsecure, 1935 DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { 1936 tc, err := tls.Dial(network, addr, cfg) 1937 if err != nil { 1938 return nil, err 1939 } 1940 atomic.AddInt32(&dials, 1) 1941 conns.Add(1) 1942 return ¬eCloseConn{Conn: tc, closefn: func() { conns.Done() }}, nil 1943 }, 1944 } 1945 c := &http.Client{Transport: tr} 1946 var reqs sync.WaitGroup 1947 const N = 20 1948 for i := 0; i < N; i++ { 1949 reqs.Add(1) 1950 if i == N-1 { 1951 // For the final request, try to make all the 1952 // others close. This isn't verified in the 1953 // count, other than the Log statement, since 1954 // it's so timing dependent. This test is 1955 // really to make sure we don't interrupt a 1956 // valid request. 1957 time.Sleep(D * 2) 1958 } 1959 go func() { 1960 defer reqs.Done() 1961 res, err := c.Get(st.ts.URL) 1962 if err != nil { 1963 t.Error(err) 1964 return 1965 } 1966 if _, err := ioutil.ReadAll(res.Body); err != nil { 1967 t.Error(err) 1968 return 1969 } 1970 res.Body.Close() 1971 }() 1972 } 1973 reqs.Wait() 1974 conns.Wait() 1975 t.Logf("did %d dials, %d requests", atomic.LoadInt32(&dials), N) 1976 } 1977 1978 type noteCloseConn struct { 1979 net.Conn 1980 onceClose sync.Once 1981 closefn func() 1982 } 1983 1984 func (c *noteCloseConn) Close() error { 1985 c.onceClose.Do(c.closefn) 1986 return c.Conn.Close() 1987 } 1988 1989 func isTimeout(err error) bool { 1990 switch err := err.(type) { 1991 case nil: 1992 return false 1993 case *url.Error: 1994 return isTimeout(err.Err) 1995 case net.Error: 1996 return err.Timeout() 1997 } 1998 return false 1999 } 2000 2001 // Test that the http1 Transport.ResponseHeaderTimeout option and cancel is sent. 2002 func TestTransportResponseHeaderTimeout_NoBody(t *testing.T) { 2003 testTransportResponseHeaderTimeout(t, false) 2004 } 2005 func TestTransportResponseHeaderTimeout_Body(t *testing.T) { 2006 testTransportResponseHeaderTimeout(t, true) 2007 } 2008 2009 func testTransportResponseHeaderTimeout(t *testing.T, body bool) { 2010 ct := newClientTester(t) 2011 ct.tr.t1 = &http.Transport{ 2012 ResponseHeaderTimeout: 5 * time.Millisecond, 2013 } 2014 ct.client = func() error { 2015 c := &http.Client{Transport: ct.tr} 2016 var err error 2017 var n int64 2018 const bodySize = 4 << 20 2019 if body { 2020 _, err = c.Post("https://dummy.tld/", "text/foo", io.LimitReader(countingReader{&n}, bodySize)) 2021 } else { 2022 _, err = c.Get("https://dummy.tld/") 2023 } 2024 if !isTimeout(err) { 2025 t.Errorf("client expected timeout error; got %#v", err) 2026 } 2027 if body && n != bodySize { 2028 t.Errorf("only read %d bytes of body; want %d", n, bodySize) 2029 } 2030 return nil 2031 } 2032 ct.server = func() error { 2033 ct.greet() 2034 for { 2035 f, err := ct.fr.ReadFrame() 2036 if err != nil { 2037 t.Logf("ReadFrame: %v", err) 2038 return nil 2039 } 2040 switch f := f.(type) { 2041 case *DataFrame: 2042 dataLen := len(f.Data()) 2043 if dataLen > 0 { 2044 if err := ct.fr.WriteWindowUpdate(0, uint32(dataLen)); err != nil { 2045 return err 2046 } 2047 if err := ct.fr.WriteWindowUpdate(f.StreamID, uint32(dataLen)); err != nil { 2048 return err 2049 } 2050 } 2051 case *RSTStreamFrame: 2052 if f.StreamID == 1 && f.ErrCode == ErrCodeCancel { 2053 return nil 2054 } 2055 } 2056 } 2057 } 2058 ct.run() 2059 } 2060 2061 func TestTransportDisableCompression(t *testing.T) { 2062 const body = "sup" 2063 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2064 want := http.Header{ 2065 "User-Agent": []string{"Go-http-client/2.0"}, 2066 } 2067 if !reflect.DeepEqual(r.Header, want) { 2068 t.Errorf("request headers = %v; want %v", r.Header, want) 2069 } 2070 }, optOnlyServer) 2071 defer st.Close() 2072 2073 tr := &Transport{ 2074 TLSClientConfig: tlsConfigInsecure, 2075 t1: &http.Transport{ 2076 DisableCompression: true, 2077 }, 2078 } 2079 defer tr.CloseIdleConnections() 2080 2081 req, err := http.NewRequest("GET", st.ts.URL, nil) 2082 if err != nil { 2083 t.Fatal(err) 2084 } 2085 res, err := tr.RoundTrip(req) 2086 if err != nil { 2087 t.Fatal(err) 2088 } 2089 defer res.Body.Close() 2090 } 2091 2092 // RFC 7540 section 8.1.2.2 2093 func TestTransportRejectsConnHeaders(t *testing.T) { 2094 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2095 var got []string 2096 for k := range r.Header { 2097 got = append(got, k) 2098 } 2099 sort.Strings(got) 2100 w.Header().Set("Got-Header", strings.Join(got, ",")) 2101 }, optOnlyServer) 2102 defer st.Close() 2103 2104 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 2105 defer tr.CloseIdleConnections() 2106 2107 tests := []struct { 2108 key string 2109 value []string 2110 want string 2111 }{ 2112 { 2113 key: "Upgrade", 2114 value: []string{"anything"}, 2115 want: "ERROR: http2: invalid Upgrade request header: [\"anything\"]", 2116 }, 2117 { 2118 key: "Connection", 2119 value: []string{"foo"}, 2120 want: "ERROR: http2: invalid Connection request header: [\"foo\"]", 2121 }, 2122 { 2123 key: "Connection", 2124 value: []string{"close"}, 2125 want: "Accept-Encoding,User-Agent", 2126 }, 2127 { 2128 key: "Connection", 2129 value: []string{"CLoSe"}, 2130 want: "Accept-Encoding,User-Agent", 2131 }, 2132 { 2133 key: "Connection", 2134 value: []string{"close", "something-else"}, 2135 want: "ERROR: http2: invalid Connection request header: [\"close\" \"something-else\"]", 2136 }, 2137 { 2138 key: "Connection", 2139 value: []string{"keep-alive"}, 2140 want: "Accept-Encoding,User-Agent", 2141 }, 2142 { 2143 key: "Connection", 2144 value: []string{"Keep-ALIVE"}, 2145 want: "Accept-Encoding,User-Agent", 2146 }, 2147 { 2148 key: "Proxy-Connection", // just deleted and ignored 2149 value: []string{"keep-alive"}, 2150 want: "Accept-Encoding,User-Agent", 2151 }, 2152 { 2153 key: "Transfer-Encoding", 2154 value: []string{""}, 2155 want: "Accept-Encoding,User-Agent", 2156 }, 2157 { 2158 key: "Transfer-Encoding", 2159 value: []string{"foo"}, 2160 want: "ERROR: http2: invalid Transfer-Encoding request header: [\"foo\"]", 2161 }, 2162 { 2163 key: "Transfer-Encoding", 2164 value: []string{"chunked"}, 2165 want: "Accept-Encoding,User-Agent", 2166 }, 2167 { 2168 key: "Transfer-Encoding", 2169 value: []string{"chunked", "other"}, 2170 want: "ERROR: http2: invalid Transfer-Encoding request header: [\"chunked\" \"other\"]", 2171 }, 2172 { 2173 key: "Content-Length", 2174 value: []string{"123"}, 2175 want: "Accept-Encoding,User-Agent", 2176 }, 2177 { 2178 key: "Keep-Alive", 2179 value: []string{"doop"}, 2180 want: "Accept-Encoding,User-Agent", 2181 }, 2182 } 2183 2184 for _, tt := range tests { 2185 req, _ := http.NewRequest("GET", st.ts.URL, nil) 2186 req.Header[tt.key] = tt.value 2187 res, err := tr.RoundTrip(req) 2188 var got string 2189 if err != nil { 2190 got = fmt.Sprintf("ERROR: %v", err) 2191 } else { 2192 got = res.Header.Get("Got-Header") 2193 res.Body.Close() 2194 } 2195 if got != tt.want { 2196 t.Errorf("For key %q, value %q, got = %q; want %q", tt.key, tt.value, got, tt.want) 2197 } 2198 } 2199 } 2200 2201 // golang.org/issue/14048 2202 func TestTransportFailsOnInvalidHeaders(t *testing.T) { 2203 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2204 var got []string 2205 for k := range r.Header { 2206 got = append(got, k) 2207 } 2208 sort.Strings(got) 2209 w.Header().Set("Got-Header", strings.Join(got, ",")) 2210 }, optOnlyServer) 2211 defer st.Close() 2212 2213 tests := [...]struct { 2214 h http.Header 2215 wantErr string 2216 }{ 2217 0: { 2218 h: http.Header{"with space": {"foo"}}, 2219 wantErr: `invalid HTTP header name "with space"`, 2220 }, 2221 1: { 2222 h: http.Header{"name": {"Брэд"}}, 2223 wantErr: "", // okay 2224 }, 2225 2: { 2226 h: http.Header{"имя": {"Brad"}}, 2227 wantErr: `invalid HTTP header name "имя"`, 2228 }, 2229 3: { 2230 h: http.Header{"foo": {"foo\x01bar"}}, 2231 wantErr: `invalid HTTP header value "foo\x01bar" for header "foo"`, 2232 }, 2233 } 2234 2235 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 2236 defer tr.CloseIdleConnections() 2237 2238 for i, tt := range tests { 2239 req, _ := http.NewRequest("GET", st.ts.URL, nil) 2240 req.Header = tt.h 2241 res, err := tr.RoundTrip(req) 2242 var bad bool 2243 if tt.wantErr == "" { 2244 if err != nil { 2245 bad = true 2246 t.Errorf("case %d: error = %v; want no error", i, err) 2247 } 2248 } else { 2249 if !strings.Contains(fmt.Sprint(err), tt.wantErr) { 2250 bad = true 2251 t.Errorf("case %d: error = %v; want error %q", i, err, tt.wantErr) 2252 } 2253 } 2254 if err == nil { 2255 if bad { 2256 t.Logf("case %d: server got headers %q", i, res.Header.Get("Got-Header")) 2257 } 2258 res.Body.Close() 2259 } 2260 } 2261 } 2262 2263 // Tests that gzipReader doesn't crash on a second Read call following 2264 // the first Read call's gzip.NewReader returning an error. 2265 func TestGzipReader_DoubleReadCrash(t *testing.T) { 2266 gz := &gzipReader{ 2267 body: ioutil.NopCloser(strings.NewReader("0123456789")), 2268 } 2269 var buf [1]byte 2270 n, err1 := gz.Read(buf[:]) 2271 if n != 0 || !strings.Contains(fmt.Sprint(err1), "invalid header") { 2272 t.Fatalf("Read = %v, %v; want 0, invalid header", n, err1) 2273 } 2274 n, err2 := gz.Read(buf[:]) 2275 if n != 0 || err2 != err1 { 2276 t.Fatalf("second Read = %v, %v; want 0, %v", n, err2, err1) 2277 } 2278 } 2279 2280 func TestTransportNewTLSConfig(t *testing.T) { 2281 tests := [...]struct { 2282 conf *tls.Config 2283 host string 2284 want *tls.Config 2285 }{ 2286 // Normal case. 2287 0: { 2288 conf: nil, 2289 host: "foo.com", 2290 want: &tls.Config{ 2291 ServerName: "foo.com", 2292 NextProtos: []string{NextProtoTLS}, 2293 }, 2294 }, 2295 2296 // User-provided name (bar.com) takes precedence: 2297 1: { 2298 conf: &tls.Config{ 2299 ServerName: "bar.com", 2300 }, 2301 host: "foo.com", 2302 want: &tls.Config{ 2303 ServerName: "bar.com", 2304 NextProtos: []string{NextProtoTLS}, 2305 }, 2306 }, 2307 2308 // NextProto is prepended: 2309 2: { 2310 conf: &tls.Config{ 2311 NextProtos: []string{"foo", "bar"}, 2312 }, 2313 host: "example.com", 2314 want: &tls.Config{ 2315 ServerName: "example.com", 2316 NextProtos: []string{NextProtoTLS, "foo", "bar"}, 2317 }, 2318 }, 2319 2320 // NextProto is not duplicated: 2321 3: { 2322 conf: &tls.Config{ 2323 NextProtos: []string{"foo", "bar", NextProtoTLS}, 2324 }, 2325 host: "example.com", 2326 want: &tls.Config{ 2327 ServerName: "example.com", 2328 NextProtos: []string{"foo", "bar", NextProtoTLS}, 2329 }, 2330 }, 2331 } 2332 for i, tt := range tests { 2333 // Ignore the session ticket keys part, which ends up populating 2334 // unexported fields in the Config: 2335 if tt.conf != nil { 2336 tt.conf.SessionTicketsDisabled = true 2337 } 2338 2339 tr := &Transport{TLSClientConfig: tt.conf} 2340 got := tr.newTLSConfig(tt.host) 2341 2342 got.SessionTicketsDisabled = false 2343 2344 if !reflect.DeepEqual(got, tt.want) { 2345 t.Errorf("%d. got %#v; want %#v", i, got, tt.want) 2346 } 2347 } 2348 } 2349 2350 // The Google GFE responds to HEAD requests with a HEADERS frame 2351 // without END_STREAM, followed by a 0-length DATA frame with 2352 // END_STREAM. Make sure we don't get confused by that. (We did.) 2353 func TestTransportReadHeadResponse(t *testing.T) { 2354 ct := newClientTester(t) 2355 clientDone := make(chan struct{}) 2356 ct.client = func() error { 2357 defer close(clientDone) 2358 req, _ := http.NewRequest("HEAD", "https://dummy.tld/", nil) 2359 res, err := ct.tr.RoundTrip(req) 2360 if err != nil { 2361 return err 2362 } 2363 if res.ContentLength != 123 { 2364 return fmt.Errorf("Content-Length = %d; want 123", res.ContentLength) 2365 } 2366 slurp, err := ioutil.ReadAll(res.Body) 2367 if err != nil { 2368 return fmt.Errorf("ReadAll: %v", err) 2369 } 2370 if len(slurp) > 0 { 2371 return fmt.Errorf("Unexpected non-empty ReadAll body: %q", slurp) 2372 } 2373 return nil 2374 } 2375 ct.server = func() error { 2376 ct.greet() 2377 for { 2378 f, err := ct.fr.ReadFrame() 2379 if err != nil { 2380 t.Logf("ReadFrame: %v", err) 2381 return nil 2382 } 2383 hf, ok := f.(*HeadersFrame) 2384 if !ok { 2385 continue 2386 } 2387 var buf bytes.Buffer 2388 enc := hpack.NewEncoder(&buf) 2389 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 2390 enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "123"}) 2391 ct.fr.WriteHeaders(HeadersFrameParam{ 2392 StreamID: hf.StreamID, 2393 EndHeaders: true, 2394 EndStream: false, // as the GFE does 2395 BlockFragment: buf.Bytes(), 2396 }) 2397 ct.fr.WriteData(hf.StreamID, true, nil) 2398 2399 <-clientDone 2400 return nil 2401 } 2402 } 2403 ct.run() 2404 } 2405 2406 func TestTransportReadHeadResponseWithBody(t *testing.T) { 2407 // This test use not valid response format. 2408 // Discarding logger output to not spam tests output. 2409 log.SetOutput(ioutil.Discard) 2410 defer log.SetOutput(os.Stderr) 2411 2412 response := "redirecting to /elsewhere" 2413 ct := newClientTester(t) 2414 clientDone := make(chan struct{}) 2415 ct.client = func() error { 2416 defer close(clientDone) 2417 req, _ := http.NewRequest("HEAD", "https://dummy.tld/", nil) 2418 res, err := ct.tr.RoundTrip(req) 2419 if err != nil { 2420 return err 2421 } 2422 if res.ContentLength != int64(len(response)) { 2423 return fmt.Errorf("Content-Length = %d; want %d", res.ContentLength, len(response)) 2424 } 2425 slurp, err := ioutil.ReadAll(res.Body) 2426 if err != nil { 2427 return fmt.Errorf("ReadAll: %v", err) 2428 } 2429 if len(slurp) > 0 { 2430 return fmt.Errorf("Unexpected non-empty ReadAll body: %q", slurp) 2431 } 2432 return nil 2433 } 2434 ct.server = func() error { 2435 ct.greet() 2436 for { 2437 f, err := ct.fr.ReadFrame() 2438 if err != nil { 2439 t.Logf("ReadFrame: %v", err) 2440 return nil 2441 } 2442 hf, ok := f.(*HeadersFrame) 2443 if !ok { 2444 continue 2445 } 2446 var buf bytes.Buffer 2447 enc := hpack.NewEncoder(&buf) 2448 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 2449 enc.WriteField(hpack.HeaderField{Name: "content-length", Value: strconv.Itoa(len(response))}) 2450 ct.fr.WriteHeaders(HeadersFrameParam{ 2451 StreamID: hf.StreamID, 2452 EndHeaders: true, 2453 EndStream: false, 2454 BlockFragment: buf.Bytes(), 2455 }) 2456 ct.fr.WriteData(hf.StreamID, true, []byte(response)) 2457 2458 <-clientDone 2459 return nil 2460 } 2461 } 2462 ct.run() 2463 } 2464 2465 type neverEnding byte 2466 2467 func (b neverEnding) Read(p []byte) (int, error) { 2468 for i := range p { 2469 p[i] = byte(b) 2470 } 2471 return len(p), nil 2472 } 2473 2474 // golang.org/issue/15425: test that a handler closing the request 2475 // body doesn't terminate the stream to the peer. (It just stops 2476 // readability from the handler's side, and eventually the client 2477 // runs out of flow control tokens) 2478 func TestTransportHandlerBodyClose(t *testing.T) { 2479 const bodySize = 10 << 20 2480 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2481 r.Body.Close() 2482 io.Copy(w, io.LimitReader(neverEnding('A'), bodySize)) 2483 }, optOnlyServer) 2484 defer st.Close() 2485 2486 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 2487 defer tr.CloseIdleConnections() 2488 2489 g0 := runtime.NumGoroutine() 2490 2491 const numReq = 10 2492 for i := 0; i < numReq; i++ { 2493 req, err := http.NewRequest("POST", st.ts.URL, struct{ io.Reader }{io.LimitReader(neverEnding('A'), bodySize)}) 2494 if err != nil { 2495 t.Fatal(err) 2496 } 2497 res, err := tr.RoundTrip(req) 2498 if err != nil { 2499 t.Fatal(err) 2500 } 2501 n, err := io.Copy(ioutil.Discard, res.Body) 2502 res.Body.Close() 2503 if n != bodySize || err != nil { 2504 t.Fatalf("req#%d: Copy = %d, %v; want %d, nil", i, n, err, bodySize) 2505 } 2506 } 2507 tr.CloseIdleConnections() 2508 2509 if !waitCondition(5*time.Second, 100*time.Millisecond, func() bool { 2510 gd := runtime.NumGoroutine() - g0 2511 return gd < numReq/2 2512 }) { 2513 t.Errorf("appeared to leak goroutines") 2514 } 2515 } 2516 2517 // https://golang.org/issue/15930 2518 func TestTransportFlowControl(t *testing.T) { 2519 const bufLen = 64 << 10 2520 var total int64 = 100 << 20 // 100MB 2521 if testing.Short() { 2522 total = 10 << 20 2523 } 2524 2525 var wrote int64 // updated atomically 2526 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2527 b := make([]byte, bufLen) 2528 for wrote < total { 2529 n, err := w.Write(b) 2530 atomic.AddInt64(&wrote, int64(n)) 2531 if err != nil { 2532 t.Errorf("ResponseWriter.Write error: %v", err) 2533 break 2534 } 2535 w.(http.Flusher).Flush() 2536 } 2537 }, optOnlyServer) 2538 2539 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 2540 defer tr.CloseIdleConnections() 2541 req, err := http.NewRequest("GET", st.ts.URL, nil) 2542 if err != nil { 2543 t.Fatal("NewRequest error:", err) 2544 } 2545 resp, err := tr.RoundTrip(req) 2546 if err != nil { 2547 t.Fatal("RoundTrip error:", err) 2548 } 2549 defer resp.Body.Close() 2550 2551 var read int64 2552 b := make([]byte, bufLen) 2553 for { 2554 n, err := resp.Body.Read(b) 2555 if err == io.EOF { 2556 break 2557 } 2558 if err != nil { 2559 t.Fatal("Read error:", err) 2560 } 2561 read += int64(n) 2562 2563 const max = transportDefaultStreamFlow 2564 if w := atomic.LoadInt64(&wrote); -max > read-w || read-w > max { 2565 t.Fatalf("Too much data inflight: server wrote %v bytes but client only received %v", w, read) 2566 } 2567 2568 // Let the server get ahead of the client. 2569 time.Sleep(1 * time.Millisecond) 2570 } 2571 } 2572 2573 // golang.org/issue/14627 -- if the server sends a GOAWAY frame, make 2574 // the Transport remember it and return it back to users (via 2575 // RoundTrip or request body reads) if needed (e.g. if the server 2576 // proceeds to close the TCP connection before the client gets its 2577 // response) 2578 func TestTransportUsesGoAwayDebugError_RoundTrip(t *testing.T) { 2579 testTransportUsesGoAwayDebugError(t, false) 2580 } 2581 2582 func TestTransportUsesGoAwayDebugError_Body(t *testing.T) { 2583 testTransportUsesGoAwayDebugError(t, true) 2584 } 2585 2586 func testTransportUsesGoAwayDebugError(t *testing.T, failMidBody bool) { 2587 ct := newClientTester(t) 2588 clientDone := make(chan struct{}) 2589 2590 const goAwayErrCode = ErrCodeHTTP11Required // arbitrary 2591 const goAwayDebugData = "some debug data" 2592 2593 ct.client = func() error { 2594 defer close(clientDone) 2595 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 2596 res, err := ct.tr.RoundTrip(req) 2597 if failMidBody { 2598 if err != nil { 2599 return fmt.Errorf("unexpected client RoundTrip error: %v", err) 2600 } 2601 _, err = io.Copy(ioutil.Discard, res.Body) 2602 res.Body.Close() 2603 } 2604 want := GoAwayError{ 2605 LastStreamID: 5, 2606 ErrCode: goAwayErrCode, 2607 DebugData: goAwayDebugData, 2608 } 2609 if !reflect.DeepEqual(err, want) { 2610 t.Errorf("RoundTrip error = %T: %#v, want %T (%#v)", err, err, want, want) 2611 } 2612 return nil 2613 } 2614 ct.server = func() error { 2615 ct.greet() 2616 for { 2617 f, err := ct.fr.ReadFrame() 2618 if err != nil { 2619 t.Logf("ReadFrame: %v", err) 2620 return nil 2621 } 2622 hf, ok := f.(*HeadersFrame) 2623 if !ok { 2624 continue 2625 } 2626 if failMidBody { 2627 var buf bytes.Buffer 2628 enc := hpack.NewEncoder(&buf) 2629 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 2630 enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "123"}) 2631 ct.fr.WriteHeaders(HeadersFrameParam{ 2632 StreamID: hf.StreamID, 2633 EndHeaders: true, 2634 EndStream: false, 2635 BlockFragment: buf.Bytes(), 2636 }) 2637 } 2638 // Write two GOAWAY frames, to test that the Transport takes 2639 // the interesting parts of both. 2640 ct.fr.WriteGoAway(5, ErrCodeNo, []byte(goAwayDebugData)) 2641 ct.fr.WriteGoAway(5, goAwayErrCode, nil) 2642 ct.sc.(*net.TCPConn).CloseWrite() 2643 <-clientDone 2644 return nil 2645 } 2646 } 2647 ct.run() 2648 } 2649 2650 func testTransportReturnsUnusedFlowControl(t *testing.T, oneDataFrame bool) { 2651 ct := newClientTester(t) 2652 2653 clientClosed := make(chan struct{}) 2654 serverWroteFirstByte := make(chan struct{}) 2655 2656 ct.client = func() error { 2657 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 2658 res, err := ct.tr.RoundTrip(req) 2659 if err != nil { 2660 return err 2661 } 2662 <-serverWroteFirstByte 2663 2664 if n, err := res.Body.Read(make([]byte, 1)); err != nil || n != 1 { 2665 return fmt.Errorf("body read = %v, %v; want 1, nil", n, err) 2666 } 2667 res.Body.Close() // leaving 4999 bytes unread 2668 close(clientClosed) 2669 2670 return nil 2671 } 2672 ct.server = func() error { 2673 ct.greet() 2674 2675 var hf *HeadersFrame 2676 for { 2677 f, err := ct.fr.ReadFrame() 2678 if err != nil { 2679 return fmt.Errorf("ReadFrame while waiting for Headers: %v", err) 2680 } 2681 switch f.(type) { 2682 case *WindowUpdateFrame, *SettingsFrame: 2683 continue 2684 } 2685 var ok bool 2686 hf, ok = f.(*HeadersFrame) 2687 if !ok { 2688 return fmt.Errorf("Got %T; want HeadersFrame", f) 2689 } 2690 break 2691 } 2692 2693 var buf bytes.Buffer 2694 enc := hpack.NewEncoder(&buf) 2695 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 2696 enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "5000"}) 2697 ct.fr.WriteHeaders(HeadersFrameParam{ 2698 StreamID: hf.StreamID, 2699 EndHeaders: true, 2700 EndStream: false, 2701 BlockFragment: buf.Bytes(), 2702 }) 2703 2704 // Two cases: 2705 // - Send one DATA frame with 5000 bytes. 2706 // - Send two DATA frames with 1 and 4999 bytes each. 2707 // 2708 // In both cases, the client should consume one byte of data, 2709 // refund that byte, then refund the following 4999 bytes. 2710 // 2711 // In the second case, the server waits for the client connection to 2712 // close before seconding the second DATA frame. This tests the case 2713 // where the client receives a DATA frame after it has reset the stream. 2714 if oneDataFrame { 2715 ct.fr.WriteData(hf.StreamID, false /* don't end stream */, make([]byte, 5000)) 2716 close(serverWroteFirstByte) 2717 <-clientClosed 2718 } else { 2719 ct.fr.WriteData(hf.StreamID, false /* don't end stream */, make([]byte, 1)) 2720 close(serverWroteFirstByte) 2721 <-clientClosed 2722 ct.fr.WriteData(hf.StreamID, false /* don't end stream */, make([]byte, 4999)) 2723 } 2724 2725 waitingFor := "RSTStreamFrame" 2726 for { 2727 f, err := ct.fr.ReadFrame() 2728 if err != nil { 2729 return fmt.Errorf("ReadFrame while waiting for %s: %v", waitingFor, err) 2730 } 2731 if _, ok := f.(*SettingsFrame); ok { 2732 continue 2733 } 2734 switch waitingFor { 2735 case "RSTStreamFrame": 2736 if rf, ok := f.(*RSTStreamFrame); !ok || rf.ErrCode != ErrCodeCancel { 2737 return fmt.Errorf("Expected a RSTStreamFrame with code cancel; got %v", summarizeFrame(f)) 2738 } 2739 waitingFor = "WindowUpdateFrame" 2740 case "WindowUpdateFrame": 2741 if wuf, ok := f.(*WindowUpdateFrame); !ok || wuf.Increment != 4999 { 2742 return fmt.Errorf("Expected WindowUpdateFrame for 4999 bytes; got %v", summarizeFrame(f)) 2743 } 2744 return nil 2745 } 2746 } 2747 } 2748 ct.run() 2749 } 2750 2751 // See golang.org/issue/16481 2752 func TestTransportReturnsUnusedFlowControlSingleWrite(t *testing.T) { 2753 testTransportReturnsUnusedFlowControl(t, true) 2754 } 2755 2756 // See golang.org/issue/20469 2757 func TestTransportReturnsUnusedFlowControlMultipleWrites(t *testing.T) { 2758 testTransportReturnsUnusedFlowControl(t, false) 2759 } 2760 2761 // Issue 16612: adjust flow control on open streams when transport 2762 // receives SETTINGS with INITIAL_WINDOW_SIZE from server. 2763 func TestTransportAdjustsFlowControl(t *testing.T) { 2764 ct := newClientTester(t) 2765 clientDone := make(chan struct{}) 2766 2767 const bodySize = 1 << 20 2768 2769 ct.client = func() error { 2770 defer ct.cc.(*net.TCPConn).CloseWrite() 2771 defer close(clientDone) 2772 2773 req, _ := http.NewRequest("POST", "https://dummy.tld/", struct{ io.Reader }{io.LimitReader(neverEnding('A'), bodySize)}) 2774 res, err := ct.tr.RoundTrip(req) 2775 if err != nil { 2776 return err 2777 } 2778 res.Body.Close() 2779 return nil 2780 } 2781 ct.server = func() error { 2782 _, err := io.ReadFull(ct.sc, make([]byte, len(ClientPreface))) 2783 if err != nil { 2784 return fmt.Errorf("reading client preface: %v", err) 2785 } 2786 2787 var gotBytes int64 2788 var sentSettings bool 2789 for { 2790 f, err := ct.fr.ReadFrame() 2791 if err != nil { 2792 select { 2793 case <-clientDone: 2794 return nil 2795 default: 2796 return fmt.Errorf("ReadFrame while waiting for Headers: %v", err) 2797 } 2798 } 2799 switch f := f.(type) { 2800 case *DataFrame: 2801 gotBytes += int64(len(f.Data())) 2802 // After we've got half the client's 2803 // initial flow control window's worth 2804 // of request body data, give it just 2805 // enough flow control to finish. 2806 if gotBytes >= initialWindowSize/2 && !sentSettings { 2807 sentSettings = true 2808 2809 ct.fr.WriteSettings(Setting{ID: SettingInitialWindowSize, Val: bodySize}) 2810 ct.fr.WriteWindowUpdate(0, bodySize) 2811 ct.fr.WriteSettingsAck() 2812 } 2813 2814 if f.StreamEnded() { 2815 var buf bytes.Buffer 2816 enc := hpack.NewEncoder(&buf) 2817 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 2818 ct.fr.WriteHeaders(HeadersFrameParam{ 2819 StreamID: f.StreamID, 2820 EndHeaders: true, 2821 EndStream: true, 2822 BlockFragment: buf.Bytes(), 2823 }) 2824 } 2825 } 2826 } 2827 } 2828 ct.run() 2829 } 2830 2831 // See golang.org/issue/16556 2832 func TestTransportReturnsDataPaddingFlowControl(t *testing.T) { 2833 ct := newClientTester(t) 2834 2835 unblockClient := make(chan bool, 1) 2836 2837 ct.client = func() error { 2838 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 2839 res, err := ct.tr.RoundTrip(req) 2840 if err != nil { 2841 return err 2842 } 2843 defer res.Body.Close() 2844 <-unblockClient 2845 return nil 2846 } 2847 ct.server = func() error { 2848 ct.greet() 2849 2850 var hf *HeadersFrame 2851 for { 2852 f, err := ct.fr.ReadFrame() 2853 if err != nil { 2854 return fmt.Errorf("ReadFrame while waiting for Headers: %v", err) 2855 } 2856 switch f.(type) { 2857 case *WindowUpdateFrame, *SettingsFrame: 2858 continue 2859 } 2860 var ok bool 2861 hf, ok = f.(*HeadersFrame) 2862 if !ok { 2863 return fmt.Errorf("Got %T; want HeadersFrame", f) 2864 } 2865 break 2866 } 2867 2868 var buf bytes.Buffer 2869 enc := hpack.NewEncoder(&buf) 2870 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 2871 enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "5000"}) 2872 ct.fr.WriteHeaders(HeadersFrameParam{ 2873 StreamID: hf.StreamID, 2874 EndHeaders: true, 2875 EndStream: false, 2876 BlockFragment: buf.Bytes(), 2877 }) 2878 pad := make([]byte, 5) 2879 ct.fr.WriteDataPadded(hf.StreamID, false, make([]byte, 5000), pad) // without ending stream 2880 2881 f, err := ct.readNonSettingsFrame() 2882 if err != nil { 2883 return fmt.Errorf("ReadFrame while waiting for first WindowUpdateFrame: %v", err) 2884 } 2885 wantBack := uint32(len(pad)) + 1 // one byte for the length of the padding 2886 if wuf, ok := f.(*WindowUpdateFrame); !ok || wuf.Increment != wantBack || wuf.StreamID != 0 { 2887 return fmt.Errorf("Expected conn WindowUpdateFrame for %d bytes; got %v", wantBack, summarizeFrame(f)) 2888 } 2889 2890 f, err = ct.readNonSettingsFrame() 2891 if err != nil { 2892 return fmt.Errorf("ReadFrame while waiting for second WindowUpdateFrame: %v", err) 2893 } 2894 if wuf, ok := f.(*WindowUpdateFrame); !ok || wuf.Increment != wantBack || wuf.StreamID == 0 { 2895 return fmt.Errorf("Expected stream WindowUpdateFrame for %d bytes; got %v", wantBack, summarizeFrame(f)) 2896 } 2897 unblockClient <- true 2898 return nil 2899 } 2900 ct.run() 2901 } 2902 2903 // golang.org/issue/16572 -- RoundTrip shouldn't hang when it gets a 2904 // StreamError as a result of the response HEADERS 2905 func TestTransportReturnsErrorOnBadResponseHeaders(t *testing.T) { 2906 ct := newClientTester(t) 2907 2908 ct.client = func() error { 2909 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 2910 res, err := ct.tr.RoundTrip(req) 2911 if err == nil { 2912 res.Body.Close() 2913 return errors.New("unexpected successful GET") 2914 } 2915 want := StreamError{1, ErrCodeProtocol, headerFieldNameError(" content-type")} 2916 if !reflect.DeepEqual(want, err) { 2917 t.Errorf("RoundTrip error = %#v; want %#v", err, want) 2918 } 2919 return nil 2920 } 2921 ct.server = func() error { 2922 ct.greet() 2923 2924 hf, err := ct.firstHeaders() 2925 if err != nil { 2926 return err 2927 } 2928 2929 var buf bytes.Buffer 2930 enc := hpack.NewEncoder(&buf) 2931 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 2932 enc.WriteField(hpack.HeaderField{Name: " content-type", Value: "bogus"}) // bogus spaces 2933 ct.fr.WriteHeaders(HeadersFrameParam{ 2934 StreamID: hf.StreamID, 2935 EndHeaders: true, 2936 EndStream: false, 2937 BlockFragment: buf.Bytes(), 2938 }) 2939 2940 for { 2941 fr, err := ct.readFrame() 2942 if err != nil { 2943 return fmt.Errorf("error waiting for RST_STREAM from client: %v", err) 2944 } 2945 if _, ok := fr.(*SettingsFrame); ok { 2946 continue 2947 } 2948 if rst, ok := fr.(*RSTStreamFrame); !ok || rst.StreamID != 1 || rst.ErrCode != ErrCodeProtocol { 2949 t.Errorf("Frame = %v; want RST_STREAM for stream 1 with ErrCodeProtocol", summarizeFrame(fr)) 2950 } 2951 break 2952 } 2953 2954 return nil 2955 } 2956 ct.run() 2957 } 2958 2959 // byteAndEOFReader returns is in an io.Reader which reads one byte 2960 // (the underlying byte) and io.EOF at once in its Read call. 2961 type byteAndEOFReader byte 2962 2963 func (b byteAndEOFReader) Read(p []byte) (n int, err error) { 2964 if len(p) == 0 { 2965 panic("unexpected useless call") 2966 } 2967 p[0] = byte(b) 2968 return 1, io.EOF 2969 } 2970 2971 // Issue 16788: the Transport had a regression where it started 2972 // sending a spurious DATA frame with a duplicate END_STREAM bit after 2973 // the request body writer goroutine had already read an EOF from the 2974 // Request.Body and included the END_STREAM on a data-carrying DATA 2975 // frame. 2976 // 2977 // Notably, to trigger this, the requests need to use a Request.Body 2978 // which returns (non-0, io.EOF) and also needs to set the ContentLength 2979 // explicitly. 2980 func TestTransportBodyDoubleEndStream(t *testing.T) { 2981 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2982 // Nothing. 2983 }, optOnlyServer) 2984 defer st.Close() 2985 2986 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 2987 defer tr.CloseIdleConnections() 2988 2989 for i := 0; i < 2; i++ { 2990 req, _ := http.NewRequest("POST", st.ts.URL, byteAndEOFReader('a')) 2991 req.ContentLength = 1 2992 res, err := tr.RoundTrip(req) 2993 if err != nil { 2994 t.Fatalf("failure on req %d: %v", i+1, err) 2995 } 2996 defer res.Body.Close() 2997 } 2998 } 2999 3000 // golang.org/issue/16847, golang.org/issue/19103 3001 func TestTransportRequestPathPseudo(t *testing.T) { 3002 type result struct { 3003 path string 3004 err string 3005 } 3006 tests := []struct { 3007 req *http.Request 3008 want result 3009 }{ 3010 0: { 3011 req: &http.Request{ 3012 Method: "GET", 3013 URL: &url.URL{ 3014 Host: "foo.com", 3015 Path: "/foo", 3016 }, 3017 }, 3018 want: result{path: "/foo"}, 3019 }, 3020 // In Go 1.7, we accepted paths of "//foo". 3021 // In Go 1.8, we rejected it (issue 16847). 3022 // In Go 1.9, we accepted it again (issue 19103). 3023 1: { 3024 req: &http.Request{ 3025 Method: "GET", 3026 URL: &url.URL{ 3027 Host: "foo.com", 3028 Path: "//foo", 3029 }, 3030 }, 3031 want: result{path: "//foo"}, 3032 }, 3033 3034 // Opaque with //$Matching_Hostname/path 3035 2: { 3036 req: &http.Request{ 3037 Method: "GET", 3038 URL: &url.URL{ 3039 Scheme: "https", 3040 Opaque: "//foo.com/path", 3041 Host: "foo.com", 3042 Path: "/ignored", 3043 }, 3044 }, 3045 want: result{path: "/path"}, 3046 }, 3047 3048 // Opaque with some other Request.Host instead: 3049 3: { 3050 req: &http.Request{ 3051 Method: "GET", 3052 Host: "bar.com", 3053 URL: &url.URL{ 3054 Scheme: "https", 3055 Opaque: "//bar.com/path", 3056 Host: "foo.com", 3057 Path: "/ignored", 3058 }, 3059 }, 3060 want: result{path: "/path"}, 3061 }, 3062 3063 // Opaque without the leading "//": 3064 4: { 3065 req: &http.Request{ 3066 Method: "GET", 3067 URL: &url.URL{ 3068 Opaque: "/path", 3069 Host: "foo.com", 3070 Path: "/ignored", 3071 }, 3072 }, 3073 want: result{path: "/path"}, 3074 }, 3075 3076 // Opaque we can't handle: 3077 5: { 3078 req: &http.Request{ 3079 Method: "GET", 3080 URL: &url.URL{ 3081 Scheme: "https", 3082 Opaque: "//unknown_host/path", 3083 Host: "foo.com", 3084 Path: "/ignored", 3085 }, 3086 }, 3087 want: result{err: `invalid request :path "https://unknown_host/path" from URL.Opaque = "//unknown_host/path"`}, 3088 }, 3089 3090 // A CONNECT request: 3091 6: { 3092 req: &http.Request{ 3093 Method: "CONNECT", 3094 URL: &url.URL{ 3095 Host: "foo.com", 3096 }, 3097 }, 3098 want: result{}, 3099 }, 3100 } 3101 for i, tt := range tests { 3102 cc := &ClientConn{peerMaxHeaderListSize: 0xffffffffffffffff} 3103 cc.henc = hpack.NewEncoder(&cc.hbuf) 3104 cc.mu.Lock() 3105 hdrs, err := cc.encodeHeaders(tt.req, false, "", -1) 3106 cc.mu.Unlock() 3107 var got result 3108 hpackDec := hpack.NewDecoder(initialHeaderTableSize, func(f hpack.HeaderField) { 3109 if f.Name == ":path" { 3110 got.path = f.Value 3111 } 3112 }) 3113 if err != nil { 3114 got.err = err.Error() 3115 } else if len(hdrs) > 0 { 3116 if _, err := hpackDec.Write(hdrs); err != nil { 3117 t.Errorf("%d. bogus hpack: %v", i, err) 3118 continue 3119 } 3120 } 3121 if got != tt.want { 3122 t.Errorf("%d. got %+v; want %+v", i, got, tt.want) 3123 } 3124 3125 } 3126 3127 } 3128 3129 // golang.org/issue/17071 -- don't sniff the first byte of the request body 3130 // before we've determined that the ClientConn is usable. 3131 func TestRoundTripDoesntConsumeRequestBodyEarly(t *testing.T) { 3132 const body = "foo" 3133 req, _ := http.NewRequest("POST", "http://foo.com/", ioutil.NopCloser(strings.NewReader(body))) 3134 cc := &ClientConn{ 3135 closed: true, 3136 } 3137 _, err := cc.RoundTrip(req) 3138 if err != errClientConnUnusable { 3139 t.Fatalf("RoundTrip = %v; want errClientConnUnusable", err) 3140 } 3141 slurp, err := ioutil.ReadAll(req.Body) 3142 if err != nil { 3143 t.Errorf("ReadAll = %v", err) 3144 } 3145 if string(slurp) != body { 3146 t.Errorf("Body = %q; want %q", slurp, body) 3147 } 3148 } 3149 3150 func TestClientConnPing(t *testing.T) { 3151 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}, optOnlyServer) 3152 defer st.Close() 3153 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3154 defer tr.CloseIdleConnections() 3155 cc, err := tr.dialClientConn(st.ts.Listener.Addr().String(), false) 3156 if err != nil { 3157 t.Fatal(err) 3158 } 3159 if err = cc.Ping(context.Background()); err != nil { 3160 t.Fatal(err) 3161 } 3162 } 3163 3164 // Issue 16974: if the server sent a DATA frame after the user 3165 // canceled the Transport's Request, the Transport previously wrote to a 3166 // closed pipe, got an error, and ended up closing the whole TCP 3167 // connection. 3168 func TestTransportCancelDataResponseRace(t *testing.T) { 3169 cancel := make(chan struct{}) 3170 clientGotError := make(chan bool, 1) 3171 3172 const msg = "Hello." 3173 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3174 if strings.Contains(r.URL.Path, "/hello") { 3175 time.Sleep(50 * time.Millisecond) 3176 io.WriteString(w, msg) 3177 return 3178 } 3179 for i := 0; i < 50; i++ { 3180 io.WriteString(w, "Some data.") 3181 w.(http.Flusher).Flush() 3182 if i == 2 { 3183 close(cancel) 3184 <-clientGotError 3185 } 3186 time.Sleep(10 * time.Millisecond) 3187 } 3188 }, optOnlyServer) 3189 defer st.Close() 3190 3191 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3192 defer tr.CloseIdleConnections() 3193 3194 c := &http.Client{Transport: tr} 3195 req, _ := http.NewRequest("GET", st.ts.URL, nil) 3196 req.Cancel = cancel 3197 res, err := c.Do(req) 3198 if err != nil { 3199 t.Fatal(err) 3200 } 3201 if _, err = io.Copy(ioutil.Discard, res.Body); err == nil { 3202 t.Fatal("unexpected success") 3203 } 3204 clientGotError <- true 3205 3206 res, err = c.Get(st.ts.URL + "/hello") 3207 if err != nil { 3208 t.Fatal(err) 3209 } 3210 slurp, err := ioutil.ReadAll(res.Body) 3211 if err != nil { 3212 t.Fatal(err) 3213 } 3214 if string(slurp) != msg { 3215 t.Errorf("Got = %q; want %q", slurp, msg) 3216 } 3217 } 3218 3219 // Issue 21316: It should be safe to reuse an http.Request after the 3220 // request has completed. 3221 func TestTransportNoRaceOnRequestObjectAfterRequestComplete(t *testing.T) { 3222 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3223 w.WriteHeader(200) 3224 io.WriteString(w, "body") 3225 }, optOnlyServer) 3226 defer st.Close() 3227 3228 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3229 defer tr.CloseIdleConnections() 3230 3231 req, _ := http.NewRequest("GET", st.ts.URL, nil) 3232 resp, err := tr.RoundTrip(req) 3233 if err != nil { 3234 t.Fatal(err) 3235 } 3236 if _, err = io.Copy(ioutil.Discard, resp.Body); err != nil { 3237 t.Fatalf("error reading response body: %v", err) 3238 } 3239 if err := resp.Body.Close(); err != nil { 3240 t.Fatalf("error closing response body: %v", err) 3241 } 3242 3243 // This access of req.Header should not race with code in the transport. 3244 req.Header = http.Header{} 3245 } 3246 3247 func TestTransportRetryAfterGOAWAY(t *testing.T) { 3248 var dialer struct { 3249 sync.Mutex 3250 count int 3251 } 3252 ct1 := make(chan *clientTester) 3253 ct2 := make(chan *clientTester) 3254 3255 ln := newLocalListener(t) 3256 defer ln.Close() 3257 3258 tr := &Transport{ 3259 TLSClientConfig: tlsConfigInsecure, 3260 } 3261 tr.DialTLS = func(network, addr string, cfg *tls.Config) (net.Conn, error) { 3262 dialer.Lock() 3263 defer dialer.Unlock() 3264 dialer.count++ 3265 if dialer.count == 3 { 3266 return nil, errors.New("unexpected number of dials") 3267 } 3268 cc, err := net.Dial("tcp", ln.Addr().String()) 3269 if err != nil { 3270 return nil, fmt.Errorf("dial error: %v", err) 3271 } 3272 sc, err := ln.Accept() 3273 if err != nil { 3274 return nil, fmt.Errorf("accept error: %v", err) 3275 } 3276 ct := &clientTester{ 3277 t: t, 3278 tr: tr, 3279 cc: cc, 3280 sc: sc, 3281 fr: NewFramer(sc, sc), 3282 } 3283 switch dialer.count { 3284 case 1: 3285 ct1 <- ct 3286 case 2: 3287 ct2 <- ct 3288 } 3289 return cc, nil 3290 } 3291 3292 errs := make(chan error, 3) 3293 done := make(chan struct{}) 3294 defer close(done) 3295 3296 // Client. 3297 go func() { 3298 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 3299 res, err := tr.RoundTrip(req) 3300 if res != nil { 3301 res.Body.Close() 3302 if got := res.Header.Get("Foo"); got != "bar" { 3303 err = fmt.Errorf("foo header = %q; want bar", got) 3304 } 3305 } 3306 if err != nil { 3307 err = fmt.Errorf("RoundTrip: %v", err) 3308 } 3309 errs <- err 3310 }() 3311 3312 connToClose := make(chan io.Closer, 2) 3313 3314 // Server for the first request. 3315 go func() { 3316 var ct *clientTester 3317 select { 3318 case ct = <-ct1: 3319 case <-done: 3320 return 3321 } 3322 3323 connToClose <- ct.cc 3324 ct.greet() 3325 hf, err := ct.firstHeaders() 3326 if err != nil { 3327 errs <- fmt.Errorf("server1 failed reading HEADERS: %v", err) 3328 return 3329 } 3330 t.Logf("server1 got %v", hf) 3331 if err := ct.fr.WriteGoAway(0 /*max id*/, ErrCodeNo, nil); err != nil { 3332 errs <- fmt.Errorf("server1 failed writing GOAWAY: %v", err) 3333 return 3334 } 3335 errs <- nil 3336 }() 3337 3338 // Server for the second request. 3339 go func() { 3340 var ct *clientTester 3341 select { 3342 case ct = <-ct2: 3343 case <-done: 3344 return 3345 } 3346 3347 connToClose <- ct.cc 3348 ct.greet() 3349 hf, err := ct.firstHeaders() 3350 if err != nil { 3351 errs <- fmt.Errorf("server2 failed reading HEADERS: %v", err) 3352 return 3353 } 3354 t.Logf("server2 got %v", hf) 3355 3356 var buf bytes.Buffer 3357 enc := hpack.NewEncoder(&buf) 3358 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 3359 enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"}) 3360 err = ct.fr.WriteHeaders(HeadersFrameParam{ 3361 StreamID: hf.StreamID, 3362 EndHeaders: true, 3363 EndStream: false, 3364 BlockFragment: buf.Bytes(), 3365 }) 3366 if err != nil { 3367 errs <- fmt.Errorf("server2 failed writing response HEADERS: %v", err) 3368 } else { 3369 errs <- nil 3370 } 3371 }() 3372 3373 for k := 0; k < 3; k++ { 3374 select { 3375 case err := <-errs: 3376 if err != nil { 3377 t.Error(err) 3378 } 3379 case <-time.After(1 * time.Second): 3380 t.Errorf("timed out") 3381 } 3382 } 3383 3384 for { 3385 select { 3386 case c := <-connToClose: 3387 c.Close() 3388 default: 3389 return 3390 } 3391 } 3392 } 3393 3394 func TestTransportRetryAfterRefusedStream(t *testing.T) { 3395 clientDone := make(chan struct{}) 3396 ct := newClientTester(t) 3397 ct.client = func() error { 3398 defer ct.cc.(*net.TCPConn).CloseWrite() 3399 defer close(clientDone) 3400 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 3401 resp, err := ct.tr.RoundTrip(req) 3402 if err != nil { 3403 return fmt.Errorf("RoundTrip: %v", err) 3404 } 3405 resp.Body.Close() 3406 if resp.StatusCode != 204 { 3407 return fmt.Errorf("Status = %v; want 204", resp.StatusCode) 3408 } 3409 return nil 3410 } 3411 ct.server = func() error { 3412 ct.greet() 3413 var buf bytes.Buffer 3414 enc := hpack.NewEncoder(&buf) 3415 nreq := 0 3416 3417 for { 3418 f, err := ct.fr.ReadFrame() 3419 if err != nil { 3420 select { 3421 case <-clientDone: 3422 // If the client's done, it 3423 // will have reported any 3424 // errors on its side. 3425 return nil 3426 default: 3427 return err 3428 } 3429 } 3430 switch f := f.(type) { 3431 case *WindowUpdateFrame, *SettingsFrame: 3432 case *HeadersFrame: 3433 if !f.HeadersEnded() { 3434 return fmt.Errorf("headers should have END_HEADERS be ended: %v", f) 3435 } 3436 nreq++ 3437 if nreq == 1 { 3438 ct.fr.WriteRSTStream(f.StreamID, ErrCodeRefusedStream) 3439 } else { 3440 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "204"}) 3441 ct.fr.WriteHeaders(HeadersFrameParam{ 3442 StreamID: f.StreamID, 3443 EndHeaders: true, 3444 EndStream: true, 3445 BlockFragment: buf.Bytes(), 3446 }) 3447 } 3448 default: 3449 return fmt.Errorf("Unexpected client frame %v", f) 3450 } 3451 } 3452 } 3453 ct.run() 3454 } 3455 3456 func TestTransportRetryHasLimit(t *testing.T) { 3457 // Skip in short mode because the total expected delay is 1s+2s+4s+8s+16s=29s. 3458 if testing.Short() { 3459 t.Skip("skipping long test in short mode") 3460 } 3461 clientDone := make(chan struct{}) 3462 ct := newClientTester(t) 3463 ct.client = func() error { 3464 defer ct.cc.(*net.TCPConn).CloseWrite() 3465 defer close(clientDone) 3466 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 3467 resp, err := ct.tr.RoundTrip(req) 3468 if err == nil { 3469 return fmt.Errorf("RoundTrip expected error, got response: %+v", resp) 3470 } 3471 t.Logf("expected error, got: %v", err) 3472 return nil 3473 } 3474 ct.server = func() error { 3475 ct.greet() 3476 for { 3477 f, err := ct.fr.ReadFrame() 3478 if err != nil { 3479 select { 3480 case <-clientDone: 3481 // If the client's done, it 3482 // will have reported any 3483 // errors on its side. 3484 return nil 3485 default: 3486 return err 3487 } 3488 } 3489 switch f := f.(type) { 3490 case *WindowUpdateFrame, *SettingsFrame: 3491 case *HeadersFrame: 3492 if !f.HeadersEnded() { 3493 return fmt.Errorf("headers should have END_HEADERS be ended: %v", f) 3494 } 3495 ct.fr.WriteRSTStream(f.StreamID, ErrCodeRefusedStream) 3496 default: 3497 return fmt.Errorf("Unexpected client frame %v", f) 3498 } 3499 } 3500 } 3501 ct.run() 3502 } 3503 3504 func TestTransportResponseDataBeforeHeaders(t *testing.T) { 3505 // This test use not valid response format. 3506 // Discarding logger output to not spam tests output. 3507 log.SetOutput(ioutil.Discard) 3508 defer log.SetOutput(os.Stderr) 3509 3510 ct := newClientTester(t) 3511 ct.client = func() error { 3512 defer ct.cc.(*net.TCPConn).CloseWrite() 3513 req := httptest.NewRequest("GET", "https://dummy.tld/", nil) 3514 // First request is normal to ensure the check is per stream and not per connection. 3515 _, err := ct.tr.RoundTrip(req) 3516 if err != nil { 3517 return fmt.Errorf("RoundTrip expected no error, got: %v", err) 3518 } 3519 // Second request returns a DATA frame with no HEADERS. 3520 resp, err := ct.tr.RoundTrip(req) 3521 if err == nil { 3522 return fmt.Errorf("RoundTrip expected error, got response: %+v", resp) 3523 } 3524 if err, ok := err.(StreamError); !ok || err.Code != ErrCodeProtocol { 3525 return fmt.Errorf("expected stream PROTOCOL_ERROR, got: %v", err) 3526 } 3527 return nil 3528 } 3529 ct.server = func() error { 3530 ct.greet() 3531 for { 3532 f, err := ct.fr.ReadFrame() 3533 if err == io.EOF { 3534 return nil 3535 } else if err != nil { 3536 return err 3537 } 3538 switch f := f.(type) { 3539 case *WindowUpdateFrame, *SettingsFrame: 3540 case *HeadersFrame: 3541 switch f.StreamID { 3542 case 1: 3543 // Send a valid response to first request. 3544 var buf bytes.Buffer 3545 enc := hpack.NewEncoder(&buf) 3546 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) 3547 ct.fr.WriteHeaders(HeadersFrameParam{ 3548 StreamID: f.StreamID, 3549 EndHeaders: true, 3550 EndStream: true, 3551 BlockFragment: buf.Bytes(), 3552 }) 3553 case 3: 3554 ct.fr.WriteData(f.StreamID, true, []byte("payload")) 3555 } 3556 default: 3557 return fmt.Errorf("Unexpected client frame %v", f) 3558 } 3559 } 3560 } 3561 ct.run() 3562 } 3563 3564 // tests Transport.StrictMaxConcurrentStreams 3565 func TestTransportRequestsStallAtServerLimit(t *testing.T) { 3566 const maxConcurrent = 2 3567 3568 greet := make(chan struct{}) // server sends initial SETTINGS frame 3569 gotRequest := make(chan struct{}) // server received a request 3570 clientDone := make(chan struct{}) 3571 3572 // Collect errors from goroutines. 3573 var wg sync.WaitGroup 3574 errs := make(chan error, 100) 3575 defer func() { 3576 wg.Wait() 3577 close(errs) 3578 for err := range errs { 3579 t.Error(err) 3580 } 3581 }() 3582 3583 // We will send maxConcurrent+2 requests. This checker goroutine waits for the 3584 // following stages: 3585 // 1. The first maxConcurrent requests are received by the server. 3586 // 2. The client will cancel the next request 3587 // 3. The server is unblocked so it can service the first maxConcurrent requests 3588 // 4. The client will send the final request 3589 wg.Add(1) 3590 unblockClient := make(chan struct{}) 3591 clientRequestCancelled := make(chan struct{}) 3592 unblockServer := make(chan struct{}) 3593 go func() { 3594 defer wg.Done() 3595 // Stage 1. 3596 for k := 0; k < maxConcurrent; k++ { 3597 <-gotRequest 3598 } 3599 // Stage 2. 3600 close(unblockClient) 3601 <-clientRequestCancelled 3602 // Stage 3: give some time for the final RoundTrip call to be scheduled and 3603 // verify that the final request is not sent. 3604 time.Sleep(50 * time.Millisecond) 3605 select { 3606 case <-gotRequest: 3607 errs <- errors.New("last request did not stall") 3608 close(unblockServer) 3609 return 3610 default: 3611 } 3612 close(unblockServer) 3613 // Stage 4. 3614 <-gotRequest 3615 }() 3616 3617 ct := newClientTester(t) 3618 ct.tr.StrictMaxConcurrentStreams = true 3619 ct.client = func() error { 3620 var wg sync.WaitGroup 3621 defer func() { 3622 wg.Wait() 3623 close(clientDone) 3624 ct.cc.(*net.TCPConn).CloseWrite() 3625 }() 3626 for k := 0; k < maxConcurrent+2; k++ { 3627 wg.Add(1) 3628 go func(k int) { 3629 defer wg.Done() 3630 // Don't send the second request until after receiving SETTINGS from the server 3631 // to avoid a race where we use the default SettingMaxConcurrentStreams, which 3632 // is much larger than maxConcurrent. We have to send the first request before 3633 // waiting because the first request triggers the dial and greet. 3634 if k > 0 { 3635 <-greet 3636 } 3637 // Block until maxConcurrent requests are sent before sending any more. 3638 if k >= maxConcurrent { 3639 <-unblockClient 3640 } 3641 req, _ := http.NewRequest("GET", fmt.Sprintf("https://dummy.tld/%d", k), nil) 3642 if k == maxConcurrent { 3643 // This request will be canceled. 3644 cancel := make(chan struct{}) 3645 req.Cancel = cancel 3646 close(cancel) 3647 _, err := ct.tr.RoundTrip(req) 3648 close(clientRequestCancelled) 3649 if err == nil { 3650 errs <- fmt.Errorf("RoundTrip(%d) should have failed due to cancel", k) 3651 return 3652 } 3653 } else { 3654 resp, err := ct.tr.RoundTrip(req) 3655 if err != nil { 3656 errs <- fmt.Errorf("RoundTrip(%d): %v", k, err) 3657 return 3658 } 3659 ioutil.ReadAll(resp.Body) 3660 resp.Body.Close() 3661 if resp.StatusCode != 204 { 3662 errs <- fmt.Errorf("Status = %v; want 204", resp.StatusCode) 3663 return 3664 } 3665 } 3666 }(k) 3667 } 3668 return nil 3669 } 3670 3671 ct.server = func() error { 3672 var wg sync.WaitGroup 3673 defer wg.Wait() 3674 3675 ct.greet(Setting{SettingMaxConcurrentStreams, maxConcurrent}) 3676 3677 // Server write loop. 3678 var buf bytes.Buffer 3679 enc := hpack.NewEncoder(&buf) 3680 writeResp := make(chan uint32, maxConcurrent+1) 3681 3682 wg.Add(1) 3683 go func() { 3684 defer wg.Done() 3685 <-unblockServer 3686 for id := range writeResp { 3687 buf.Reset() 3688 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "204"}) 3689 ct.fr.WriteHeaders(HeadersFrameParam{ 3690 StreamID: id, 3691 EndHeaders: true, 3692 EndStream: true, 3693 BlockFragment: buf.Bytes(), 3694 }) 3695 } 3696 }() 3697 3698 // Server read loop. 3699 var nreq int 3700 for { 3701 f, err := ct.fr.ReadFrame() 3702 if err != nil { 3703 select { 3704 case <-clientDone: 3705 // If the client's done, it will have reported any errors on its side. 3706 return nil 3707 default: 3708 return err 3709 } 3710 } 3711 switch f := f.(type) { 3712 case *WindowUpdateFrame: 3713 case *SettingsFrame: 3714 // Wait for the client SETTINGS ack until ending the greet. 3715 close(greet) 3716 case *HeadersFrame: 3717 if !f.HeadersEnded() { 3718 return fmt.Errorf("headers should have END_HEADERS be ended: %v", f) 3719 } 3720 gotRequest <- struct{}{} 3721 nreq++ 3722 writeResp <- f.StreamID 3723 if nreq == maxConcurrent+1 { 3724 close(writeResp) 3725 } 3726 default: 3727 return fmt.Errorf("Unexpected client frame %v", f) 3728 } 3729 } 3730 } 3731 3732 ct.run() 3733 } 3734 3735 func TestAuthorityAddr(t *testing.T) { 3736 tests := []struct { 3737 scheme, authority string 3738 want string 3739 }{ 3740 {"http", "foo.com", "foo.com:80"}, 3741 {"https", "foo.com", "foo.com:443"}, 3742 {"https", "foo.com:1234", "foo.com:1234"}, 3743 {"https", "1.2.3.4:1234", "1.2.3.4:1234"}, 3744 {"https", "1.2.3.4", "1.2.3.4:443"}, 3745 {"https", "[::1]:1234", "[::1]:1234"}, 3746 {"https", "[::1]", "[::1]:443"}, 3747 } 3748 for _, tt := range tests { 3749 got := authorityAddr(tt.scheme, tt.authority) 3750 if got != tt.want { 3751 t.Errorf("authorityAddr(%q, %q) = %q; want %q", tt.scheme, tt.authority, got, tt.want) 3752 } 3753 } 3754 } 3755 3756 // Issue 20448: stop allocating for DATA frames' payload after 3757 // Response.Body.Close is called. 3758 func TestTransportAllocationsAfterResponseBodyClose(t *testing.T) { 3759 megabyteZero := make([]byte, 1<<20) 3760 3761 writeErr := make(chan error, 1) 3762 3763 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3764 w.(http.Flusher).Flush() 3765 var sum int64 3766 for i := 0; i < 100; i++ { 3767 n, err := w.Write(megabyteZero) 3768 sum += int64(n) 3769 if err != nil { 3770 writeErr <- err 3771 return 3772 } 3773 } 3774 t.Logf("wrote all %d bytes", sum) 3775 writeErr <- nil 3776 }, optOnlyServer) 3777 defer st.Close() 3778 3779 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3780 defer tr.CloseIdleConnections() 3781 c := &http.Client{Transport: tr} 3782 res, err := c.Get(st.ts.URL) 3783 if err != nil { 3784 t.Fatal(err) 3785 } 3786 var buf [1]byte 3787 if _, err := res.Body.Read(buf[:]); err != nil { 3788 t.Error(err) 3789 } 3790 if err := res.Body.Close(); err != nil { 3791 t.Error(err) 3792 } 3793 3794 trb, ok := res.Body.(transportResponseBody) 3795 if !ok { 3796 t.Fatalf("res.Body = %T; want transportResponseBody", res.Body) 3797 } 3798 if trb.cs.bufPipe.b != nil { 3799 t.Errorf("response body pipe is still open") 3800 } 3801 3802 gotErr := <-writeErr 3803 if gotErr == nil { 3804 t.Errorf("Handler unexpectedly managed to write its entire response without getting an error") 3805 } else if gotErr != errStreamClosed { 3806 t.Errorf("Handler Write err = %v; want errStreamClosed", gotErr) 3807 } 3808 } 3809 3810 // Issue 18891: make sure Request.Body == NoBody means no DATA frame 3811 // is ever sent, even if empty. 3812 func TestTransportNoBodyMeansNoDATA(t *testing.T) { 3813 ct := newClientTester(t) 3814 3815 unblockClient := make(chan bool) 3816 3817 ct.client = func() error { 3818 req, _ := http.NewRequest("GET", "https://dummy.tld/", http.NoBody) 3819 ct.tr.RoundTrip(req) 3820 <-unblockClient 3821 return nil 3822 } 3823 ct.server = func() error { 3824 defer close(unblockClient) 3825 defer ct.cc.(*net.TCPConn).Close() 3826 ct.greet() 3827 3828 for { 3829 f, err := ct.fr.ReadFrame() 3830 if err != nil { 3831 return fmt.Errorf("ReadFrame while waiting for Headers: %v", err) 3832 } 3833 switch f := f.(type) { 3834 default: 3835 return fmt.Errorf("Got %T; want HeadersFrame", f) 3836 case *WindowUpdateFrame, *SettingsFrame: 3837 continue 3838 case *HeadersFrame: 3839 if !f.StreamEnded() { 3840 return fmt.Errorf("got headers frame without END_STREAM") 3841 } 3842 return nil 3843 } 3844 } 3845 } 3846 ct.run() 3847 } 3848 3849 func benchSimpleRoundTrip(b *testing.B, nHeaders int) { 3850 defer disableGoroutineTracking()() 3851 b.ReportAllocs() 3852 st := newServerTester(b, 3853 func(w http.ResponseWriter, r *http.Request) { 3854 }, 3855 optOnlyServer, 3856 optQuiet, 3857 ) 3858 defer st.Close() 3859 3860 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3861 defer tr.CloseIdleConnections() 3862 3863 req, err := http.NewRequest("GET", st.ts.URL, nil) 3864 if err != nil { 3865 b.Fatal(err) 3866 } 3867 3868 for i := 0; i < nHeaders; i++ { 3869 name := fmt.Sprint("A-", i) 3870 req.Header.Set(name, "*") 3871 } 3872 3873 b.ResetTimer() 3874 3875 for i := 0; i < b.N; i++ { 3876 res, err := tr.RoundTrip(req) 3877 if err != nil { 3878 if res != nil { 3879 res.Body.Close() 3880 } 3881 b.Fatalf("RoundTrip err = %v; want nil", err) 3882 } 3883 res.Body.Close() 3884 if res.StatusCode != http.StatusOK { 3885 b.Fatalf("Response code = %v; want %v", res.StatusCode, http.StatusOK) 3886 } 3887 } 3888 } 3889 3890 type infiniteReader struct{} 3891 3892 func (r infiniteReader) Read(b []byte) (int, error) { 3893 return len(b), nil 3894 } 3895 3896 // Issue 20521: it is not an error to receive a response and end stream 3897 // from the server without the body being consumed. 3898 func TestTransportResponseAndResetWithoutConsumingBodyRace(t *testing.T) { 3899 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3900 w.WriteHeader(http.StatusOK) 3901 }, optOnlyServer) 3902 defer st.Close() 3903 3904 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3905 defer tr.CloseIdleConnections() 3906 3907 // The request body needs to be big enough to trigger flow control. 3908 req, _ := http.NewRequest("PUT", st.ts.URL, infiniteReader{}) 3909 res, err := tr.RoundTrip(req) 3910 if err != nil { 3911 t.Fatal(err) 3912 } 3913 if res.StatusCode != http.StatusOK { 3914 t.Fatalf("Response code = %v; want %v", res.StatusCode, http.StatusOK) 3915 } 3916 } 3917 3918 // Verify transport doesn't crash when receiving bogus response lacking a :status header. 3919 // Issue 22880. 3920 func TestTransportHandlesInvalidStatuslessResponse(t *testing.T) { 3921 ct := newClientTester(t) 3922 ct.client = func() error { 3923 req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) 3924 _, err := ct.tr.RoundTrip(req) 3925 const substr = "malformed response from server: missing status pseudo header" 3926 if !strings.Contains(fmt.Sprint(err), substr) { 3927 return fmt.Errorf("RoundTrip error = %v; want substring %q", err, substr) 3928 } 3929 return nil 3930 } 3931 ct.server = func() error { 3932 ct.greet() 3933 var buf bytes.Buffer 3934 enc := hpack.NewEncoder(&buf) 3935 3936 for { 3937 f, err := ct.fr.ReadFrame() 3938 if err != nil { 3939 return err 3940 } 3941 switch f := f.(type) { 3942 case *HeadersFrame: 3943 enc.WriteField(hpack.HeaderField{Name: "content-type", Value: "text/html"}) // no :status header 3944 ct.fr.WriteHeaders(HeadersFrameParam{ 3945 StreamID: f.StreamID, 3946 EndHeaders: true, 3947 EndStream: false, // we'll send some DATA to try to crash the transport 3948 BlockFragment: buf.Bytes(), 3949 }) 3950 ct.fr.WriteData(f.StreamID, true, []byte("payload")) 3951 return nil 3952 } 3953 } 3954 } 3955 ct.run() 3956 } 3957 3958 func BenchmarkClientRequestHeaders(b *testing.B) { 3959 b.Run(" 0 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 0) }) 3960 b.Run(" 10 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 10) }) 3961 b.Run(" 100 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 100) }) 3962 b.Run("1000 Headers", func(b *testing.B) { benchSimpleRoundTrip(b, 1000) }) 3963 } 3964 3965 func activeStreams(cc *ClientConn) int { 3966 cc.mu.Lock() 3967 defer cc.mu.Unlock() 3968 return len(cc.streams) 3969 } 3970 3971 type closeMode int 3972 3973 const ( 3974 closeAtHeaders closeMode = iota 3975 closeAtBody 3976 shutdown 3977 shutdownCancel 3978 ) 3979 3980 // See golang.org/issue/17292 3981 func testClientConnClose(t *testing.T, closeMode closeMode) { 3982 clientDone := make(chan struct{}) 3983 defer close(clientDone) 3984 handlerDone := make(chan struct{}) 3985 closeDone := make(chan struct{}) 3986 beforeHeader := func() {} 3987 bodyWrite := func(w http.ResponseWriter) {} 3988 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3989 defer close(handlerDone) 3990 beforeHeader() 3991 w.WriteHeader(http.StatusOK) 3992 w.(http.Flusher).Flush() 3993 bodyWrite(w) 3994 select { 3995 case <-w.(http.CloseNotifier).CloseNotify(): 3996 // client closed connection before completion 3997 if closeMode == shutdown || closeMode == shutdownCancel { 3998 t.Error("expected request to complete") 3999 } 4000 case <-clientDone: 4001 if closeMode == closeAtHeaders || closeMode == closeAtBody { 4002 t.Error("expected connection closed by client") 4003 } 4004 } 4005 }, optOnlyServer) 4006 defer st.Close() 4007 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 4008 defer tr.CloseIdleConnections() 4009 cc, err := tr.dialClientConn(st.ts.Listener.Addr().String(), false) 4010 req, err := http.NewRequest("GET", st.ts.URL, nil) 4011 if err != nil { 4012 t.Fatal(err) 4013 } 4014 if closeMode == closeAtHeaders { 4015 beforeHeader = func() { 4016 if err := cc.Close(); err != nil { 4017 t.Error(err) 4018 } 4019 close(closeDone) 4020 } 4021 } 4022 var sendBody chan struct{} 4023 if closeMode == closeAtBody { 4024 sendBody = make(chan struct{}) 4025 bodyWrite = func(w http.ResponseWriter) { 4026 <-sendBody 4027 b := make([]byte, 32) 4028 w.Write(b) 4029 w.(http.Flusher).Flush() 4030 if err := cc.Close(); err != nil { 4031 t.Errorf("unexpected ClientConn close error: %v", err) 4032 } 4033 close(closeDone) 4034 w.Write(b) 4035 w.(http.Flusher).Flush() 4036 } 4037 } 4038 res, err := cc.RoundTrip(req) 4039 if res != nil { 4040 defer res.Body.Close() 4041 } 4042 if closeMode == closeAtHeaders { 4043 got := fmt.Sprint(err) 4044 want := "http2: client connection force closed via ClientConn.Close" 4045 if got != want { 4046 t.Fatalf("RoundTrip error = %v, want %v", got, want) 4047 } 4048 } else { 4049 if err != nil { 4050 t.Fatalf("RoundTrip: %v", err) 4051 } 4052 if got, want := activeStreams(cc), 1; got != want { 4053 t.Errorf("got %d active streams, want %d", got, want) 4054 } 4055 } 4056 switch closeMode { 4057 case shutdownCancel: 4058 if err = cc.Shutdown(canceledCtx); err != context.Canceled { 4059 t.Errorf("got %v, want %v", err, context.Canceled) 4060 } 4061 if cc.closing == false { 4062 t.Error("expected closing to be true") 4063 } 4064 if cc.CanTakeNewRequest() == true { 4065 t.Error("CanTakeNewRequest to return false") 4066 } 4067 if v, want := len(cc.streams), 1; v != want { 4068 t.Errorf("expected %d active streams, got %d", want, v) 4069 } 4070 clientDone <- struct{}{} 4071 <-handlerDone 4072 case shutdown: 4073 wait := make(chan struct{}) 4074 shutdownEnterWaitStateHook = func() { 4075 close(wait) 4076 shutdownEnterWaitStateHook = func() {} 4077 } 4078 defer func() { shutdownEnterWaitStateHook = func() {} }() 4079 shutdown := make(chan struct{}, 1) 4080 go func() { 4081 if err = cc.Shutdown(context.Background()); err != nil { 4082 t.Error(err) 4083 } 4084 close(shutdown) 4085 }() 4086 // Let the shutdown to enter wait state 4087 <-wait 4088 cc.mu.Lock() 4089 if cc.closing == false { 4090 t.Error("expected closing to be true") 4091 } 4092 cc.mu.Unlock() 4093 if cc.CanTakeNewRequest() == true { 4094 t.Error("CanTakeNewRequest to return false") 4095 } 4096 if got, want := activeStreams(cc), 1; got != want { 4097 t.Errorf("got %d active streams, want %d", got, want) 4098 } 4099 // Let the active request finish 4100 clientDone <- struct{}{} 4101 // Wait for the shutdown to end 4102 select { 4103 case <-shutdown: 4104 case <-time.After(2 * time.Second): 4105 t.Fatal("expected server connection to close") 4106 } 4107 case closeAtHeaders, closeAtBody: 4108 if closeMode == closeAtBody { 4109 go close(sendBody) 4110 if _, err := io.Copy(ioutil.Discard, res.Body); err == nil { 4111 t.Error("expected a Copy error, got nil") 4112 } 4113 } 4114 <-closeDone 4115 if got, want := activeStreams(cc), 0; got != want { 4116 t.Errorf("got %d active streams, want %d", got, want) 4117 } 4118 // wait for server to get the connection close notice 4119 select { 4120 case <-handlerDone: 4121 case <-time.After(2 * time.Second): 4122 t.Fatal("expected server connection to close") 4123 } 4124 } 4125 } 4126 4127 // The client closes the connection just after the server got the client's HEADERS 4128 // frame, but before the server sends its HEADERS response back. The expected 4129 // result is an error on RoundTrip explaining the client closed the connection. 4130 func TestClientConnCloseAtHeaders(t *testing.T) { 4131 testClientConnClose(t, closeAtHeaders) 4132 } 4133 4134 // The client closes the connection between two server's response DATA frames. 4135 // The expected behavior is a response body io read error on the client. 4136 func TestClientConnCloseAtBody(t *testing.T) { 4137 testClientConnClose(t, closeAtBody) 4138 } 4139 4140 // The client sends a GOAWAY frame before the server finished processing a request. 4141 // We expect the connection not to close until the request is completed. 4142 func TestClientConnShutdown(t *testing.T) { 4143 testClientConnClose(t, shutdown) 4144 } 4145 4146 // The client sends a GOAWAY frame before the server finishes processing a request, 4147 // but cancels the passed context before the request is completed. The expected 4148 // behavior is the client closing the connection after the context is canceled. 4149 func TestClientConnShutdownCancel(t *testing.T) { 4150 testClientConnClose(t, shutdownCancel) 4151 } 4152 4153 // Issue 25009: use Request.GetBody if present, even if it seems like 4154 // we might not need it. Apparently something else can still read from 4155 // the original request body. Data race? In any case, rewinding 4156 // unconditionally on retry is a nicer model anyway and should 4157 // simplify code in the future (after the Go 1.11 freeze) 4158 func TestTransportUsesGetBodyWhenPresent(t *testing.T) { 4159 calls := 0 4160 someBody := func() io.ReadCloser { 4161 return struct{ io.ReadCloser }{ioutil.NopCloser(bytes.NewReader(nil))} 4162 } 4163 req := &http.Request{ 4164 Body: someBody(), 4165 GetBody: func() (io.ReadCloser, error) { 4166 calls++ 4167 return someBody(), nil 4168 }, 4169 } 4170 4171 afterBodyWrite := false // pretend we haven't read+written the body yet 4172 req2, err := shouldRetryRequest(req, errClientConnUnusable, afterBodyWrite) 4173 if err != nil { 4174 t.Fatal(err) 4175 } 4176 if calls != 1 { 4177 t.Errorf("Calls = %d; want 1", calls) 4178 } 4179 if req2 == req { 4180 t.Error("req2 changed") 4181 } 4182 if req2 == nil { 4183 t.Fatal("req2 is nil") 4184 } 4185 if req2.Body == nil { 4186 t.Fatal("req2.Body is nil") 4187 } 4188 if req2.GetBody == nil { 4189 t.Fatal("req2.GetBody is nil") 4190 } 4191 if req2.Body == req.Body { 4192 t.Error("req2.Body unchanged") 4193 } 4194 } 4195 4196 // Issue 22891: verify that the "https" altproto we register with net/http 4197 // is a certain type: a struct with one field with our *http2.Transport in it. 4198 func TestNoDialH2RoundTripperType(t *testing.T) { 4199 t1 := new(http.Transport) 4200 t2 := new(Transport) 4201 rt := noDialH2RoundTripper{t2} 4202 if err := registerHTTPSProtocol(t1, rt); err != nil { 4203 t.Fatal(err) 4204 } 4205 rv := reflect.ValueOf(rt) 4206 if rv.Type().Kind() != reflect.Struct { 4207 t.Fatalf("kind = %v; net/http expects struct", rv.Type().Kind()) 4208 } 4209 if n := rv.Type().NumField(); n != 1 { 4210 t.Fatalf("fields = %d; net/http expects 1", n) 4211 } 4212 v := rv.Field(0) 4213 if _, ok := v.Interface().(*Transport); !ok { 4214 t.Fatalf("wrong kind %T; want *Transport", v.Interface()) 4215 } 4216 } 4217 4218 type errReader struct { 4219 body []byte 4220 err error 4221 } 4222 4223 func (r *errReader) Read(p []byte) (int, error) { 4224 if len(r.body) > 0 { 4225 n := copy(p, r.body) 4226 r.body = r.body[n:] 4227 return n, nil 4228 } 4229 return 0, r.err 4230 } 4231 4232 func testTransportBodyReadError(t *testing.T, body []byte) { 4233 if runtime.GOOS == "windows" { 4234 // So far we've only seen this be flaky on Windows, 4235 // perhaps due to TCP behavior on shutdowns while 4236 // unread data is in flight. This test should be 4237 // fixed, but a skip is better than annoying people 4238 // for now. 4239 t.Skip("skipping flaky test on Windows; https://golang.org/issue/31260") 4240 } 4241 clientDone := make(chan struct{}) 4242 ct := newClientTester(t) 4243 ct.client = func() error { 4244 defer ct.cc.(*net.TCPConn).CloseWrite() 4245 defer close(clientDone) 4246 4247 checkNoStreams := func() error { 4248 cp, ok := ct.tr.connPool().(*clientConnPool) 4249 if !ok { 4250 return fmt.Errorf("conn pool is %T; want *clientConnPool", ct.tr.connPool()) 4251 } 4252 cp.mu.Lock() 4253 defer cp.mu.Unlock() 4254 conns, ok := cp.conns["dummy.tld:443"] 4255 if !ok { 4256 return fmt.Errorf("missing connection") 4257 } 4258 if len(conns) != 1 { 4259 return fmt.Errorf("conn pool size: %v; expect 1", len(conns)) 4260 } 4261 if activeStreams(conns[0]) != 0 { 4262 return fmt.Errorf("active streams count: %v; want 0", activeStreams(conns[0])) 4263 } 4264 return nil 4265 } 4266 bodyReadError := errors.New("body read error") 4267 body := &errReader{body, bodyReadError} 4268 req, err := http.NewRequest("PUT", "https://dummy.tld/", body) 4269 if err != nil { 4270 return err 4271 } 4272 _, err = ct.tr.RoundTrip(req) 4273 if err != bodyReadError { 4274 return fmt.Errorf("err = %v; want %v", err, bodyReadError) 4275 } 4276 if err = checkNoStreams(); err != nil { 4277 return err 4278 } 4279 return nil 4280 } 4281 ct.server = func() error { 4282 ct.greet() 4283 var receivedBody []byte 4284 var resetCount int 4285 for { 4286 f, err := ct.fr.ReadFrame() 4287 t.Logf("server: ReadFrame = %v, %v", f, err) 4288 if err != nil { 4289 select { 4290 case <-clientDone: 4291 // If the client's done, it 4292 // will have reported any 4293 // errors on its side. 4294 if bytes.Compare(receivedBody, body) != 0 { 4295 return fmt.Errorf("body: %q; expected %q", receivedBody, body) 4296 } 4297 if resetCount != 1 { 4298 return fmt.Errorf("stream reset count: %v; expected: 1", resetCount) 4299 } 4300 return nil 4301 default: 4302 return err 4303 } 4304 } 4305 switch f := f.(type) { 4306 case *WindowUpdateFrame, *SettingsFrame: 4307 case *HeadersFrame: 4308 case *DataFrame: 4309 receivedBody = append(receivedBody, f.Data()...) 4310 case *RSTStreamFrame: 4311 resetCount++ 4312 default: 4313 return fmt.Errorf("Unexpected client frame %v", f) 4314 } 4315 } 4316 } 4317 ct.run() 4318 } 4319 4320 func TestTransportBodyReadError_Immediately(t *testing.T) { testTransportBodyReadError(t, nil) } 4321 func TestTransportBodyReadError_Some(t *testing.T) { testTransportBodyReadError(t, []byte("123")) }