github.com/useflyent/fhttp@v0.0.0-20211004035111-333f430cfbbf/http2/server_test.go (about) 1 // Copyright 2014 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 "bytes" 9 "compress/gzip" 10 "compress/zlib" 11 "context" 12 "crypto/tls" 13 "errors" 14 "flag" 15 "fmt" 16 "io" 17 "io/ioutil" 18 "log" 19 "net" 20 "os" 21 "os/exec" 22 "reflect" 23 "runtime" 24 "strconv" 25 "strings" 26 "sync" 27 "sync/atomic" 28 "testing" 29 "time" 30 31 http "github.com/useflyent/fhttp" 32 "github.com/useflyent/fhttp/httptest" 33 34 "golang.org/x/net/http2/hpack" 35 ) 36 37 var stderrVerbose = flag.Bool("stderr_verbose", false, "Mirror verbosity to stderr, unbuffered") 38 39 func stderrv() io.Writer { 40 if *stderrVerbose { 41 return os.Stderr 42 } 43 44 return ioutil.Discard 45 } 46 47 type serverTester struct { 48 cc net.Conn // client conn 49 t testing.TB 50 ts *httptest.Server 51 fr *Framer 52 serverLogBuf bytes.Buffer // logger for httptest.Server 53 logFilter []string // substrings to filter out 54 scMu sync.Mutex // guards sc 55 sc *serverConn 56 hpackDec *hpack.Decoder 57 decodedHeaders [][2]string 58 59 // If http2debug!=2, then we capture Frame debug logs that will be written 60 // to t.Log after a test fails. The read and write logs use separate locks 61 // and buffers so we don't accidentally introduce synchronization between 62 // the read and write goroutines, which may hide data races. 63 frameReadLogMu sync.Mutex 64 frameReadLogBuf bytes.Buffer 65 frameWriteLogMu sync.Mutex 66 frameWriteLogBuf bytes.Buffer 67 68 // writing headers: 69 headerBuf bytes.Buffer 70 hpackEnc *hpack.Encoder 71 } 72 73 func init() { 74 testHookOnPanicMu = new(sync.Mutex) 75 goAwayTimeout = 25 * time.Millisecond 76 } 77 78 func resetHooks() { 79 testHookOnPanicMu.Lock() 80 testHookOnPanic = nil 81 testHookOnPanicMu.Unlock() 82 } 83 84 type serverTesterOpt string 85 86 var optOnlyServer = serverTesterOpt("only_server") 87 var optQuiet = serverTesterOpt("quiet_logging") 88 var optFramerReuseFrames = serverTesterOpt("frame_reuse_frames") 89 90 func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}) *serverTester { 91 resetHooks() 92 93 ts := httptest.NewUnstartedServer(handler) 94 95 tlsConfig := &tls.Config{ 96 InsecureSkipVerify: true, 97 NextProtos: []string{NextProtoTLS}, 98 } 99 100 var onlyServer, quiet, framerReuseFrames bool 101 h2server := new(Server) 102 for _, opt := range opts { 103 switch v := opt.(type) { 104 case func(*tls.Config): 105 v(tlsConfig) 106 case func(*httptest.Server): 107 v(ts) 108 case func(*Server): 109 v(h2server) 110 case serverTesterOpt: 111 switch v { 112 case optOnlyServer: 113 onlyServer = true 114 case optQuiet: 115 quiet = true 116 case optFramerReuseFrames: 117 framerReuseFrames = true 118 } 119 case func(net.Conn, http.ConnState): 120 ts.Config.ConnState = v 121 default: 122 t.Fatalf("unknown newServerTester option type %T", v) 123 } 124 } 125 126 ConfigureServer(ts.Config, h2server) 127 128 st := &serverTester{ 129 t: t, 130 ts: ts, 131 } 132 st.hpackEnc = hpack.NewEncoder(&st.headerBuf) 133 st.hpackDec = hpack.NewDecoder(initialHeaderTableSize, st.onHeaderField) 134 135 ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config 136 if quiet { 137 ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0) 138 } else { 139 ts.Config.ErrorLog = log.New(io.MultiWriter(stderrv(), twriter{t: t, st: st}, &st.serverLogBuf), "", log.LstdFlags) 140 } 141 ts.StartTLS() 142 143 if VerboseLogs { 144 t.Logf("Running test server at: %s", ts.URL) 145 } 146 testHookGetServerConn = func(v *serverConn) { 147 st.scMu.Lock() 148 defer st.scMu.Unlock() 149 st.sc = v 150 } 151 log.SetOutput(io.MultiWriter(stderrv(), twriter{t: t, st: st})) 152 if !onlyServer { 153 cc, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig) 154 if err != nil { 155 t.Fatal(err) 156 } 157 st.cc = cc 158 st.fr = NewFramer(cc, cc) 159 if framerReuseFrames { 160 st.fr.SetReuseFrames() 161 } 162 if !logFrameReads && !logFrameWrites { 163 st.fr.debugReadLoggerf = func(m string, v ...interface{}) { 164 m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n" 165 st.frameReadLogMu.Lock() 166 fmt.Fprintf(&st.frameReadLogBuf, m, v...) 167 st.frameReadLogMu.Unlock() 168 } 169 st.fr.debugWriteLoggerf = func(m string, v ...interface{}) { 170 m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n" 171 st.frameWriteLogMu.Lock() 172 fmt.Fprintf(&st.frameWriteLogBuf, m, v...) 173 st.frameWriteLogMu.Unlock() 174 } 175 st.fr.logReads = true 176 st.fr.logWrites = true 177 } 178 } 179 return st 180 } 181 182 func (st *serverTester) closeConn() { 183 st.scMu.Lock() 184 defer st.scMu.Unlock() 185 st.sc.conn.Close() 186 } 187 188 func (st *serverTester) addLogFilter(phrase string) { 189 st.logFilter = append(st.logFilter, phrase) 190 } 191 192 func (st *serverTester) stream(id uint32) *stream { 193 ch := make(chan *stream, 1) 194 st.sc.serveMsgCh <- func(int) { 195 ch <- st.sc.streams[id] 196 } 197 return <-ch 198 } 199 200 func (st *serverTester) streamState(id uint32) streamState { 201 ch := make(chan streamState, 1) 202 st.sc.serveMsgCh <- func(int) { 203 state, _ := st.sc.state(id) 204 ch <- state 205 } 206 return <-ch 207 } 208 209 // loopNum reports how many times this conn's select loop has gone around. 210 func (st *serverTester) loopNum() int { 211 lastc := make(chan int, 1) 212 st.sc.serveMsgCh <- func(loopNum int) { 213 lastc <- loopNum 214 } 215 return <-lastc 216 } 217 218 // awaitIdle heuristically awaits for the server conn's select loop to be idle. 219 // The heuristic is that the server connection's serve loop must schedule 220 // 50 times in a row without any channel sends or receives occurring. 221 func (st *serverTester) awaitIdle() { 222 remain := 50 223 last := st.loopNum() 224 for remain > 0 { 225 n := st.loopNum() 226 if n == last+1 { 227 remain-- 228 } else { 229 remain = 50 230 } 231 last = n 232 } 233 } 234 235 func (st *serverTester) Close() { 236 if st.t.Failed() { 237 st.frameReadLogMu.Lock() 238 if st.frameReadLogBuf.Len() > 0 { 239 st.t.Logf("Framer read log:\n%s", st.frameReadLogBuf.String()) 240 } 241 st.frameReadLogMu.Unlock() 242 243 st.frameWriteLogMu.Lock() 244 if st.frameWriteLogBuf.Len() > 0 { 245 st.t.Logf("Framer write log:\n%s", st.frameWriteLogBuf.String()) 246 } 247 st.frameWriteLogMu.Unlock() 248 249 // If we failed already (and are likely in a Fatal, 250 // unwindowing), force close the connection, so the 251 // httptest.Server doesn't wait forever for the conn 252 // to close. 253 if st.cc != nil { 254 st.cc.Close() 255 } 256 } 257 st.ts.Close() 258 if st.cc != nil { 259 st.cc.Close() 260 } 261 log.SetOutput(os.Stderr) 262 } 263 264 // greet initiates the client's HTTP/2 connection into a state where 265 // frames may be sent. 266 func (st *serverTester) greet() { 267 st.greetAndCheckSettings(func(Setting) error { return nil }) 268 } 269 270 func (st *serverTester) greetAndCheckSettings(checkSetting func(s Setting) error) { 271 st.writePreface() 272 st.writeInitialSettings() 273 st.wantSettings().ForeachSetting(checkSetting) 274 st.writeSettingsAck() 275 276 // The initial WINDOW_UPDATE and SETTINGS ACK can come in any order. 277 var gotSettingsAck bool 278 var gotWindowUpdate bool 279 280 for i := 0; i < 2; i++ { 281 f, err := st.readFrame() 282 if err != nil { 283 st.t.Fatal(err) 284 } 285 switch f := f.(type) { 286 case *SettingsFrame: 287 if !f.Header().Flags.Has(FlagSettingsAck) { 288 st.t.Fatal("Settings Frame didn't have ACK set") 289 } 290 gotSettingsAck = true 291 292 case *WindowUpdateFrame: 293 if f.FrameHeader.StreamID != 0 { 294 st.t.Fatalf("WindowUpdate StreamID = %d; want 0", f.FrameHeader.StreamID) 295 } 296 incr := uint32((&Server{}).initialConnRecvWindowSize() - initialWindowSize) 297 if f.Increment != incr { 298 st.t.Fatalf("WindowUpdate increment = %d; want %d", f.Increment, incr) 299 } 300 gotWindowUpdate = true 301 302 default: 303 st.t.Fatalf("Wanting a settings ACK or window update, received a %T", f) 304 } 305 } 306 307 if !gotSettingsAck { 308 st.t.Fatalf("Didn't get a settings ACK") 309 } 310 if !gotWindowUpdate { 311 st.t.Fatalf("Didn't get a window update") 312 } 313 } 314 315 func (st *serverTester) writePreface() { 316 n, err := st.cc.Write(clientPreface) 317 if err != nil { 318 st.t.Fatalf("Error writing client preface: %v", err) 319 } 320 if n != len(clientPreface) { 321 st.t.Fatalf("Writing client preface, wrote %d bytes; want %d", n, len(clientPreface)) 322 } 323 } 324 325 func (st *serverTester) writeInitialSettings() { 326 if err := st.fr.WriteSettings(); err != nil { 327 st.t.Fatalf("Error writing initial SETTINGS frame from client to server: %v", err) 328 } 329 } 330 331 func (st *serverTester) writeSettingsAck() { 332 if err := st.fr.WriteSettingsAck(); err != nil { 333 st.t.Fatalf("Error writing ACK of server's SETTINGS: %v", err) 334 } 335 } 336 337 func (st *serverTester) writeHeaders(p HeadersFrameParam) { 338 if err := st.fr.WriteHeaders(p); err != nil { 339 st.t.Fatalf("Error writing HEADERS: %v", err) 340 } 341 } 342 343 func (st *serverTester) writePriority(id uint32, p PriorityParam) { 344 if err := st.fr.WritePriority(id, p); err != nil { 345 st.t.Fatalf("Error writing PRIORITY: %v", err) 346 } 347 } 348 349 func (st *serverTester) encodeHeaderField(k, v string) { 350 err := st.hpackEnc.WriteField(hpack.HeaderField{Name: k, Value: v}) 351 if err != nil { 352 st.t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err) 353 } 354 } 355 356 // encodeHeaderRaw is the magic-free version of encodeHeader. 357 // It takes 0 or more (k, v) pairs and encodes them. 358 func (st *serverTester) encodeHeaderRaw(headers ...string) []byte { 359 if len(headers)%2 == 1 { 360 panic("odd number of kv args") 361 } 362 st.headerBuf.Reset() 363 for len(headers) > 0 { 364 k, v := headers[0], headers[1] 365 st.encodeHeaderField(k, v) 366 headers = headers[2:] 367 } 368 return st.headerBuf.Bytes() 369 } 370 371 // encodeHeader encodes headers and returns their HPACK bytes. headers 372 // must contain an even number of key/value pairs. There may be 373 // multiple pairs for keys (e.g. "cookie"). The :method, :path, and 374 // :scheme headers default to GET, / and https. The :authority header 375 // defaults to st.ts.Listener.Addr(). 376 func (st *serverTester) encodeHeader(headers ...string) []byte { 377 if len(headers)%2 == 1 { 378 panic("odd number of kv args") 379 } 380 381 st.headerBuf.Reset() 382 defaultAuthority := st.ts.Listener.Addr().String() 383 384 if len(headers) == 0 { 385 // Fast path, mostly for benchmarks, so test code doesn't pollute 386 // profiles when we're looking to improve server allocations. 387 st.encodeHeaderField(":method", "GET") 388 st.encodeHeaderField(":scheme", "https") 389 st.encodeHeaderField(":authority", defaultAuthority) 390 st.encodeHeaderField(":path", "/") 391 return st.headerBuf.Bytes() 392 } 393 394 if len(headers) == 2 && headers[0] == ":method" { 395 // Another fast path for benchmarks. 396 st.encodeHeaderField(":method", headers[1]) 397 st.encodeHeaderField(":scheme", "https") 398 st.encodeHeaderField(":authority", defaultAuthority) 399 st.encodeHeaderField(":path", "/") 400 return st.headerBuf.Bytes() 401 } 402 403 pseudoCount := map[string]int{} 404 keys := []string{":method", ":scheme", ":authority", ":path"} 405 vals := map[string][]string{ 406 ":method": {"GET"}, 407 ":scheme": {"https"}, 408 ":authority": {defaultAuthority}, 409 ":path": {"/"}, 410 } 411 for len(headers) > 0 { 412 k, v := headers[0], headers[1] 413 headers = headers[2:] 414 if _, ok := vals[k]; !ok { 415 keys = append(keys, k) 416 } 417 if strings.HasPrefix(k, ":") { 418 pseudoCount[k]++ 419 if pseudoCount[k] == 1 { 420 vals[k] = []string{v} 421 } else { 422 // Allows testing of invalid headers w/ dup pseudo fields. 423 vals[k] = append(vals[k], v) 424 } 425 } else { 426 vals[k] = append(vals[k], v) 427 } 428 } 429 for _, k := range keys { 430 for _, v := range vals[k] { 431 st.encodeHeaderField(k, v) 432 } 433 } 434 return st.headerBuf.Bytes() 435 } 436 437 // bodylessReq1 writes a HEADERS frames with StreamID 1 and EndStream and EndHeaders set. 438 func (st *serverTester) bodylessReq1(headers ...string) { 439 st.writeHeaders(HeadersFrameParam{ 440 StreamID: 1, // clients send odd numbers 441 BlockFragment: st.encodeHeader(headers...), 442 EndStream: true, 443 EndHeaders: true, 444 }) 445 } 446 447 func (st *serverTester) writeData(streamID uint32, endStream bool, data []byte) { 448 if err := st.fr.WriteData(streamID, endStream, data); err != nil { 449 st.t.Fatalf("Error writing DATA: %v", err) 450 } 451 } 452 453 func (st *serverTester) writeDataPadded(streamID uint32, endStream bool, data, pad []byte) { 454 if err := st.fr.WriteDataPadded(streamID, endStream, data, pad); err != nil { 455 st.t.Fatalf("Error writing DATA: %v", err) 456 } 457 } 458 459 func readFrameTimeout(fr *Framer, wait time.Duration) (Frame, error) { 460 ch := make(chan interface{}, 1) 461 go func() { 462 fr, err := fr.ReadFrame() 463 if err != nil { 464 ch <- err 465 } else { 466 ch <- fr 467 } 468 }() 469 t := time.NewTimer(wait) 470 select { 471 case v := <-ch: 472 t.Stop() 473 if fr, ok := v.(Frame); ok { 474 return fr, nil 475 } 476 return nil, v.(error) 477 case <-t.C: 478 return nil, errors.New("timeout waiting for frame") 479 } 480 } 481 482 func (st *serverTester) readFrame() (Frame, error) { 483 return readFrameTimeout(st.fr, 2*time.Second) 484 } 485 486 func (st *serverTester) wantHeaders() *HeadersFrame { 487 f, err := st.readFrame() 488 if err != nil { 489 st.t.Fatalf("Error while expecting a HEADERS frame: %v", err) 490 } 491 hf, ok := f.(*HeadersFrame) 492 if !ok { 493 st.t.Fatalf("got a %T; want *HeadersFrame", f) 494 } 495 return hf 496 } 497 498 func (st *serverTester) wantContinuation() *ContinuationFrame { 499 f, err := st.readFrame() 500 if err != nil { 501 st.t.Fatalf("Error while expecting a CONTINUATION frame: %v", err) 502 } 503 cf, ok := f.(*ContinuationFrame) 504 if !ok { 505 st.t.Fatalf("got a %T; want *ContinuationFrame", f) 506 } 507 return cf 508 } 509 510 func (st *serverTester) wantData() *DataFrame { 511 f, err := st.readFrame() 512 if err != nil { 513 st.t.Fatalf("Error while expecting a DATA frame: %v", err) 514 } 515 df, ok := f.(*DataFrame) 516 if !ok { 517 st.t.Fatalf("got a %T; want *DataFrame", f) 518 } 519 return df 520 } 521 522 func (st *serverTester) wantSettings() *SettingsFrame { 523 f, err := st.readFrame() 524 if err != nil { 525 st.t.Fatalf("Error while expecting a SETTINGS frame: %v", err) 526 } 527 sf, ok := f.(*SettingsFrame) 528 if !ok { 529 st.t.Fatalf("got a %T; want *SettingsFrame", f) 530 } 531 return sf 532 } 533 534 func (st *serverTester) wantPing() *PingFrame { 535 f, err := st.readFrame() 536 if err != nil { 537 st.t.Fatalf("Error while expecting a PING frame: %v", err) 538 } 539 pf, ok := f.(*PingFrame) 540 if !ok { 541 st.t.Fatalf("got a %T; want *PingFrame", f) 542 } 543 return pf 544 } 545 546 func (st *serverTester) wantGoAway() *GoAwayFrame { 547 f, err := st.readFrame() 548 if err != nil { 549 st.t.Fatalf("Error while expecting a GOAWAY frame: %v", err) 550 } 551 gf, ok := f.(*GoAwayFrame) 552 if !ok { 553 st.t.Fatalf("got a %T; want *GoAwayFrame", f) 554 } 555 return gf 556 } 557 558 func (st *serverTester) wantRSTStream(streamID uint32, errCode ErrCode) { 559 f, err := st.readFrame() 560 if err != nil { 561 st.t.Fatalf("Error while expecting an RSTStream frame: %v", err) 562 } 563 rs, ok := f.(*RSTStreamFrame) 564 if !ok { 565 st.t.Fatalf("got a %T; want *RSTStreamFrame", f) 566 } 567 if rs.FrameHeader.StreamID != streamID { 568 st.t.Fatalf("RSTStream StreamID = %d; want %d", rs.FrameHeader.StreamID, streamID) 569 } 570 if rs.ErrCode != errCode { 571 st.t.Fatalf("RSTStream ErrCode = %d (%s); want %d (%s)", rs.ErrCode, rs.ErrCode, errCode, errCode) 572 } 573 } 574 575 func (st *serverTester) wantWindowUpdate(streamID, incr uint32) { 576 f, err := st.readFrame() 577 if err != nil { 578 st.t.Fatalf("Error while expecting a WINDOW_UPDATE frame: %v", err) 579 } 580 wu, ok := f.(*WindowUpdateFrame) 581 if !ok { 582 st.t.Fatalf("got a %T; want *WindowUpdateFrame", f) 583 } 584 if wu.FrameHeader.StreamID != streamID { 585 st.t.Fatalf("WindowUpdate StreamID = %d; want %d", wu.FrameHeader.StreamID, streamID) 586 } 587 if wu.Increment != incr { 588 st.t.Fatalf("WindowUpdate increment = %d; want %d", wu.Increment, incr) 589 } 590 } 591 592 func (st *serverTester) wantSettingsAck() { 593 f, err := st.readFrame() 594 if err != nil { 595 st.t.Fatal(err) 596 } 597 sf, ok := f.(*SettingsFrame) 598 if !ok { 599 st.t.Fatalf("Wanting a settings ACK, received a %T", f) 600 } 601 if !sf.Header().Flags.Has(FlagSettingsAck) { 602 st.t.Fatal("Settings Frame didn't have ACK set") 603 } 604 } 605 606 func (st *serverTester) wantPushPromise() *PushPromiseFrame { 607 f, err := st.readFrame() 608 if err != nil { 609 st.t.Fatal(err) 610 } 611 ppf, ok := f.(*PushPromiseFrame) 612 if !ok { 613 st.t.Fatalf("Wanted PushPromise, received %T", ppf) 614 } 615 return ppf 616 } 617 618 func TestServer(t *testing.T) { 619 gotReq := make(chan bool, 1) 620 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 621 w.Header().Set("Foo", "Bar") 622 gotReq <- true 623 }) 624 defer st.Close() 625 626 covers("3.5", ` 627 The server connection preface consists of a potentially empty 628 SETTINGS frame ([SETTINGS]) that MUST be the first frame the 629 server sends in the HTTP/2 connection. 630 `) 631 632 st.greet() 633 st.writeHeaders(HeadersFrameParam{ 634 StreamID: 1, // clients send odd numbers 635 BlockFragment: st.encodeHeader(), 636 EndStream: true, // no DATA frames 637 EndHeaders: true, 638 }) 639 640 select { 641 case <-gotReq: 642 case <-time.After(2 * time.Second): 643 t.Error("timeout waiting for request") 644 } 645 } 646 647 func TestServer_Request_Get(t *testing.T) { 648 testServerRequest(t, func(st *serverTester) { 649 st.writeHeaders(HeadersFrameParam{ 650 StreamID: 1, // clients send odd numbers 651 BlockFragment: st.encodeHeader("foo-bar", "some-value"), 652 EndStream: true, // no DATA frames 653 EndHeaders: true, 654 }) 655 }, func(r *http.Request) { 656 if r.Method != "GET" { 657 t.Errorf("Method = %q; want GET", r.Method) 658 } 659 if r.URL.Path != "/" { 660 t.Errorf("URL.Path = %q; want /", r.URL.Path) 661 } 662 if r.ContentLength != 0 { 663 t.Errorf("ContentLength = %v; want 0", r.ContentLength) 664 } 665 if r.Close { 666 t.Error("Close = true; want false") 667 } 668 if !strings.Contains(r.RemoteAddr, ":") { 669 t.Errorf("RemoteAddr = %q; want something with a colon", r.RemoteAddr) 670 } 671 if r.Proto != "HTTP/2.0" || r.ProtoMajor != 2 || r.ProtoMinor != 0 { 672 t.Errorf("Proto = %q Major=%v,Minor=%v; want HTTP/2.0", r.Proto, r.ProtoMajor, r.ProtoMinor) 673 } 674 wantHeader := http.Header{ 675 "Foo-Bar": []string{"some-value"}, 676 } 677 if !reflect.DeepEqual(r.Header, wantHeader) { 678 t.Errorf("Header = %#v; want %#v", r.Header, wantHeader) 679 } 680 if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 { 681 t.Errorf("Read = %d, %v; want 0, EOF", n, err) 682 } 683 }) 684 } 685 686 func TestServer_Request_Get_PathSlashes(t *testing.T) { 687 testServerRequest(t, func(st *serverTester) { 688 st.writeHeaders(HeadersFrameParam{ 689 StreamID: 1, // clients send odd numbers 690 BlockFragment: st.encodeHeader(":path", "/%2f/"), 691 EndStream: true, // no DATA frames 692 EndHeaders: true, 693 }) 694 }, func(r *http.Request) { 695 if r.RequestURI != "/%2f/" { 696 t.Errorf("RequestURI = %q; want /%%2f/", r.RequestURI) 697 } 698 if r.URL.Path != "///" { 699 t.Errorf("URL.Path = %q; want ///", r.URL.Path) 700 } 701 }) 702 } 703 704 // TODO: add a test with EndStream=true on the HEADERS but setting a 705 // Content-Length anyway. Should we just omit it and force it to 706 // zero? 707 708 func TestServer_Request_Post_NoContentLength_EndStream(t *testing.T) { 709 testServerRequest(t, func(st *serverTester) { 710 st.writeHeaders(HeadersFrameParam{ 711 StreamID: 1, // clients send odd numbers 712 BlockFragment: st.encodeHeader(":method", "POST"), 713 EndStream: true, 714 EndHeaders: true, 715 }) 716 }, func(r *http.Request) { 717 if r.Method != "POST" { 718 t.Errorf("Method = %q; want POST", r.Method) 719 } 720 if r.ContentLength != 0 { 721 t.Errorf("ContentLength = %v; want 0", r.ContentLength) 722 } 723 if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 { 724 t.Errorf("Read = %d, %v; want 0, EOF", n, err) 725 } 726 }) 727 } 728 729 func TestServer_Request_Post_Body_ImmediateEOF(t *testing.T) { 730 testBodyContents(t, -1, "", func(st *serverTester) { 731 st.writeHeaders(HeadersFrameParam{ 732 StreamID: 1, // clients send odd numbers 733 BlockFragment: st.encodeHeader(":method", "POST"), 734 EndStream: false, // to say DATA frames are coming 735 EndHeaders: true, 736 }) 737 st.writeData(1, true, nil) // just kidding. empty body. 738 }) 739 } 740 741 func TestServer_Request_Post_Body_OneData(t *testing.T) { 742 const content = "Some content" 743 testBodyContents(t, -1, content, func(st *serverTester) { 744 st.writeHeaders(HeadersFrameParam{ 745 StreamID: 1, // clients send odd numbers 746 BlockFragment: st.encodeHeader(":method", "POST"), 747 EndStream: false, // to say DATA frames are coming 748 EndHeaders: true, 749 }) 750 st.writeData(1, true, []byte(content)) 751 }) 752 } 753 754 func TestServer_Request_Post_Body_TwoData(t *testing.T) { 755 const content = "Some content" 756 testBodyContents(t, -1, content, func(st *serverTester) { 757 st.writeHeaders(HeadersFrameParam{ 758 StreamID: 1, // clients send odd numbers 759 BlockFragment: st.encodeHeader(":method", "POST"), 760 EndStream: false, // to say DATA frames are coming 761 EndHeaders: true, 762 }) 763 st.writeData(1, false, []byte(content[:5])) 764 st.writeData(1, true, []byte(content[5:])) 765 }) 766 } 767 768 func TestServer_Request_Post_Body_ContentLength_Correct(t *testing.T) { 769 const content = "Some content" 770 testBodyContents(t, int64(len(content)), content, func(st *serverTester) { 771 st.writeHeaders(HeadersFrameParam{ 772 StreamID: 1, // clients send odd numbers 773 BlockFragment: st.encodeHeader( 774 ":method", "POST", 775 "content-length", strconv.Itoa(len(content)), 776 ), 777 EndStream: false, // to say DATA frames are coming 778 EndHeaders: true, 779 }) 780 st.writeData(1, true, []byte(content)) 781 }) 782 } 783 784 func TestServer_Request_Post_Body_ContentLength_TooLarge(t *testing.T) { 785 testBodyContentsFail(t, 3, "request declared a Content-Length of 3 but only wrote 2 bytes", 786 func(st *serverTester) { 787 st.writeHeaders(HeadersFrameParam{ 788 StreamID: 1, // clients send odd numbers 789 BlockFragment: st.encodeHeader( 790 ":method", "POST", 791 "content-length", "3", 792 ), 793 EndStream: false, // to say DATA frames are coming 794 EndHeaders: true, 795 }) 796 st.writeData(1, true, []byte("12")) 797 }) 798 } 799 800 func TestServer_Request_Post_Body_ContentLength_TooSmall(t *testing.T) { 801 testBodyContentsFail(t, 4, "sender tried to send more than declared Content-Length of 4 bytes", 802 func(st *serverTester) { 803 st.writeHeaders(HeadersFrameParam{ 804 StreamID: 1, // clients send odd numbers 805 BlockFragment: st.encodeHeader( 806 ":method", "POST", 807 "content-length", "4", 808 ), 809 EndStream: false, // to say DATA frames are coming 810 EndHeaders: true, 811 }) 812 st.writeData(1, true, []byte("12345")) 813 }) 814 } 815 816 func testBodyContents(t *testing.T, wantContentLength int64, wantBody string, write func(st *serverTester)) { 817 testServerRequest(t, write, func(r *http.Request) { 818 if r.Method != "POST" { 819 t.Errorf("Method = %q; want POST", r.Method) 820 } 821 if r.ContentLength != wantContentLength { 822 t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength) 823 } 824 all, err := ioutil.ReadAll(r.Body) 825 if err != nil { 826 t.Fatal(err) 827 } 828 if string(all) != wantBody { 829 t.Errorf("Read = %q; want %q", all, wantBody) 830 } 831 if err := r.Body.Close(); err != nil { 832 t.Fatalf("Close: %v", err) 833 } 834 }) 835 } 836 837 func testBodyContentsFail(t *testing.T, wantContentLength int64, wantReadError string, write func(st *serverTester)) { 838 testServerRequest(t, write, func(r *http.Request) { 839 if r.Method != "POST" { 840 t.Errorf("Method = %q; want POST", r.Method) 841 } 842 if r.ContentLength != wantContentLength { 843 t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength) 844 } 845 all, err := ioutil.ReadAll(r.Body) 846 if err == nil { 847 t.Fatalf("expected an error (%q) reading from the body. Successfully read %q instead.", 848 wantReadError, all) 849 } 850 if !strings.Contains(err.Error(), wantReadError) { 851 t.Fatalf("Body.Read = %v; want substring %q", err, wantReadError) 852 } 853 if err := r.Body.Close(); err != nil { 854 t.Fatalf("Close: %v", err) 855 } 856 }) 857 } 858 859 // Using a Host header, instead of :authority 860 func TestServer_Request_Get_Host(t *testing.T) { 861 const host = "example.com" 862 testServerRequest(t, func(st *serverTester) { 863 st.writeHeaders(HeadersFrameParam{ 864 StreamID: 1, // clients send odd numbers 865 BlockFragment: st.encodeHeader(":authority", "", "host", host), 866 EndStream: true, 867 EndHeaders: true, 868 }) 869 }, func(r *http.Request) { 870 if r.Host != host { 871 t.Errorf("Host = %q; want %q", r.Host, host) 872 } 873 }) 874 } 875 876 // Using an :authority pseudo-header, instead of Host 877 func TestServer_Request_Get_Authority(t *testing.T) { 878 const host = "example.com" 879 testServerRequest(t, func(st *serverTester) { 880 st.writeHeaders(HeadersFrameParam{ 881 StreamID: 1, // clients send odd numbers 882 BlockFragment: st.encodeHeader(":authority", host), 883 EndStream: true, 884 EndHeaders: true, 885 }) 886 }, func(r *http.Request) { 887 if r.Host != host { 888 t.Errorf("Host = %q; want %q", r.Host, host) 889 } 890 }) 891 } 892 893 func TestServer_Request_WithContinuation(t *testing.T) { 894 wantHeader := http.Header{ 895 "Foo-One": []string{"value-one"}, 896 "Foo-Two": []string{"value-two"}, 897 "Foo-Three": []string{"value-three"}, 898 } 899 testServerRequest(t, func(st *serverTester) { 900 fullHeaders := st.encodeHeader( 901 "foo-one", "value-one", 902 "foo-two", "value-two", 903 "foo-three", "value-three", 904 ) 905 remain := fullHeaders 906 chunks := 0 907 for len(remain) > 0 { 908 const maxChunkSize = 5 909 chunk := remain 910 if len(chunk) > maxChunkSize { 911 chunk = chunk[:maxChunkSize] 912 } 913 remain = remain[len(chunk):] 914 915 if chunks == 0 { 916 st.writeHeaders(HeadersFrameParam{ 917 StreamID: 1, // clients send odd numbers 918 BlockFragment: chunk, 919 EndStream: true, // no DATA frames 920 EndHeaders: false, // we'll have continuation frames 921 }) 922 } else { 923 err := st.fr.WriteContinuation(1, len(remain) == 0, chunk) 924 if err != nil { 925 t.Fatal(err) 926 } 927 } 928 chunks++ 929 } 930 if chunks < 2 { 931 t.Fatal("too few chunks") 932 } 933 }, func(r *http.Request) { 934 if !reflect.DeepEqual(r.Header, wantHeader) { 935 t.Errorf("Header = %#v; want %#v", r.Header, wantHeader) 936 } 937 }) 938 } 939 940 // Concatenated cookie headers. ("8.1.2.5 Compressing the Cookie Header Field") 941 func TestServer_Request_CookieConcat(t *testing.T) { 942 const host = "example.com" 943 testServerRequest(t, func(st *serverTester) { 944 st.bodylessReq1( 945 ":authority", host, 946 "cookie", "a=b", 947 "cookie", "c=d", 948 "cookie", "e=f", 949 ) 950 }, func(r *http.Request) { 951 const want = "a=b; c=d; e=f" 952 if got := r.Header.Get("Cookie"); got != want { 953 t.Errorf("Cookie = %q; want %q", got, want) 954 } 955 }) 956 } 957 958 func TestServer_Request_Reject_CapitalHeader(t *testing.T) { 959 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("UPPER", "v") }) 960 } 961 962 func TestServer_Request_Reject_HeaderFieldNameColon(t *testing.T) { 963 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("has:colon", "v") }) 964 } 965 966 func TestServer_Request_Reject_HeaderFieldNameNULL(t *testing.T) { 967 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("has\x00null", "v") }) 968 } 969 970 func TestServer_Request_Reject_HeaderFieldNameEmpty(t *testing.T) { 971 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("", "v") }) 972 } 973 974 func TestServer_Request_Reject_HeaderFieldValueNewline(t *testing.T) { 975 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\nnewline") }) 976 } 977 978 func TestServer_Request_Reject_HeaderFieldValueCR(t *testing.T) { 979 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\rcarriage") }) 980 } 981 982 func TestServer_Request_Reject_HeaderFieldValueDEL(t *testing.T) { 983 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\x7fdel") }) 984 } 985 986 func TestServer_Request_Reject_Pseudo_Missing_method(t *testing.T) { 987 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":method", "") }) 988 } 989 990 func TestServer_Request_Reject_Pseudo_ExactlyOne(t *testing.T) { 991 // 8.1.2.3 Request Pseudo-Header Fields 992 // "All HTTP/2 requests MUST include exactly one valid value" ... 993 testRejectRequest(t, func(st *serverTester) { 994 st.addLogFilter("duplicate pseudo-header") 995 st.bodylessReq1(":method", "GET", ":method", "POST") 996 }) 997 } 998 999 func TestServer_Request_Reject_Pseudo_AfterRegular(t *testing.T) { 1000 // 8.1.2.3 Request Pseudo-Header Fields 1001 // "All pseudo-header fields MUST appear in the header block 1002 // before regular header fields. Any request or response that 1003 // contains a pseudo-header field that appears in a header 1004 // block after a regular header field MUST be treated as 1005 // malformed (Section 8.1.2.6)." 1006 testRejectRequest(t, func(st *serverTester) { 1007 st.addLogFilter("pseudo-header after regular header") 1008 var buf bytes.Buffer 1009 enc := hpack.NewEncoder(&buf) 1010 enc.WriteField(hpack.HeaderField{Name: ":method", Value: "GET"}) 1011 enc.WriteField(hpack.HeaderField{Name: "regular", Value: "foobar"}) 1012 enc.WriteField(hpack.HeaderField{Name: ":path", Value: "/"}) 1013 enc.WriteField(hpack.HeaderField{Name: ":scheme", Value: "https"}) 1014 st.writeHeaders(HeadersFrameParam{ 1015 StreamID: 1, // clients send odd numbers 1016 BlockFragment: buf.Bytes(), 1017 EndStream: true, 1018 EndHeaders: true, 1019 }) 1020 }) 1021 } 1022 1023 func TestServer_Request_Reject_Pseudo_Missing_path(t *testing.T) { 1024 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":path", "") }) 1025 } 1026 1027 func TestServer_Request_Reject_Pseudo_Missing_scheme(t *testing.T) { 1028 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "") }) 1029 } 1030 1031 func TestServer_Request_Reject_Pseudo_scheme_invalid(t *testing.T) { 1032 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "bogus") }) 1033 } 1034 1035 func TestServer_Request_Reject_Pseudo_Unknown(t *testing.T) { 1036 testRejectRequest(t, func(st *serverTester) { 1037 st.addLogFilter(`invalid pseudo-header ":unknown_thing"`) 1038 st.bodylessReq1(":unknown_thing", "") 1039 }) 1040 } 1041 1042 func testRejectRequest(t *testing.T, send func(*serverTester)) { 1043 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 1044 t.Error("server request made it to handler; should've been rejected") 1045 }) 1046 defer st.Close() 1047 1048 st.greet() 1049 send(st) 1050 st.wantRSTStream(1, ErrCodeProtocol) 1051 } 1052 1053 func testRejectRequestWithProtocolError(t *testing.T, send func(*serverTester)) { 1054 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 1055 t.Error("server request made it to handler; should've been rejected") 1056 }, optQuiet) 1057 defer st.Close() 1058 1059 st.greet() 1060 send(st) 1061 gf := st.wantGoAway() 1062 if gf.ErrCode != ErrCodeProtocol { 1063 t.Errorf("err code = %v; want %v", gf.ErrCode, ErrCodeProtocol) 1064 } 1065 } 1066 1067 // Section 5.1, on idle connections: "Receiving any frame other than 1068 // HEADERS or PRIORITY on a stream in this state MUST be treated as a 1069 // connection error (Section 5.4.1) of type PROTOCOL_ERROR." 1070 func TestRejectFrameOnIdle_WindowUpdate(t *testing.T) { 1071 testRejectRequestWithProtocolError(t, func(st *serverTester) { 1072 st.fr.WriteWindowUpdate(123, 456) 1073 }) 1074 } 1075 func TestRejectFrameOnIdle_Data(t *testing.T) { 1076 testRejectRequestWithProtocolError(t, func(st *serverTester) { 1077 st.fr.WriteData(123, true, nil) 1078 }) 1079 } 1080 func TestRejectFrameOnIdle_RSTStream(t *testing.T) { 1081 testRejectRequestWithProtocolError(t, func(st *serverTester) { 1082 st.fr.WriteRSTStream(123, ErrCodeCancel) 1083 }) 1084 } 1085 1086 func TestServer_Request_Connect(t *testing.T) { 1087 testServerRequest(t, func(st *serverTester) { 1088 st.writeHeaders(HeadersFrameParam{ 1089 StreamID: 1, 1090 BlockFragment: st.encodeHeaderRaw( 1091 ":method", "CONNECT", 1092 ":authority", "example.com:123", 1093 ), 1094 EndStream: true, 1095 EndHeaders: true, 1096 }) 1097 }, func(r *http.Request) { 1098 if g, w := r.Method, "CONNECT"; g != w { 1099 t.Errorf("Method = %q; want %q", g, w) 1100 } 1101 if g, w := r.RequestURI, "example.com:123"; g != w { 1102 t.Errorf("RequestURI = %q; want %q", g, w) 1103 } 1104 if g, w := r.URL.Host, "example.com:123"; g != w { 1105 t.Errorf("URL.Host = %q; want %q", g, w) 1106 } 1107 }) 1108 } 1109 1110 func TestServer_Request_Connect_InvalidPath(t *testing.T) { 1111 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) { 1112 st.writeHeaders(HeadersFrameParam{ 1113 StreamID: 1, 1114 BlockFragment: st.encodeHeaderRaw( 1115 ":method", "CONNECT", 1116 ":authority", "example.com:123", 1117 ":path", "/bogus", 1118 ), 1119 EndStream: true, 1120 EndHeaders: true, 1121 }) 1122 }) 1123 } 1124 1125 func TestServer_Request_Connect_InvalidScheme(t *testing.T) { 1126 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) { 1127 st.writeHeaders(HeadersFrameParam{ 1128 StreamID: 1, 1129 BlockFragment: st.encodeHeaderRaw( 1130 ":method", "CONNECT", 1131 ":authority", "example.com:123", 1132 ":scheme", "https", 1133 ), 1134 EndStream: true, 1135 EndHeaders: true, 1136 }) 1137 }) 1138 } 1139 1140 func TestServer_Ping(t *testing.T) { 1141 st := newServerTester(t, nil) 1142 defer st.Close() 1143 st.greet() 1144 1145 // Server should ignore this one, since it has ACK set. 1146 ackPingData := [8]byte{1, 2, 4, 8, 16, 32, 64, 128} 1147 if err := st.fr.WritePing(true, ackPingData); err != nil { 1148 t.Fatal(err) 1149 } 1150 1151 // But the server should reply to this one, since ACK is false. 1152 pingData := [8]byte{1, 2, 3, 4, 5, 6, 7, 8} 1153 if err := st.fr.WritePing(false, pingData); err != nil { 1154 t.Fatal(err) 1155 } 1156 1157 pf := st.wantPing() 1158 if !pf.Flags.Has(FlagPingAck) { 1159 t.Error("response ping doesn't have ACK set") 1160 } 1161 if pf.Data != pingData { 1162 t.Errorf("response ping has data %q; want %q", pf.Data, pingData) 1163 } 1164 } 1165 1166 func TestServer_MaxQueuedControlFrames(t *testing.T) { 1167 if testing.Short() { 1168 t.Skip("skipping in short mode") 1169 } 1170 1171 st := newServerTester(t, nil) 1172 defer st.Close() 1173 st.greet() 1174 1175 const extraPings = 500000 // enough to fill the TCP buffers 1176 1177 for i := 0; i < maxQueuedControlFrames+extraPings; i++ { 1178 pingData := [8]byte{1, 2, 3, 4, 5, 6, 7, 8} 1179 if err := st.fr.WritePing(false, pingData); err != nil { 1180 if i == 0 { 1181 t.Fatal(err) 1182 } 1183 // We expect the connection to get closed by the server when the TCP 1184 // buffer fills up and the write queue reaches MaxQueuedControlFrames. 1185 t.Logf("sent %d PING frames", i) 1186 return 1187 } 1188 } 1189 t.Errorf("unexpected success sending all PING frames") 1190 } 1191 1192 func TestServer_RejectsLargeFrames(t *testing.T) { 1193 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" || runtime.GOOS == "zos" { 1194 t.Skip("see golang.org/issue/13434, golang.org/issue/37321") 1195 } 1196 st := newServerTester(t, nil) 1197 defer st.Close() 1198 st.greet() 1199 1200 // Write too large of a frame (too large by one byte) 1201 // We ignore the return value because it's expected that the server 1202 // will only read the first 9 bytes (the headre) and then disconnect. 1203 st.fr.WriteRawFrame(0xff, 0, 0, make([]byte, defaultMaxReadFrameSize+1)) 1204 1205 gf := st.wantGoAway() 1206 if gf.ErrCode != ErrCodeFrameSize { 1207 t.Errorf("GOAWAY err = %v; want %v", gf.ErrCode, ErrCodeFrameSize) 1208 } 1209 if st.serverLogBuf.Len() != 0 { 1210 // Previously we spun here for a bit until the GOAWAY disconnect 1211 // timer fired, logging while we fired. 1212 t.Errorf("unexpected server output: %.500s\n", st.serverLogBuf.Bytes()) 1213 } 1214 } 1215 1216 func TestServer_Handler_Sends_WindowUpdate(t *testing.T) { 1217 puppet := newHandlerPuppet() 1218 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 1219 puppet.act(w, r) 1220 }) 1221 defer st.Close() 1222 defer puppet.done() 1223 1224 st.greet() 1225 1226 st.writeHeaders(HeadersFrameParam{ 1227 StreamID: 1, // clients send odd numbers 1228 BlockFragment: st.encodeHeader(":method", "POST"), 1229 EndStream: false, // data coming 1230 EndHeaders: true, 1231 }) 1232 st.writeData(1, false, []byte("abcdef")) 1233 puppet.do(readBodyHandler(t, "abc")) 1234 st.wantWindowUpdate(0, 3) 1235 st.wantWindowUpdate(1, 3) 1236 1237 puppet.do(readBodyHandler(t, "def")) 1238 st.wantWindowUpdate(0, 3) 1239 st.wantWindowUpdate(1, 3) 1240 1241 st.writeData(1, true, []byte("ghijkl")) // END_STREAM here 1242 puppet.do(readBodyHandler(t, "ghi")) 1243 puppet.do(readBodyHandler(t, "jkl")) 1244 st.wantWindowUpdate(0, 3) 1245 st.wantWindowUpdate(0, 3) // no more stream-level, since END_STREAM 1246 } 1247 1248 // the version of the TestServer_Handler_Sends_WindowUpdate with padding. 1249 // See golang.org/issue/16556 1250 func TestServer_Handler_Sends_WindowUpdate_Padding(t *testing.T) { 1251 puppet := newHandlerPuppet() 1252 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 1253 puppet.act(w, r) 1254 }) 1255 defer st.Close() 1256 defer puppet.done() 1257 1258 st.greet() 1259 1260 st.writeHeaders(HeadersFrameParam{ 1261 StreamID: 1, 1262 BlockFragment: st.encodeHeader(":method", "POST"), 1263 EndStream: false, 1264 EndHeaders: true, 1265 }) 1266 st.writeDataPadded(1, false, []byte("abcdef"), []byte{0, 0, 0, 0}) 1267 1268 // Expect to immediately get our 5 bytes of padding back for 1269 // both the connection and stream (4 bytes of padding + 1 byte of length) 1270 st.wantWindowUpdate(0, 5) 1271 st.wantWindowUpdate(1, 5) 1272 1273 puppet.do(readBodyHandler(t, "abc")) 1274 st.wantWindowUpdate(0, 3) 1275 st.wantWindowUpdate(1, 3) 1276 1277 puppet.do(readBodyHandler(t, "def")) 1278 st.wantWindowUpdate(0, 3) 1279 st.wantWindowUpdate(1, 3) 1280 } 1281 1282 func TestServer_Send_GoAway_After_Bogus_WindowUpdate(t *testing.T) { 1283 st := newServerTester(t, nil) 1284 defer st.Close() 1285 st.greet() 1286 if err := st.fr.WriteWindowUpdate(0, 1<<31-1); err != nil { 1287 t.Fatal(err) 1288 } 1289 gf := st.wantGoAway() 1290 if gf.ErrCode != ErrCodeFlowControl { 1291 t.Errorf("GOAWAY err = %v; want %v", gf.ErrCode, ErrCodeFlowControl) 1292 } 1293 if gf.LastStreamID != 0 { 1294 t.Errorf("GOAWAY last stream ID = %v; want %v", gf.LastStreamID, 0) 1295 } 1296 } 1297 1298 func TestServer_Send_RstStream_After_Bogus_WindowUpdate(t *testing.T) { 1299 inHandler := make(chan bool) 1300 blockHandler := make(chan bool) 1301 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 1302 inHandler <- true 1303 <-blockHandler 1304 }) 1305 defer st.Close() 1306 defer close(blockHandler) 1307 st.greet() 1308 st.writeHeaders(HeadersFrameParam{ 1309 StreamID: 1, 1310 BlockFragment: st.encodeHeader(":method", "POST"), 1311 EndStream: false, // keep it open 1312 EndHeaders: true, 1313 }) 1314 <-inHandler 1315 // Send a bogus window update: 1316 if err := st.fr.WriteWindowUpdate(1, 1<<31-1); err != nil { 1317 t.Fatal(err) 1318 } 1319 st.wantRSTStream(1, ErrCodeFlowControl) 1320 } 1321 1322 // testServerPostUnblock sends a hanging POST with unsent data to handler, 1323 // then runs fn once in the handler, and verifies that the error returned from 1324 // handler is acceptable. It fails if takes over 5 seconds for handler to exit. 1325 func testServerPostUnblock(t *testing.T, 1326 handler func(http.ResponseWriter, *http.Request) error, 1327 fn func(*serverTester), 1328 checkErr func(error), 1329 otherHeaders ...string) { 1330 inHandler := make(chan bool) 1331 errc := make(chan error, 1) 1332 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 1333 inHandler <- true 1334 errc <- handler(w, r) 1335 }) 1336 defer st.Close() 1337 st.greet() 1338 st.writeHeaders(HeadersFrameParam{ 1339 StreamID: 1, 1340 BlockFragment: st.encodeHeader(append([]string{":method", "POST"}, otherHeaders...)...), 1341 EndStream: false, // keep it open 1342 EndHeaders: true, 1343 }) 1344 <-inHandler 1345 fn(st) 1346 select { 1347 case err := <-errc: 1348 if checkErr != nil { 1349 checkErr(err) 1350 } 1351 case <-time.After(5 * time.Second): 1352 t.Fatal("timeout waiting for Handler to return") 1353 } 1354 } 1355 1356 func TestServer_RSTStream_Unblocks_Read(t *testing.T) { 1357 testServerPostUnblock(t, 1358 func(w http.ResponseWriter, r *http.Request) (err error) { 1359 _, err = r.Body.Read(make([]byte, 1)) 1360 return 1361 }, 1362 func(st *serverTester) { 1363 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil { 1364 t.Fatal(err) 1365 } 1366 }, 1367 func(err error) { 1368 want := StreamError{StreamID: 0x1, Code: 0x8} 1369 if !reflect.DeepEqual(err, want) { 1370 t.Errorf("Read error = %v; want %v", err, want) 1371 } 1372 }, 1373 ) 1374 } 1375 1376 func TestServer_RSTStream_Unblocks_Header_Write(t *testing.T) { 1377 // Run this test a bunch, because it doesn't always 1378 // deadlock. But with a bunch, it did. 1379 n := 50 1380 if testing.Short() { 1381 n = 5 1382 } 1383 for i := 0; i < n; i++ { 1384 testServer_RSTStream_Unblocks_Header_Write(t) 1385 } 1386 } 1387 1388 func testServer_RSTStream_Unblocks_Header_Write(t *testing.T) { 1389 inHandler := make(chan bool, 1) 1390 unblockHandler := make(chan bool, 1) 1391 headerWritten := make(chan bool, 1) 1392 wroteRST := make(chan bool, 1) 1393 1394 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 1395 inHandler <- true 1396 <-wroteRST 1397 w.Header().Set("foo", "bar") 1398 w.WriteHeader(200) 1399 w.(http.Flusher).Flush() 1400 headerWritten <- true 1401 <-unblockHandler 1402 }) 1403 defer st.Close() 1404 1405 st.greet() 1406 st.writeHeaders(HeadersFrameParam{ 1407 StreamID: 1, 1408 BlockFragment: st.encodeHeader(":method", "POST"), 1409 EndStream: false, // keep it open 1410 EndHeaders: true, 1411 }) 1412 <-inHandler 1413 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil { 1414 t.Fatal(err) 1415 } 1416 wroteRST <- true 1417 st.awaitIdle() 1418 select { 1419 case <-headerWritten: 1420 case <-time.After(2 * time.Second): 1421 t.Error("timeout waiting for header write") 1422 } 1423 unblockHandler <- true 1424 } 1425 1426 func TestServer_DeadConn_Unblocks_Read(t *testing.T) { 1427 testServerPostUnblock(t, 1428 func(w http.ResponseWriter, r *http.Request) (err error) { 1429 _, err = r.Body.Read(make([]byte, 1)) 1430 return 1431 }, 1432 func(st *serverTester) { st.cc.Close() }, 1433 func(err error) { 1434 if err == nil { 1435 t.Error("unexpected nil error from Request.Body.Read") 1436 } 1437 }, 1438 ) 1439 } 1440 1441 var blockUntilClosed = func(w http.ResponseWriter, r *http.Request) error { 1442 <-w.(http.CloseNotifier).CloseNotify() 1443 return nil 1444 } 1445 1446 func TestServer_CloseNotify_After_RSTStream(t *testing.T) { 1447 testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) { 1448 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil { 1449 t.Fatal(err) 1450 } 1451 }, nil) 1452 } 1453 1454 func TestServer_CloseNotify_After_ConnClose(t *testing.T) { 1455 testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) { st.cc.Close() }, nil) 1456 } 1457 1458 // that CloseNotify unblocks after a stream error due to the client's 1459 // problem that's unrelated to them explicitly canceling it (which is 1460 // TestServer_CloseNotify_After_RSTStream above) 1461 func TestServer_CloseNotify_After_StreamError(t *testing.T) { 1462 testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) { 1463 // data longer than declared Content-Length => stream error 1464 st.writeData(1, true, []byte("1234")) 1465 }, nil, "content-length", "3") 1466 } 1467 1468 func TestServer_StateTransitions(t *testing.T) { 1469 var st *serverTester 1470 inHandler := make(chan bool) 1471 writeData := make(chan bool) 1472 leaveHandler := make(chan bool) 1473 st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 1474 inHandler <- true 1475 if st.stream(1) == nil { 1476 t.Errorf("nil stream 1 in handler") 1477 } 1478 if got, want := st.streamState(1), stateOpen; got != want { 1479 t.Errorf("in handler, state is %v; want %v", got, want) 1480 } 1481 writeData <- true 1482 if n, err := r.Body.Read(make([]byte, 1)); n != 0 || err != io.EOF { 1483 t.Errorf("body read = %d, %v; want 0, EOF", n, err) 1484 } 1485 if got, want := st.streamState(1), stateHalfClosedRemote; got != want { 1486 t.Errorf("in handler, state is %v; want %v", got, want) 1487 } 1488 1489 <-leaveHandler 1490 }) 1491 st.greet() 1492 if st.stream(1) != nil { 1493 t.Fatal("stream 1 should be empty") 1494 } 1495 if got := st.streamState(1); got != stateIdle { 1496 t.Fatalf("stream 1 should be idle; got %v", got) 1497 } 1498 1499 st.writeHeaders(HeadersFrameParam{ 1500 StreamID: 1, 1501 BlockFragment: st.encodeHeader(":method", "POST"), 1502 EndStream: false, // keep it open 1503 EndHeaders: true, 1504 }) 1505 <-inHandler 1506 <-writeData 1507 st.writeData(1, true, nil) 1508 1509 leaveHandler <- true 1510 hf := st.wantHeaders() 1511 if !hf.StreamEnded() { 1512 t.Fatal("expected END_STREAM flag") 1513 } 1514 1515 if got, want := st.streamState(1), stateClosed; got != want { 1516 t.Errorf("at end, state is %v; want %v", got, want) 1517 } 1518 if st.stream(1) != nil { 1519 t.Fatal("at end, stream 1 should be gone") 1520 } 1521 } 1522 1523 // test HEADERS w/o EndHeaders + another HEADERS (should get rejected) 1524 func TestServer_Rejects_HeadersNoEnd_Then_Headers(t *testing.T) { 1525 testServerRejectsConn(t, func(st *serverTester) { 1526 st.writeHeaders(HeadersFrameParam{ 1527 StreamID: 1, 1528 BlockFragment: st.encodeHeader(), 1529 EndStream: true, 1530 EndHeaders: false, 1531 }) 1532 st.writeHeaders(HeadersFrameParam{ // Not a continuation. 1533 StreamID: 3, // different stream. 1534 BlockFragment: st.encodeHeader(), 1535 EndStream: true, 1536 EndHeaders: true, 1537 }) 1538 }) 1539 } 1540 1541 // test HEADERS w/o EndHeaders + PING (should get rejected) 1542 func TestServer_Rejects_HeadersNoEnd_Then_Ping(t *testing.T) { 1543 testServerRejectsConn(t, func(st *serverTester) { 1544 st.writeHeaders(HeadersFrameParam{ 1545 StreamID: 1, 1546 BlockFragment: st.encodeHeader(), 1547 EndStream: true, 1548 EndHeaders: false, 1549 }) 1550 if err := st.fr.WritePing(false, [8]byte{}); err != nil { 1551 t.Fatal(err) 1552 } 1553 }) 1554 } 1555 1556 // test HEADERS w/ EndHeaders + a continuation HEADERS (should get rejected) 1557 func TestServer_Rejects_HeadersEnd_Then_Continuation(t *testing.T) { 1558 testServerRejectsConn(t, func(st *serverTester) { 1559 st.writeHeaders(HeadersFrameParam{ 1560 StreamID: 1, 1561 BlockFragment: st.encodeHeader(), 1562 EndStream: true, 1563 EndHeaders: true, 1564 }) 1565 st.wantHeaders() 1566 if err := st.fr.WriteContinuation(1, true, encodeHeaderNoImplicit(t, "foo", "bar")); err != nil { 1567 t.Fatal(err) 1568 } 1569 }) 1570 } 1571 1572 // test HEADERS w/o EndHeaders + a continuation HEADERS on wrong stream ID 1573 func TestServer_Rejects_HeadersNoEnd_Then_ContinuationWrongStream(t *testing.T) { 1574 testServerRejectsConn(t, func(st *serverTester) { 1575 st.writeHeaders(HeadersFrameParam{ 1576 StreamID: 1, 1577 BlockFragment: st.encodeHeader(), 1578 EndStream: true, 1579 EndHeaders: false, 1580 }) 1581 if err := st.fr.WriteContinuation(3, true, encodeHeaderNoImplicit(t, "foo", "bar")); err != nil { 1582 t.Fatal(err) 1583 } 1584 }) 1585 } 1586 1587 // No HEADERS on stream 0. 1588 func TestServer_Rejects_Headers0(t *testing.T) { 1589 testServerRejectsConn(t, func(st *serverTester) { 1590 st.fr.AllowIllegalWrites = true 1591 st.writeHeaders(HeadersFrameParam{ 1592 StreamID: 0, 1593 BlockFragment: st.encodeHeader(), 1594 EndStream: true, 1595 EndHeaders: true, 1596 }) 1597 }) 1598 } 1599 1600 // No CONTINUATION on stream 0. 1601 func TestServer_Rejects_Continuation0(t *testing.T) { 1602 testServerRejectsConn(t, func(st *serverTester) { 1603 st.fr.AllowIllegalWrites = true 1604 if err := st.fr.WriteContinuation(0, true, st.encodeHeader()); err != nil { 1605 t.Fatal(err) 1606 } 1607 }) 1608 } 1609 1610 // No PRIORITY on stream 0. 1611 func TestServer_Rejects_Priority0(t *testing.T) { 1612 testServerRejectsConn(t, func(st *serverTester) { 1613 st.fr.AllowIllegalWrites = true 1614 st.writePriority(0, PriorityParam{StreamDep: 1}) 1615 }) 1616 } 1617 1618 // No HEADERS frame with a self-dependence. 1619 func TestServer_Rejects_HeadersSelfDependence(t *testing.T) { 1620 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) { 1621 st.fr.AllowIllegalWrites = true 1622 st.writeHeaders(HeadersFrameParam{ 1623 StreamID: 1, 1624 BlockFragment: st.encodeHeader(), 1625 EndStream: true, 1626 EndHeaders: true, 1627 Priority: PriorityParam{StreamDep: 1}, 1628 }) 1629 }) 1630 } 1631 1632 // No PRIORTY frame with a self-dependence. 1633 func TestServer_Rejects_PrioritySelfDependence(t *testing.T) { 1634 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) { 1635 st.fr.AllowIllegalWrites = true 1636 st.writePriority(1, PriorityParam{StreamDep: 1}) 1637 }) 1638 } 1639 1640 func TestServer_Rejects_PushPromise(t *testing.T) { 1641 testServerRejectsConn(t, func(st *serverTester) { 1642 // The server will not react to single PUSH_PROMISE w/o EndHeaders 1643 // flag. Because in that case, the framer will wait for more 1644 // CONTINUATIONs, and never produce a MetaPushPromiseFrame to the 1645 // server. 1646 pp := PushPromiseParam{ 1647 StreamID: 1, 1648 PromiseID: 3, 1649 EndHeaders: true, 1650 } 1651 if err := st.fr.WritePushPromise(pp); err != nil { 1652 t.Fatal(err) 1653 } 1654 }) 1655 } 1656 1657 // testServerRejectsConn tests that the server hangs up with a GOAWAY 1658 // frame and a server close after the client does something 1659 // deserving a CONNECTION_ERROR. 1660 func testServerRejectsConn(t *testing.T, writeReq func(*serverTester)) { 1661 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}) 1662 st.addLogFilter("connection error: PROTOCOL_ERROR") 1663 defer st.Close() 1664 st.greet() 1665 writeReq(st) 1666 1667 st.wantGoAway() 1668 errc := make(chan error, 1) 1669 go func() { 1670 fr, err := st.fr.ReadFrame() 1671 if err == nil { 1672 err = fmt.Errorf("got frame of type %T", fr) 1673 } 1674 errc <- err 1675 }() 1676 select { 1677 case err := <-errc: 1678 if err != io.EOF { 1679 t.Errorf("ReadFrame = %v; want io.EOF", err) 1680 } 1681 case <-time.After(2 * time.Second): 1682 t.Error("timeout waiting for disconnect") 1683 } 1684 } 1685 1686 // testServerRejectsStream tests that the server sends a RST_STREAM with the provided 1687 // error code after a client sends a bogus request. 1688 func testServerRejectsStream(t *testing.T, code ErrCode, writeReq func(*serverTester)) { 1689 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}) 1690 defer st.Close() 1691 st.greet() 1692 writeReq(st) 1693 st.wantRSTStream(1, code) 1694 } 1695 1696 // testServerRequest sets up an idle HTTP/2 connection and lets you 1697 // write a single request with writeReq, and then verify that the 1698 // *http.Request is built correctly in checkReq. 1699 func testServerRequest(t *testing.T, writeReq func(*serverTester), checkReq func(*http.Request)) { 1700 gotReq := make(chan bool, 1) 1701 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 1702 if r.Body == nil { 1703 t.Fatal("nil Body") 1704 } 1705 checkReq(r) 1706 gotReq <- true 1707 }) 1708 defer st.Close() 1709 1710 st.greet() 1711 writeReq(st) 1712 1713 select { 1714 case <-gotReq: 1715 case <-time.After(2 * time.Second): 1716 t.Error("timeout waiting for request") 1717 } 1718 } 1719 1720 func getSlash(st *serverTester) { st.bodylessReq1() } 1721 1722 func TestServer_Response_NoData(t *testing.T) { 1723 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 1724 // Nothing. 1725 return nil 1726 }, func(st *serverTester) { 1727 getSlash(st) 1728 hf := st.wantHeaders() 1729 if !hf.StreamEnded() { 1730 t.Fatal("want END_STREAM flag") 1731 } 1732 if !hf.HeadersEnded() { 1733 t.Fatal("want END_HEADERS flag") 1734 } 1735 }) 1736 } 1737 1738 func TestServer_Response_NoData_Header_FooBar(t *testing.T) { 1739 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 1740 w.Header().Set("Foo-Bar", "some-value") 1741 return nil 1742 }, func(st *serverTester) { 1743 getSlash(st) 1744 hf := st.wantHeaders() 1745 if !hf.StreamEnded() { 1746 t.Fatal("want END_STREAM flag") 1747 } 1748 if !hf.HeadersEnded() { 1749 t.Fatal("want END_HEADERS flag") 1750 } 1751 goth := st.decodeHeader(hf.HeaderBlockFragment()) 1752 wanth := [][2]string{ 1753 {":status", "200"}, 1754 {"foo-bar", "some-value"}, 1755 {"content-length", "0"}, 1756 } 1757 if !reflect.DeepEqual(goth, wanth) { 1758 t.Errorf("Got headers %v; want %v", goth, wanth) 1759 } 1760 }) 1761 } 1762 1763 // Reject content-length headers containing a sign. 1764 // See https://golang.org/issue/39017 1765 func TestServerIgnoresContentLengthSignWhenWritingChunks(t *testing.T) { 1766 tests := []struct { 1767 name string 1768 cl string 1769 wantCL string 1770 }{ 1771 { 1772 name: "proper content-length", 1773 cl: "3", 1774 wantCL: "3", 1775 }, 1776 { 1777 name: "ignore cl with plus sign", 1778 cl: "+3", 1779 wantCL: "0", 1780 }, 1781 { 1782 name: "ignore cl with minus sign", 1783 cl: "-3", 1784 wantCL: "0", 1785 }, 1786 { 1787 name: "max int64, for safe uint64->int64 conversion", 1788 cl: "9223372036854775807", 1789 wantCL: "9223372036854775807", 1790 }, 1791 { 1792 name: "overflows int64, so ignored", 1793 cl: "9223372036854775808", 1794 wantCL: "0", 1795 }, 1796 } 1797 1798 for _, tt := range tests { 1799 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 1800 w.Header().Set("content-length", tt.cl) 1801 return nil 1802 }, func(st *serverTester) { 1803 getSlash(st) 1804 hf := st.wantHeaders() 1805 goth := st.decodeHeader(hf.HeaderBlockFragment()) 1806 wanth := [][2]string{ 1807 {":status", "200"}, 1808 {"content-length", tt.wantCL}, 1809 } 1810 if !reflect.DeepEqual(goth, wanth) { 1811 t.Errorf("For case %q, value %q, got = %q; want %q", tt.name, tt.cl, goth, wanth) 1812 } 1813 }) 1814 } 1815 } 1816 1817 // Reject content-length headers containing a sign. 1818 // See https://golang.org/issue/39017 1819 func TestServerRejectsContentLengthWithSignNewRequests(t *testing.T) { 1820 tests := []struct { 1821 name string 1822 cl string 1823 wantCL int64 1824 }{ 1825 { 1826 name: "proper content-length", 1827 cl: "3", 1828 wantCL: 3, 1829 }, 1830 { 1831 name: "ignore cl with plus sign", 1832 cl: "+3", 1833 wantCL: 0, 1834 }, 1835 { 1836 name: "ignore cl with minus sign", 1837 cl: "-3", 1838 wantCL: 0, 1839 }, 1840 { 1841 name: "max int64, for safe uint64->int64 conversion", 1842 cl: "9223372036854775807", 1843 wantCL: 9223372036854775807, 1844 }, 1845 { 1846 name: "overflows int64, so ignored", 1847 cl: "9223372036854775808", 1848 wantCL: 0, 1849 }, 1850 } 1851 1852 for _, tt := range tests { 1853 tt := tt 1854 t.Run(tt.name, func(t *testing.T) { 1855 writeReq := func(st *serverTester) { 1856 st.writeHeaders(HeadersFrameParam{ 1857 StreamID: 1, // clients send odd numbers 1858 BlockFragment: st.encodeHeader("content-length", tt.cl), 1859 EndStream: false, 1860 EndHeaders: true, 1861 }) 1862 st.writeData(1, false, []byte("")) 1863 } 1864 checkReq := func(r *http.Request) { 1865 if r.ContentLength != tt.wantCL { 1866 t.Fatalf("Got: %q\nWant: %q", r.ContentLength, tt.wantCL) 1867 } 1868 } 1869 testServerRequest(t, writeReq, checkReq) 1870 }) 1871 } 1872 } 1873 1874 func TestServer_Response_Data_Sniff_DoesntOverride(t *testing.T) { 1875 const msg = "<html>this is HTML." 1876 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 1877 w.Header().Set("Content-Type", "foo/bar") 1878 io.WriteString(w, msg) 1879 return nil 1880 }, func(st *serverTester) { 1881 getSlash(st) 1882 hf := st.wantHeaders() 1883 if hf.StreamEnded() { 1884 t.Fatal("don't want END_STREAM, expecting data") 1885 } 1886 if !hf.HeadersEnded() { 1887 t.Fatal("want END_HEADERS flag") 1888 } 1889 goth := st.decodeHeader(hf.HeaderBlockFragment()) 1890 wanth := [][2]string{ 1891 {":status", "200"}, 1892 {"content-type", "foo/bar"}, 1893 {"content-length", strconv.Itoa(len(msg))}, 1894 } 1895 if !reflect.DeepEqual(goth, wanth) { 1896 t.Errorf("Got headers %v; want %v", goth, wanth) 1897 } 1898 df := st.wantData() 1899 if !df.StreamEnded() { 1900 t.Error("expected DATA to have END_STREAM flag") 1901 } 1902 if got := string(df.Data()); got != msg { 1903 t.Errorf("got DATA %q; want %q", got, msg) 1904 } 1905 }) 1906 } 1907 1908 func TestServer_Response_TransferEncoding_chunked(t *testing.T) { 1909 const msg = "hi" 1910 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 1911 w.Header().Set("Transfer-Encoding", "chunked") // should be stripped 1912 io.WriteString(w, msg) 1913 return nil 1914 }, func(st *serverTester) { 1915 getSlash(st) 1916 hf := st.wantHeaders() 1917 goth := st.decodeHeader(hf.HeaderBlockFragment()) 1918 wanth := [][2]string{ 1919 {":status", "200"}, 1920 {"content-type", "text/plain; charset=utf-8"}, 1921 {"content-length", strconv.Itoa(len(msg))}, 1922 } 1923 if !reflect.DeepEqual(goth, wanth) { 1924 t.Errorf("Got headers %v; want %v", goth, wanth) 1925 } 1926 }) 1927 } 1928 1929 // Header accessed only after the initial write. 1930 func TestServer_Response_Data_IgnoreHeaderAfterWrite_After(t *testing.T) { 1931 const msg = "<html>this is HTML." 1932 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 1933 io.WriteString(w, msg) 1934 w.Header().Set("foo", "should be ignored") 1935 return nil 1936 }, func(st *serverTester) { 1937 getSlash(st) 1938 hf := st.wantHeaders() 1939 if hf.StreamEnded() { 1940 t.Fatal("unexpected END_STREAM") 1941 } 1942 if !hf.HeadersEnded() { 1943 t.Fatal("want END_HEADERS flag") 1944 } 1945 goth := st.decodeHeader(hf.HeaderBlockFragment()) 1946 wanth := [][2]string{ 1947 {":status", "200"}, 1948 {"content-type", "text/html; charset=utf-8"}, 1949 {"content-length", strconv.Itoa(len(msg))}, 1950 } 1951 if !reflect.DeepEqual(goth, wanth) { 1952 t.Errorf("Got headers %v; want %v", goth, wanth) 1953 } 1954 }) 1955 } 1956 1957 // Header accessed before the initial write and later mutated. 1958 func TestServer_Response_Data_IgnoreHeaderAfterWrite_Overwrite(t *testing.T) { 1959 const msg = "<html>this is HTML." 1960 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 1961 w.Header().Set("foo", "proper value") 1962 io.WriteString(w, msg) 1963 w.Header().Set("foo", "should be ignored") 1964 return nil 1965 }, func(st *serverTester) { 1966 getSlash(st) 1967 hf := st.wantHeaders() 1968 if hf.StreamEnded() { 1969 t.Fatal("unexpected END_STREAM") 1970 } 1971 if !hf.HeadersEnded() { 1972 t.Fatal("want END_HEADERS flag") 1973 } 1974 goth := st.decodeHeader(hf.HeaderBlockFragment()) 1975 wanth := [][2]string{ 1976 {":status", "200"}, 1977 {"foo", "proper value"}, 1978 {"content-type", "text/html; charset=utf-8"}, 1979 {"content-length", strconv.Itoa(len(msg))}, 1980 } 1981 if !reflect.DeepEqual(goth, wanth) { 1982 t.Errorf("Got headers %v; want %v", goth, wanth) 1983 } 1984 }) 1985 } 1986 1987 func TestServer_Response_Data_SniffLenType(t *testing.T) { 1988 const msg = "<html>this is HTML." 1989 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 1990 io.WriteString(w, msg) 1991 return nil 1992 }, func(st *serverTester) { 1993 getSlash(st) 1994 hf := st.wantHeaders() 1995 if hf.StreamEnded() { 1996 t.Fatal("don't want END_STREAM, expecting data") 1997 } 1998 if !hf.HeadersEnded() { 1999 t.Fatal("want END_HEADERS flag") 2000 } 2001 goth := st.decodeHeader(hf.HeaderBlockFragment()) 2002 wanth := [][2]string{ 2003 {":status", "200"}, 2004 {"content-type", "text/html; charset=utf-8"}, 2005 {"content-length", strconv.Itoa(len(msg))}, 2006 } 2007 if !reflect.DeepEqual(goth, wanth) { 2008 t.Errorf("Got headers %v; want %v", goth, wanth) 2009 } 2010 df := st.wantData() 2011 if !df.StreamEnded() { 2012 t.Error("expected DATA to have END_STREAM flag") 2013 } 2014 if got := string(df.Data()); got != msg { 2015 t.Errorf("got DATA %q; want %q", got, msg) 2016 } 2017 }) 2018 } 2019 2020 func TestServer_Response_Header_Flush_MidWrite(t *testing.T) { 2021 const msg = "<html>this is HTML" 2022 const msg2 = ", and this is the next chunk" 2023 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 2024 io.WriteString(w, msg) 2025 w.(http.Flusher).Flush() 2026 io.WriteString(w, msg2) 2027 return nil 2028 }, func(st *serverTester) { 2029 getSlash(st) 2030 hf := st.wantHeaders() 2031 if hf.StreamEnded() { 2032 t.Fatal("unexpected END_STREAM flag") 2033 } 2034 if !hf.HeadersEnded() { 2035 t.Fatal("want END_HEADERS flag") 2036 } 2037 goth := st.decodeHeader(hf.HeaderBlockFragment()) 2038 wanth := [][2]string{ 2039 {":status", "200"}, 2040 {"content-type", "text/html; charset=utf-8"}, // sniffed 2041 // and no content-length 2042 } 2043 if !reflect.DeepEqual(goth, wanth) { 2044 t.Errorf("Got headers %v; want %v", goth, wanth) 2045 } 2046 { 2047 df := st.wantData() 2048 if df.StreamEnded() { 2049 t.Error("unexpected END_STREAM flag") 2050 } 2051 if got := string(df.Data()); got != msg { 2052 t.Errorf("got DATA %q; want %q", got, msg) 2053 } 2054 } 2055 { 2056 df := st.wantData() 2057 if !df.StreamEnded() { 2058 t.Error("wanted END_STREAM flag on last data chunk") 2059 } 2060 if got := string(df.Data()); got != msg2 { 2061 t.Errorf("got DATA %q; want %q", got, msg2) 2062 } 2063 } 2064 }) 2065 } 2066 2067 func TestServer_Response_LargeWrite(t *testing.T) { 2068 const size = 1 << 20 2069 const maxFrameSize = 16 << 10 2070 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 2071 n, err := w.Write(bytes.Repeat([]byte("a"), size)) 2072 if err != nil { 2073 return fmt.Errorf("Write error: %v", err) 2074 } 2075 if n != size { 2076 return fmt.Errorf("wrong size %d from Write", n) 2077 } 2078 return nil 2079 }, func(st *serverTester) { 2080 if err := st.fr.WriteSettings( 2081 Setting{SettingInitialWindowSize, 0}, 2082 Setting{SettingMaxFrameSize, maxFrameSize}, 2083 ); err != nil { 2084 t.Fatal(err) 2085 } 2086 st.wantSettingsAck() 2087 2088 getSlash(st) // make the single request 2089 2090 // Give the handler quota to write: 2091 if err := st.fr.WriteWindowUpdate(1, size); err != nil { 2092 t.Fatal(err) 2093 } 2094 // Give the handler quota to write to connection-level 2095 // window as well 2096 if err := st.fr.WriteWindowUpdate(0, size); err != nil { 2097 t.Fatal(err) 2098 } 2099 hf := st.wantHeaders() 2100 if hf.StreamEnded() { 2101 t.Fatal("unexpected END_STREAM flag") 2102 } 2103 if !hf.HeadersEnded() { 2104 t.Fatal("want END_HEADERS flag") 2105 } 2106 goth := st.decodeHeader(hf.HeaderBlockFragment()) 2107 wanth := [][2]string{ 2108 {":status", "200"}, 2109 {"content-type", "text/plain; charset=utf-8"}, // sniffed 2110 // and no content-length 2111 } 2112 if !reflect.DeepEqual(goth, wanth) { 2113 t.Errorf("Got headers %v; want %v", goth, wanth) 2114 } 2115 var bytes, frames int 2116 for { 2117 df := st.wantData() 2118 bytes += len(df.Data()) 2119 frames++ 2120 for _, b := range df.Data() { 2121 if b != 'a' { 2122 t.Fatal("non-'a' byte seen in DATA") 2123 } 2124 } 2125 if df.StreamEnded() { 2126 break 2127 } 2128 } 2129 if bytes != size { 2130 t.Errorf("Got %d bytes; want %d", bytes, size) 2131 } 2132 if want := int(size / maxFrameSize); frames < want || frames > want*2 { 2133 t.Errorf("Got %d frames; want %d", frames, size) 2134 } 2135 }) 2136 } 2137 2138 // Test that the handler can't write more than the client allows 2139 func TestServer_Response_LargeWrite_FlowControlled(t *testing.T) { 2140 // Make these reads. Before each read, the client adds exactly enough 2141 // flow-control to satisfy the read. Numbers chosen arbitrarily. 2142 reads := []int{123, 1, 13, 127} 2143 size := 0 2144 for _, n := range reads { 2145 size += n 2146 } 2147 2148 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 2149 w.(http.Flusher).Flush() 2150 n, err := w.Write(bytes.Repeat([]byte("a"), size)) 2151 if err != nil { 2152 return fmt.Errorf("Write error: %v", err) 2153 } 2154 if n != size { 2155 return fmt.Errorf("wrong size %d from Write", n) 2156 } 2157 return nil 2158 }, func(st *serverTester) { 2159 // Set the window size to something explicit for this test. 2160 // It's also how much initial data we expect. 2161 if err := st.fr.WriteSettings(Setting{SettingInitialWindowSize, uint32(reads[0])}); err != nil { 2162 t.Fatal(err) 2163 } 2164 st.wantSettingsAck() 2165 2166 getSlash(st) // make the single request 2167 2168 hf := st.wantHeaders() 2169 if hf.StreamEnded() { 2170 t.Fatal("unexpected END_STREAM flag") 2171 } 2172 if !hf.HeadersEnded() { 2173 t.Fatal("want END_HEADERS flag") 2174 } 2175 2176 df := st.wantData() 2177 if got := len(df.Data()); got != reads[0] { 2178 t.Fatalf("Initial window size = %d but got DATA with %d bytes", reads[0], got) 2179 } 2180 2181 for _, quota := range reads[1:] { 2182 if err := st.fr.WriteWindowUpdate(1, uint32(quota)); err != nil { 2183 t.Fatal(err) 2184 } 2185 df := st.wantData() 2186 if int(quota) != len(df.Data()) { 2187 t.Fatalf("read %d bytes after giving %d quota", len(df.Data()), quota) 2188 } 2189 } 2190 }) 2191 } 2192 2193 // Test that the handler blocked in a Write is unblocked if the server sends a RST_STREAM. 2194 func TestServer_Response_RST_Unblocks_LargeWrite(t *testing.T) { 2195 const size = 1 << 20 2196 const maxFrameSize = 16 << 10 2197 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 2198 w.(http.Flusher).Flush() 2199 errc := make(chan error, 1) 2200 go func() { 2201 _, err := w.Write(bytes.Repeat([]byte("a"), size)) 2202 errc <- err 2203 }() 2204 select { 2205 case err := <-errc: 2206 if err == nil { 2207 return errors.New("unexpected nil error from Write in handler") 2208 } 2209 return nil 2210 case <-time.After(2 * time.Second): 2211 return errors.New("timeout waiting for Write in handler") 2212 } 2213 }, func(st *serverTester) { 2214 if err := st.fr.WriteSettings( 2215 Setting{SettingInitialWindowSize, 0}, 2216 Setting{SettingMaxFrameSize, maxFrameSize}, 2217 ); err != nil { 2218 t.Fatal(err) 2219 } 2220 st.wantSettingsAck() 2221 2222 getSlash(st) // make the single request 2223 2224 hf := st.wantHeaders() 2225 if hf.StreamEnded() { 2226 t.Fatal("unexpected END_STREAM flag") 2227 } 2228 if !hf.HeadersEnded() { 2229 t.Fatal("want END_HEADERS flag") 2230 } 2231 2232 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil { 2233 t.Fatal(err) 2234 } 2235 }) 2236 } 2237 2238 func TestServer_Response_Empty_Data_Not_FlowControlled(t *testing.T) { 2239 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 2240 w.(http.Flusher).Flush() 2241 // Nothing; send empty DATA 2242 return nil 2243 }, func(st *serverTester) { 2244 // Handler gets no data quota: 2245 if err := st.fr.WriteSettings(Setting{SettingInitialWindowSize, 0}); err != nil { 2246 t.Fatal(err) 2247 } 2248 st.wantSettingsAck() 2249 2250 getSlash(st) // make the single request 2251 2252 hf := st.wantHeaders() 2253 if hf.StreamEnded() { 2254 t.Fatal("unexpected END_STREAM flag") 2255 } 2256 if !hf.HeadersEnded() { 2257 t.Fatal("want END_HEADERS flag") 2258 } 2259 2260 df := st.wantData() 2261 if got := len(df.Data()); got != 0 { 2262 t.Fatalf("unexpected %d DATA bytes; want 0", got) 2263 } 2264 if !df.StreamEnded() { 2265 t.Fatal("DATA didn't have END_STREAM") 2266 } 2267 }) 2268 } 2269 2270 func TestServer_Response_Automatic100Continue(t *testing.T) { 2271 const msg = "foo" 2272 const reply = "bar" 2273 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 2274 if v := r.Header.Get("Expect"); v != "" { 2275 t.Errorf("Expect header = %q; want empty", v) 2276 } 2277 buf := make([]byte, len(msg)) 2278 // This read should trigger the 100-continue being sent. 2279 if n, err := io.ReadFull(r.Body, buf); err != nil || n != len(msg) || string(buf) != msg { 2280 return fmt.Errorf("ReadFull = %q, %v; want %q, nil", buf[:n], err, msg) 2281 } 2282 _, err := io.WriteString(w, reply) 2283 return err 2284 }, func(st *serverTester) { 2285 st.writeHeaders(HeadersFrameParam{ 2286 StreamID: 1, // clients send odd numbers 2287 BlockFragment: st.encodeHeader(":method", "POST", "expect", "100-continue"), 2288 EndStream: false, 2289 EndHeaders: true, 2290 }) 2291 hf := st.wantHeaders() 2292 if hf.StreamEnded() { 2293 t.Fatal("unexpected END_STREAM flag") 2294 } 2295 if !hf.HeadersEnded() { 2296 t.Fatal("want END_HEADERS flag") 2297 } 2298 goth := st.decodeHeader(hf.HeaderBlockFragment()) 2299 wanth := [][2]string{ 2300 {":status", "100"}, 2301 } 2302 if !reflect.DeepEqual(goth, wanth) { 2303 t.Fatalf("Got headers %v; want %v", goth, wanth) 2304 } 2305 2306 // Okay, they sent status 100, so we can send our 2307 // gigantic and/or sensitive "foo" payload now. 2308 st.writeData(1, true, []byte(msg)) 2309 2310 st.wantWindowUpdate(0, uint32(len(msg))) 2311 2312 hf = st.wantHeaders() 2313 if hf.StreamEnded() { 2314 t.Fatal("expected data to follow") 2315 } 2316 if !hf.HeadersEnded() { 2317 t.Fatal("want END_HEADERS flag") 2318 } 2319 goth = st.decodeHeader(hf.HeaderBlockFragment()) 2320 wanth = [][2]string{ 2321 {":status", "200"}, 2322 {"content-type", "text/plain; charset=utf-8"}, 2323 {"content-length", strconv.Itoa(len(reply))}, 2324 } 2325 if !reflect.DeepEqual(goth, wanth) { 2326 t.Errorf("Got headers %v; want %v", goth, wanth) 2327 } 2328 2329 df := st.wantData() 2330 if string(df.Data()) != reply { 2331 t.Errorf("Client read %q; want %q", df.Data(), reply) 2332 } 2333 if !df.StreamEnded() { 2334 t.Errorf("expect data stream end") 2335 } 2336 }) 2337 } 2338 2339 func TestServer_HandlerWriteErrorOnDisconnect(t *testing.T) { 2340 errc := make(chan error, 1) 2341 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 2342 p := []byte("some data.\n") 2343 for { 2344 _, err := w.Write(p) 2345 if err != nil { 2346 errc <- err 2347 return nil 2348 } 2349 } 2350 }, func(st *serverTester) { 2351 st.writeHeaders(HeadersFrameParam{ 2352 StreamID: 1, 2353 BlockFragment: st.encodeHeader(), 2354 EndStream: false, 2355 EndHeaders: true, 2356 }) 2357 hf := st.wantHeaders() 2358 if hf.StreamEnded() { 2359 t.Fatal("unexpected END_STREAM flag") 2360 } 2361 if !hf.HeadersEnded() { 2362 t.Fatal("want END_HEADERS flag") 2363 } 2364 // Close the connection and wait for the handler to (hopefully) notice. 2365 st.cc.Close() 2366 select { 2367 case <-errc: 2368 case <-time.After(5 * time.Second): 2369 t.Error("timeout") 2370 } 2371 }) 2372 } 2373 2374 func TestServer_Rejects_Too_Many_Streams(t *testing.T) { 2375 const testPath = "/some/path" 2376 2377 inHandler := make(chan uint32) 2378 leaveHandler := make(chan bool) 2379 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2380 id := w.(*responseWriter).rws.stream.id 2381 inHandler <- id 2382 if id == 1+(defaultMaxStreams+1)*2 && r.URL.Path != testPath { 2383 t.Errorf("decoded final path as %q; want %q", r.URL.Path, testPath) 2384 } 2385 <-leaveHandler 2386 }) 2387 defer st.Close() 2388 st.greet() 2389 nextStreamID := uint32(1) 2390 streamID := func() uint32 { 2391 defer func() { nextStreamID += 2 }() 2392 return nextStreamID 2393 } 2394 sendReq := func(id uint32, headers ...string) { 2395 st.writeHeaders(HeadersFrameParam{ 2396 StreamID: id, 2397 BlockFragment: st.encodeHeader(headers...), 2398 EndStream: true, 2399 EndHeaders: true, 2400 }) 2401 } 2402 for i := 0; i < defaultMaxStreams; i++ { 2403 sendReq(streamID()) 2404 <-inHandler 2405 } 2406 defer func() { 2407 for i := 0; i < defaultMaxStreams; i++ { 2408 leaveHandler <- true 2409 } 2410 }() 2411 2412 // And this one should cross the limit: 2413 // (It's also sent as a CONTINUATION, to verify we still track the decoder context, 2414 // even if we're rejecting it) 2415 rejectID := streamID() 2416 headerBlock := st.encodeHeader(":path", testPath) 2417 frag1, frag2 := headerBlock[:3], headerBlock[3:] 2418 st.writeHeaders(HeadersFrameParam{ 2419 StreamID: rejectID, 2420 BlockFragment: frag1, 2421 EndStream: true, 2422 EndHeaders: false, // CONTINUATION coming 2423 }) 2424 if err := st.fr.WriteContinuation(rejectID, true, frag2); err != nil { 2425 t.Fatal(err) 2426 } 2427 st.wantRSTStream(rejectID, ErrCodeProtocol) 2428 2429 // But let a handler finish: 2430 leaveHandler <- true 2431 st.wantHeaders() 2432 2433 // And now another stream should be able to start: 2434 goodID := streamID() 2435 sendReq(goodID, ":path", testPath) 2436 select { 2437 case got := <-inHandler: 2438 if got != goodID { 2439 t.Errorf("Got stream %d; want %d", got, goodID) 2440 } 2441 case <-time.After(3 * time.Second): 2442 t.Error("timeout waiting for handler") 2443 } 2444 } 2445 2446 // So many response headers that the server needs to use CONTINUATION frames: 2447 func TestServer_Response_ManyHeaders_With_Continuation(t *testing.T) { 2448 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 2449 h := w.Header() 2450 for i := 0; i < 5000; i++ { 2451 h.Set(fmt.Sprintf("x-header-%d", i), fmt.Sprintf("x-value-%d", i)) 2452 } 2453 return nil 2454 }, func(st *serverTester) { 2455 getSlash(st) 2456 hf := st.wantHeaders() 2457 if hf.HeadersEnded() { 2458 t.Fatal("got unwanted END_HEADERS flag") 2459 } 2460 n := 0 2461 for { 2462 n++ 2463 cf := st.wantContinuation() 2464 if cf.HeadersEnded() { 2465 break 2466 } 2467 } 2468 if n < 5 { 2469 t.Errorf("Only got %d CONTINUATION frames; expected 5+ (currently 6)", n) 2470 } 2471 }) 2472 } 2473 2474 // This previously crashed (reported by Mathieu Lonjaret as observed 2475 // while using Camlistore) because we got a DATA frame from the client 2476 // after the handler exited and our logic at the time was wrong, 2477 // keeping a stream in the map in stateClosed, which tickled an 2478 // invariant check later when we tried to remove that stream (via 2479 // defer sc.closeAllStreamsOnConnClose) when the serverConn serve loop 2480 // ended. 2481 func TestServer_NoCrash_HandlerClose_Then_ClientClose(t *testing.T) { 2482 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 2483 // nothing 2484 return nil 2485 }, func(st *serverTester) { 2486 st.writeHeaders(HeadersFrameParam{ 2487 StreamID: 1, 2488 BlockFragment: st.encodeHeader(), 2489 EndStream: false, // DATA is coming 2490 EndHeaders: true, 2491 }) 2492 hf := st.wantHeaders() 2493 if !hf.HeadersEnded() || !hf.StreamEnded() { 2494 t.Fatalf("want END_HEADERS+END_STREAM, got %v", hf) 2495 } 2496 2497 // Sent when the a Handler closes while a client has 2498 // indicated it's still sending DATA: 2499 st.wantRSTStream(1, ErrCodeNo) 2500 2501 // Now the handler has ended, so it's ended its 2502 // stream, but the client hasn't closed its side 2503 // (stateClosedLocal). So send more data and verify 2504 // it doesn't crash with an internal invariant panic, like 2505 // it did before. 2506 st.writeData(1, true, []byte("foo")) 2507 2508 // Get our flow control bytes back, since the handler didn't get them. 2509 st.wantWindowUpdate(0, uint32(len("foo"))) 2510 2511 // Sent after a peer sends data anyway (admittedly the 2512 // previous RST_STREAM might've still been in-flight), 2513 // but they'll get the more friendly 'cancel' code 2514 // first. 2515 st.wantRSTStream(1, ErrCodeStreamClosed) 2516 2517 // Set up a bunch of machinery to record the panic we saw 2518 // previously. 2519 var ( 2520 panMu sync.Mutex 2521 panicVal interface{} 2522 ) 2523 2524 testHookOnPanicMu.Lock() 2525 testHookOnPanic = func(sc *serverConn, pv interface{}) bool { 2526 panMu.Lock() 2527 panicVal = pv 2528 panMu.Unlock() 2529 return true 2530 } 2531 testHookOnPanicMu.Unlock() 2532 2533 // Now force the serve loop to end, via closing the connection. 2534 st.cc.Close() 2535 select { 2536 case <-st.sc.doneServing: 2537 // Loop has exited. 2538 panMu.Lock() 2539 got := panicVal 2540 panMu.Unlock() 2541 if got != nil { 2542 t.Errorf("Got panic: %v", got) 2543 } 2544 case <-time.After(5 * time.Second): 2545 t.Error("timeout") 2546 } 2547 }) 2548 } 2549 2550 func TestServer_Rejects_TLS10(t *testing.T) { testRejectTLS(t, tls.VersionTLS10) } 2551 func TestServer_Rejects_TLS11(t *testing.T) { testRejectTLS(t, tls.VersionTLS11) } 2552 2553 func testRejectTLS(t *testing.T, max uint16) { 2554 st := newServerTester(t, nil, func(c *tls.Config) { 2555 c.MaxVersion = max 2556 }) 2557 defer st.Close() 2558 gf := st.wantGoAway() 2559 if got, want := gf.ErrCode, ErrCodeInadequateSecurity; got != want { 2560 t.Errorf("Got error code %v; want %v", got, want) 2561 } 2562 } 2563 2564 func TestServer_Rejects_TLSBadCipher(t *testing.T) { 2565 st := newServerTester(t, nil, func(c *tls.Config) { 2566 // All TLS 1.3 ciphers are good. Test with TLS 1.2. 2567 c.MaxVersion = tls.VersionTLS12 2568 // Only list bad ones: 2569 c.CipherSuites = []uint16{ 2570 tls.TLS_RSA_WITH_RC4_128_SHA, 2571 tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, 2572 tls.TLS_RSA_WITH_AES_128_CBC_SHA, 2573 tls.TLS_RSA_WITH_AES_256_CBC_SHA, 2574 tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 2575 tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 2576 tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 2577 tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, 2578 tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 2579 tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 2580 tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 2581 cipher_TLS_RSA_WITH_AES_128_CBC_SHA256, 2582 } 2583 }) 2584 defer st.Close() 2585 gf := st.wantGoAway() 2586 if got, want := gf.ErrCode, ErrCodeInadequateSecurity; got != want { 2587 t.Errorf("Got error code %v; want %v", got, want) 2588 } 2589 } 2590 2591 func TestServer_Advertises_Common_Cipher(t *testing.T) { 2592 const requiredSuite = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 2593 st := newServerTester(t, nil, func(c *tls.Config) { 2594 // Have the client only support the one required by the spec. 2595 c.CipherSuites = []uint16{requiredSuite} 2596 }, func(ts *httptest.Server) { 2597 var srv *http.Server = ts.Config 2598 // Have the server configured with no specific cipher suites. 2599 // This tests that Go's defaults include the required one. 2600 srv.TLSConfig = nil 2601 }) 2602 defer st.Close() 2603 st.greet() 2604 } 2605 2606 func (st *serverTester) onHeaderField(f hpack.HeaderField) { 2607 if f.Name == "date" { 2608 return 2609 } 2610 st.decodedHeaders = append(st.decodedHeaders, [2]string{f.Name, f.Value}) 2611 } 2612 2613 func (st *serverTester) decodeHeader(headerBlock []byte) (pairs [][2]string) { 2614 st.decodedHeaders = nil 2615 if _, err := st.hpackDec.Write(headerBlock); err != nil { 2616 st.t.Fatalf("hpack decoding error: %v", err) 2617 } 2618 if err := st.hpackDec.Close(); err != nil { 2619 st.t.Fatalf("hpack decoding error: %v", err) 2620 } 2621 return st.decodedHeaders 2622 } 2623 2624 // testServerResponse sets up an idle HTTP/2 connection. The client function should 2625 // write a single request that must be handled by the handler. This waits up to 5s 2626 // for client to return, then up to an additional 2s for the handler to return. 2627 func testServerResponse(t testing.TB, 2628 handler func(http.ResponseWriter, *http.Request) error, 2629 client func(*serverTester), 2630 ) { 2631 errc := make(chan error, 1) 2632 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2633 if r.Body == nil { 2634 t.Fatal("nil Body") 2635 } 2636 errc <- handler(w, r) 2637 }) 2638 defer st.Close() 2639 2640 donec := make(chan bool) 2641 go func() { 2642 defer close(donec) 2643 st.greet() 2644 client(st) 2645 }() 2646 2647 select { 2648 case <-donec: 2649 case <-time.After(5 * time.Second): 2650 t.Fatal("timeout in client") 2651 } 2652 2653 select { 2654 case err := <-errc: 2655 if err != nil { 2656 t.Fatalf("Error in handler: %v", err) 2657 } 2658 case <-time.After(2 * time.Second): 2659 t.Fatal("timeout in handler") 2660 } 2661 } 2662 2663 // readBodyHandler returns an http Handler func that reads len(want) 2664 // bytes from r.Body and fails t if the contents read were not 2665 // the value of want. 2666 func readBodyHandler(t *testing.T, want string) func(w http.ResponseWriter, r *http.Request) { 2667 return func(w http.ResponseWriter, r *http.Request) { 2668 buf := make([]byte, len(want)) 2669 _, err := io.ReadFull(r.Body, buf) 2670 if err != nil { 2671 t.Error(err) 2672 return 2673 } 2674 if string(buf) != want { 2675 t.Errorf("read %q; want %q", buf, want) 2676 } 2677 } 2678 } 2679 2680 // TestServerWithCurl currently fails, hence the LenientCipherSuites test. See: 2681 // https://github.com/tatsuhiro-t/nghttp2/issues/140 & 2682 // http://sourceforge.net/p/curl/bugs/1472/ 2683 func TestServerWithCurl(t *testing.T) { testServerWithCurl(t, false) } 2684 func TestServerWithCurl_LenientCipherSuites(t *testing.T) { testServerWithCurl(t, true) } 2685 2686 func testServerWithCurl(t *testing.T, permitProhibitedCipherSuites bool) { 2687 if runtime.GOOS != "linux" { 2688 t.Skip("skipping Docker test when not on Linux; requires --net which won't work with boot2docker anyway") 2689 } 2690 if testing.Short() { 2691 t.Skip("skipping curl test in short mode") 2692 } 2693 requireCurl(t) 2694 var gotConn int32 2695 testHookOnConn = func() { atomic.StoreInt32(&gotConn, 1) } 2696 2697 const msg = "Hello from curl!\n" 2698 ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 2699 w.Header().Set("Foo", "Bar") 2700 w.Header().Set("Client-Proto", r.Proto) 2701 io.WriteString(w, msg) 2702 })) 2703 ConfigureServer(ts.Config, &Server{ 2704 PermitProhibitedCipherSuites: permitProhibitedCipherSuites, 2705 }) 2706 ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config 2707 ts.StartTLS() 2708 defer ts.Close() 2709 2710 t.Logf("Running test server for curl to hit at: %s", ts.URL) 2711 container := curl(t, "--silent", "--http2", "--insecure", "-v", ts.URL) 2712 defer kill(container) 2713 resc := make(chan interface{}, 1) 2714 go func() { 2715 res, err := dockerLogs(container) 2716 if err != nil { 2717 resc <- err 2718 } else { 2719 resc <- res 2720 } 2721 }() 2722 select { 2723 case res := <-resc: 2724 if err, ok := res.(error); ok { 2725 t.Fatal(err) 2726 } 2727 body := string(res.([]byte)) 2728 // Search for both "key: value" and "key:value", since curl changed their format 2729 // Our Dockerfile contains the latest version (no space), but just in case people 2730 // didn't rebuild, check both. 2731 if !strings.Contains(body, "foo: Bar") && !strings.Contains(body, "foo:Bar") { 2732 t.Errorf("didn't see foo: Bar header") 2733 t.Logf("Got: %s", body) 2734 } 2735 if !strings.Contains(body, "client-proto: HTTP/2") && !strings.Contains(body, "client-proto:HTTP/2") { 2736 t.Errorf("didn't see client-proto: HTTP/2 header") 2737 t.Logf("Got: %s", res) 2738 } 2739 if !strings.Contains(string(res.([]byte)), msg) { 2740 t.Errorf("didn't see %q content", msg) 2741 t.Logf("Got: %s", res) 2742 } 2743 case <-time.After(3 * time.Second): 2744 t.Errorf("timeout waiting for curl") 2745 } 2746 2747 if atomic.LoadInt32(&gotConn) == 0 { 2748 t.Error("never saw an http2 connection") 2749 } 2750 } 2751 2752 var doh2load = flag.Bool("h2load", false, "Run h2load test") 2753 2754 func TestServerWithH2Load(t *testing.T) { 2755 if !*doh2load { 2756 t.Skip("Skipping without --h2load flag.") 2757 } 2758 if runtime.GOOS != "linux" { 2759 t.Skip("skipping Docker test when not on Linux; requires --net which won't work with boot2docker anyway") 2760 } 2761 requireH2load(t) 2762 2763 msg := strings.Repeat("Hello, h2load!\n", 5000) 2764 ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 2765 io.WriteString(w, msg) 2766 w.(http.Flusher).Flush() 2767 io.WriteString(w, msg) 2768 })) 2769 ts.StartTLS() 2770 defer ts.Close() 2771 2772 cmd := exec.Command("docker", "run", "--net=host", "--entrypoint=/usr/local/bin/h2load", "gohttp2/curl", 2773 "-n100000", "-c100", "-m100", ts.URL) 2774 cmd.Stdout = os.Stdout 2775 cmd.Stderr = os.Stderr 2776 if err := cmd.Run(); err != nil { 2777 t.Fatal(err) 2778 } 2779 } 2780 2781 // Issue 12843 2782 func TestServerDoS_MaxHeaderListSize(t *testing.T) { 2783 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}) 2784 defer st.Close() 2785 2786 // shake hands 2787 frameSize := defaultMaxReadFrameSize 2788 var advHeaderListSize *uint32 2789 st.greetAndCheckSettings(func(s Setting) error { 2790 switch s.ID { 2791 case SettingMaxFrameSize: 2792 if s.Val < minMaxFrameSize { 2793 frameSize = minMaxFrameSize 2794 } else if s.Val > maxFrameSize { 2795 frameSize = maxFrameSize 2796 } else { 2797 frameSize = int(s.Val) 2798 } 2799 case SettingMaxHeaderListSize: 2800 advHeaderListSize = &s.Val 2801 } 2802 return nil 2803 }) 2804 2805 if advHeaderListSize == nil { 2806 t.Errorf("server didn't advertise a max header list size") 2807 } else if *advHeaderListSize == 0 { 2808 t.Errorf("server advertised a max header list size of 0") 2809 } 2810 2811 st.encodeHeaderField(":method", "GET") 2812 st.encodeHeaderField(":path", "/") 2813 st.encodeHeaderField(":scheme", "https") 2814 cookie := strings.Repeat("*", 4058) 2815 st.encodeHeaderField("cookie", cookie) 2816 st.writeHeaders(HeadersFrameParam{ 2817 StreamID: 1, 2818 BlockFragment: st.headerBuf.Bytes(), 2819 EndStream: true, 2820 EndHeaders: false, 2821 }) 2822 2823 // Capture the short encoding of a duplicate ~4K cookie, now 2824 // that we've already sent it once. 2825 st.headerBuf.Reset() 2826 st.encodeHeaderField("cookie", cookie) 2827 2828 // Now send 1MB of it. 2829 const size = 1 << 20 2830 b := bytes.Repeat(st.headerBuf.Bytes(), size/st.headerBuf.Len()) 2831 for len(b) > 0 { 2832 chunk := b 2833 if len(chunk) > frameSize { 2834 chunk = chunk[:frameSize] 2835 } 2836 b = b[len(chunk):] 2837 st.fr.WriteContinuation(1, len(b) == 0, chunk) 2838 } 2839 2840 h := st.wantHeaders() 2841 if !h.HeadersEnded() { 2842 t.Fatalf("Got HEADERS without END_HEADERS set: %v", h) 2843 } 2844 headers := st.decodeHeader(h.HeaderBlockFragment()) 2845 want := [][2]string{ 2846 {":status", "431"}, 2847 {"content-type", "text/html; charset=utf-8"}, 2848 {"content-length", "63"}, 2849 } 2850 if !reflect.DeepEqual(headers, want) { 2851 t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want) 2852 } 2853 } 2854 2855 func TestServer_Response_Stream_With_Missing_Trailer(t *testing.T) { 2856 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 2857 w.Header().Set("Trailer", "test-trailer") 2858 return nil 2859 }, func(st *serverTester) { 2860 getSlash(st) 2861 hf := st.wantHeaders() 2862 if !hf.HeadersEnded() { 2863 t.Fatal("want END_HEADERS flag") 2864 } 2865 df := st.wantData() 2866 if len(df.data) != 0 { 2867 t.Fatal("did not want data") 2868 } 2869 if !df.StreamEnded() { 2870 t.Fatal("want END_STREAM flag") 2871 } 2872 }) 2873 } 2874 2875 func TestCompressionErrorOnWrite(t *testing.T) { 2876 const maxStrLen = 8 << 10 2877 var serverConfig *http.Server 2878 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2879 // No response body. 2880 }, func(ts *httptest.Server) { 2881 serverConfig = ts.Config 2882 serverConfig.MaxHeaderBytes = maxStrLen 2883 }) 2884 st.addLogFilter("connection error: COMPRESSION_ERROR") 2885 defer st.Close() 2886 st.greet() 2887 2888 maxAllowed := st.sc.framer.maxHeaderStringLen() 2889 2890 // Crank this up, now that we have a conn connected with the 2891 // hpack.Decoder's max string length set has been initialized 2892 // from the earlier low ~8K value. We want this higher so don't 2893 // hit the max header list size. We only want to test hitting 2894 // the max string size. 2895 serverConfig.MaxHeaderBytes = 1 << 20 2896 2897 // First a request with a header that's exactly the max allowed size 2898 // for the hpack compression. It's still too long for the header list 2899 // size, so we'll get the 431 error, but that keeps the compression 2900 // context still valid. 2901 hbf := st.encodeHeader("foo", strings.Repeat("a", maxAllowed)) 2902 2903 st.writeHeaders(HeadersFrameParam{ 2904 StreamID: 1, 2905 BlockFragment: hbf, 2906 EndStream: true, 2907 EndHeaders: true, 2908 }) 2909 h := st.wantHeaders() 2910 if !h.HeadersEnded() { 2911 t.Fatalf("Got HEADERS without END_HEADERS set: %v", h) 2912 } 2913 headers := st.decodeHeader(h.HeaderBlockFragment()) 2914 want := [][2]string{ 2915 {":status", "431"}, 2916 {"content-type", "text/html; charset=utf-8"}, 2917 {"content-length", "63"}, 2918 } 2919 if !reflect.DeepEqual(headers, want) { 2920 t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want) 2921 } 2922 df := st.wantData() 2923 if !strings.Contains(string(df.Data()), "HTTP Error 431") { 2924 t.Errorf("Unexpected data body: %q", df.Data()) 2925 } 2926 if !df.StreamEnded() { 2927 t.Fatalf("expect data stream end") 2928 } 2929 2930 // And now send one that's just one byte too big. 2931 hbf = st.encodeHeader("bar", strings.Repeat("b", maxAllowed+1)) 2932 st.writeHeaders(HeadersFrameParam{ 2933 StreamID: 3, 2934 BlockFragment: hbf, 2935 EndStream: true, 2936 EndHeaders: true, 2937 }) 2938 ga := st.wantGoAway() 2939 if ga.ErrCode != ErrCodeCompression { 2940 t.Errorf("GOAWAY err = %v; want ErrCodeCompression", ga.ErrCode) 2941 } 2942 } 2943 2944 func TestCompressionErrorOnClose(t *testing.T) { 2945 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 2946 // No response body. 2947 }) 2948 st.addLogFilter("connection error: COMPRESSION_ERROR") 2949 defer st.Close() 2950 st.greet() 2951 2952 hbf := st.encodeHeader("foo", "bar") 2953 hbf = hbf[:len(hbf)-1] // truncate one byte from the end, so hpack.Decoder.Close fails. 2954 st.writeHeaders(HeadersFrameParam{ 2955 StreamID: 1, 2956 BlockFragment: hbf, 2957 EndStream: true, 2958 EndHeaders: true, 2959 }) 2960 ga := st.wantGoAway() 2961 if ga.ErrCode != ErrCodeCompression { 2962 t.Errorf("GOAWAY err = %v; want ErrCodeCompression", ga.ErrCode) 2963 } 2964 } 2965 2966 // test that a server handler can read trailers from a client 2967 func TestServerReadsTrailers(t *testing.T) { 2968 const testBody = "some test body" 2969 writeReq := func(st *serverTester) { 2970 st.writeHeaders(HeadersFrameParam{ 2971 StreamID: 1, // clients send odd numbers 2972 BlockFragment: st.encodeHeader("trailer", "Foo, Bar", "trailer", "Baz"), 2973 EndStream: false, 2974 EndHeaders: true, 2975 }) 2976 st.writeData(1, false, []byte(testBody)) 2977 st.writeHeaders(HeadersFrameParam{ 2978 StreamID: 1, // clients send odd numbers 2979 BlockFragment: st.encodeHeaderRaw( 2980 "foo", "foov", 2981 "bar", "barv", 2982 "baz", "bazv", 2983 "surprise", "wasn't declared; shouldn't show up", 2984 ), 2985 EndStream: true, 2986 EndHeaders: true, 2987 }) 2988 } 2989 checkReq := func(r *http.Request) { 2990 wantTrailer := http.Header{ 2991 "Foo": nil, 2992 "Bar": nil, 2993 "Baz": nil, 2994 } 2995 if !reflect.DeepEqual(r.Trailer, wantTrailer) { 2996 t.Errorf("initial Trailer = %v; want %v", r.Trailer, wantTrailer) 2997 } 2998 slurp, err := ioutil.ReadAll(r.Body) 2999 if string(slurp) != testBody { 3000 t.Errorf("read body %q; want %q", slurp, testBody) 3001 } 3002 if err != nil { 3003 t.Fatalf("Body slurp: %v", err) 3004 } 3005 wantTrailerAfter := http.Header{ 3006 "Foo": {"foov"}, 3007 "Bar": {"barv"}, 3008 "Baz": {"bazv"}, 3009 } 3010 if !reflect.DeepEqual(r.Trailer, wantTrailerAfter) { 3011 t.Errorf("final Trailer = %v; want %v", r.Trailer, wantTrailerAfter) 3012 } 3013 } 3014 testServerRequest(t, writeReq, checkReq) 3015 } 3016 3017 // test that a server handler can send trailers 3018 func TestServerWritesTrailers_WithFlush(t *testing.T) { testServerWritesTrailers(t, true) } 3019 func TestServerWritesTrailers_WithoutFlush(t *testing.T) { testServerWritesTrailers(t, false) } 3020 3021 func testServerWritesTrailers(t *testing.T, withFlush bool) { 3022 // See https://httpwg.github.io/specs/rfc7540.html#rfc.section.8.1.3 3023 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 3024 w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B") 3025 w.Header().Add("Trailer", "Server-Trailer-C") 3026 w.Header().Add("Trailer", "Transfer-Encoding, Content-Length, Trailer") // filtered 3027 3028 // Regular headers: 3029 w.Header().Set("Foo", "Bar") 3030 w.Header().Set("Content-Length", "5") // len("Hello") 3031 3032 io.WriteString(w, "Hello") 3033 if withFlush { 3034 w.(http.Flusher).Flush() 3035 } 3036 w.Header().Set("Server-Trailer-A", "valuea") 3037 w.Header().Set("Server-Trailer-C", "valuec") // skipping B 3038 // After a flush, random keys like Server-Surprise shouldn't show up: 3039 w.Header().Set("Server-Surpise", "surprise! this isn't predeclared!") 3040 // But we do permit promoting keys to trailers after a 3041 // flush if they start with the magic 3042 // otherwise-invalid "Trailer:" prefix: 3043 w.Header().Set("Trailer:Post-Header-Trailer", "hi1") 3044 w.Header().Set("Trailer:post-header-trailer2", "hi2") 3045 w.Header().Set("Trailer:Range", "invalid") 3046 w.Header().Set("Trailer:Foo\x01Bogus", "invalid") 3047 w.Header().Set("Transfer-Encoding", "should not be included; Forbidden by RFC 7230 4.1.2") 3048 w.Header().Set("Content-Length", "should not be included; Forbidden by RFC 7230 4.1.2") 3049 w.Header().Set("Trailer", "should not be included; Forbidden by RFC 7230 4.1.2") 3050 return nil 3051 }, func(st *serverTester) { 3052 getSlash(st) 3053 hf := st.wantHeaders() 3054 if hf.StreamEnded() { 3055 t.Fatal("response HEADERS had END_STREAM") 3056 } 3057 if !hf.HeadersEnded() { 3058 t.Fatal("response HEADERS didn't have END_HEADERS") 3059 } 3060 goth := st.decodeHeader(hf.HeaderBlockFragment()) 3061 wanth := [][2]string{ 3062 {":status", "200"}, 3063 {"foo", "Bar"}, 3064 {"trailer", "Server-Trailer-A, Server-Trailer-B"}, 3065 {"trailer", "Server-Trailer-C"}, 3066 {"trailer", "Transfer-Encoding, Content-Length, Trailer"}, 3067 {"content-type", "text/plain; charset=utf-8"}, 3068 {"content-length", "5"}, 3069 } 3070 if !reflect.DeepEqual(goth, wanth) { 3071 t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth) 3072 } 3073 df := st.wantData() 3074 if string(df.Data()) != "Hello" { 3075 t.Fatalf("Client read %q; want Hello", df.Data()) 3076 } 3077 if df.StreamEnded() { 3078 t.Fatalf("data frame had STREAM_ENDED") 3079 } 3080 tf := st.wantHeaders() // for the trailers 3081 if !tf.StreamEnded() { 3082 t.Fatalf("trailers HEADERS lacked END_STREAM") 3083 } 3084 if !tf.HeadersEnded() { 3085 t.Fatalf("trailers HEADERS lacked END_HEADERS") 3086 } 3087 wanth = [][2]string{ 3088 {"post-header-trailer", "hi1"}, 3089 {"post-header-trailer2", "hi2"}, 3090 {"server-trailer-a", "valuea"}, 3091 {"server-trailer-c", "valuec"}, 3092 } 3093 goth = st.decodeHeader(tf.HeaderBlockFragment()) 3094 if !reflect.DeepEqual(goth, wanth) { 3095 t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth) 3096 } 3097 }) 3098 } 3099 3100 // validate transmitted header field names & values 3101 // golang.org/issue/14048 3102 func TestServerDoesntWriteInvalidHeaders(t *testing.T) { 3103 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 3104 w.Header().Add("OK1", "x") 3105 w.Header().Add("Bad:Colon", "x") // colon (non-token byte) in key 3106 w.Header().Add("Bad1\x00", "x") // null in key 3107 w.Header().Add("Bad2", "x\x00y") // null in value 3108 return nil 3109 }, func(st *serverTester) { 3110 getSlash(st) 3111 hf := st.wantHeaders() 3112 if !hf.StreamEnded() { 3113 t.Error("response HEADERS lacked END_STREAM") 3114 } 3115 if !hf.HeadersEnded() { 3116 t.Fatal("response HEADERS didn't have END_HEADERS") 3117 } 3118 goth := st.decodeHeader(hf.HeaderBlockFragment()) 3119 wanth := [][2]string{ 3120 {":status", "200"}, 3121 {"ok1", "x"}, 3122 {"content-length", "0"}, 3123 } 3124 if !reflect.DeepEqual(goth, wanth) { 3125 t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth) 3126 } 3127 }) 3128 } 3129 3130 func BenchmarkServerGets(b *testing.B) { 3131 defer disableGoroutineTracking()() 3132 b.ReportAllocs() 3133 3134 const msg = "Hello, world" 3135 st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) { 3136 io.WriteString(w, msg) 3137 }) 3138 defer st.Close() 3139 st.greet() 3140 3141 // Give the server quota to reply. (plus it has the 64KB) 3142 if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil { 3143 b.Fatal(err) 3144 } 3145 3146 for i := 0; i < b.N; i++ { 3147 id := 1 + uint32(i)*2 3148 st.writeHeaders(HeadersFrameParam{ 3149 StreamID: id, 3150 BlockFragment: st.encodeHeader(), 3151 EndStream: true, 3152 EndHeaders: true, 3153 }) 3154 st.wantHeaders() 3155 df := st.wantData() 3156 if !df.StreamEnded() { 3157 b.Fatalf("DATA didn't have END_STREAM; got %v", df) 3158 } 3159 } 3160 } 3161 3162 func BenchmarkServerPosts(b *testing.B) { 3163 defer disableGoroutineTracking()() 3164 b.ReportAllocs() 3165 3166 const msg = "Hello, world" 3167 st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) { 3168 // Consume the (empty) body from th peer before replying, otherwise 3169 // the server will sometimes (depending on scheduling) send the peer a 3170 // a RST_STREAM with the CANCEL error code. 3171 if n, err := io.Copy(ioutil.Discard, r.Body); n != 0 || err != nil { 3172 b.Errorf("Copy error; got %v, %v; want 0, nil", n, err) 3173 } 3174 io.WriteString(w, msg) 3175 }) 3176 defer st.Close() 3177 st.greet() 3178 3179 // Give the server quota to reply. (plus it has the 64KB) 3180 if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil { 3181 b.Fatal(err) 3182 } 3183 3184 for i := 0; i < b.N; i++ { 3185 id := 1 + uint32(i)*2 3186 st.writeHeaders(HeadersFrameParam{ 3187 StreamID: id, 3188 BlockFragment: st.encodeHeader(":method", "POST"), 3189 EndStream: false, 3190 EndHeaders: true, 3191 }) 3192 st.writeData(id, true, nil) 3193 st.wantHeaders() 3194 df := st.wantData() 3195 if !df.StreamEnded() { 3196 b.Fatalf("DATA didn't have END_STREAM; got %v", df) 3197 } 3198 } 3199 } 3200 3201 // Send a stream of messages from server to client in separate data frames. 3202 // Brings up performance issues seen in long streams. 3203 // Created to show problem in go issue #18502 3204 func BenchmarkServerToClientStreamDefaultOptions(b *testing.B) { 3205 benchmarkServerToClientStream(b) 3206 } 3207 3208 // Justification for Change-Id: Iad93420ef6c3918f54249d867098f1dadfa324d8 3209 // Expect to see memory/alloc reduction by opting in to Frame reuse with the Framer. 3210 func BenchmarkServerToClientStreamReuseFrames(b *testing.B) { 3211 benchmarkServerToClientStream(b, optFramerReuseFrames) 3212 } 3213 3214 func benchmarkServerToClientStream(b *testing.B, newServerOpts ...interface{}) { 3215 defer disableGoroutineTracking()() 3216 b.ReportAllocs() 3217 const msgLen = 1 3218 // default window size 3219 const windowSize = 1<<16 - 1 3220 3221 // next message to send from the server and for the client to expect 3222 nextMsg := func(i int) []byte { 3223 msg := make([]byte, msgLen) 3224 msg[0] = byte(i) 3225 if len(msg) != msgLen { 3226 panic("invalid test setup msg length") 3227 } 3228 return msg 3229 } 3230 3231 st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) { 3232 // Consume the (empty) body from th peer before replying, otherwise 3233 // the server will sometimes (depending on scheduling) send the peer a 3234 // a RST_STREAM with the CANCEL error code. 3235 if n, err := io.Copy(ioutil.Discard, r.Body); n != 0 || err != nil { 3236 b.Errorf("Copy error; got %v, %v; want 0, nil", n, err) 3237 } 3238 for i := 0; i < b.N; i += 1 { 3239 w.Write(nextMsg(i)) 3240 w.(http.Flusher).Flush() 3241 } 3242 }, newServerOpts...) 3243 defer st.Close() 3244 st.greet() 3245 3246 const id = uint32(1) 3247 3248 st.writeHeaders(HeadersFrameParam{ 3249 StreamID: id, 3250 BlockFragment: st.encodeHeader(":method", "POST"), 3251 EndStream: false, 3252 EndHeaders: true, 3253 }) 3254 3255 st.writeData(id, true, nil) 3256 st.wantHeaders() 3257 3258 var pendingWindowUpdate = uint32(0) 3259 3260 for i := 0; i < b.N; i += 1 { 3261 expected := nextMsg(i) 3262 df := st.wantData() 3263 if bytes.Compare(expected, df.data) != 0 { 3264 b.Fatalf("Bad message received; want %v; got %v", expected, df.data) 3265 } 3266 // try to send infrequent but large window updates so they don't overwhelm the test 3267 pendingWindowUpdate += uint32(len(df.data)) 3268 if pendingWindowUpdate >= windowSize/2 { 3269 if err := st.fr.WriteWindowUpdate(0, pendingWindowUpdate); err != nil { 3270 b.Fatal(err) 3271 } 3272 if err := st.fr.WriteWindowUpdate(id, pendingWindowUpdate); err != nil { 3273 b.Fatal(err) 3274 } 3275 pendingWindowUpdate = 0 3276 } 3277 } 3278 df := st.wantData() 3279 if !df.StreamEnded() { 3280 b.Fatalf("DATA didn't have END_STREAM; got %v", df) 3281 } 3282 } 3283 3284 // go-fuzz bug, originally reported at https://github.com/bradfitz/http2/issues/53 3285 // Verify we don't hang. 3286 func TestIssue53(t *testing.T) { 3287 const data = "PRI * HTTP/2.0\r\n\r\nSM" + 3288 "\r\n\r\n\x00\x00\x00\x01\ainfinfin\ad" 3289 s := &http.Server{ 3290 ErrorLog: log.New(io.MultiWriter(stderrv(), twriter{t: t}), "", log.LstdFlags), 3291 Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 3292 w.Write([]byte("hello")) 3293 }), 3294 } 3295 s2 := &Server{ 3296 MaxReadFrameSize: 1 << 16, 3297 PermitProhibitedCipherSuites: true, 3298 } 3299 c := &issue53Conn{[]byte(data), false, false} 3300 s2.ServeConn(c, &ServeConnOpts{BaseConfig: s}) 3301 if !c.closed { 3302 t.Fatal("connection is not closed") 3303 } 3304 } 3305 3306 type issue53Conn struct { 3307 data []byte 3308 closed bool 3309 written bool 3310 } 3311 3312 func (c *issue53Conn) Read(b []byte) (n int, err error) { 3313 if len(c.data) == 0 { 3314 return 0, io.EOF 3315 } 3316 n = copy(b, c.data) 3317 c.data = c.data[n:] 3318 return 3319 } 3320 3321 func (c *issue53Conn) Write(b []byte) (n int, err error) { 3322 c.written = true 3323 return len(b), nil 3324 } 3325 3326 func (c *issue53Conn) Close() error { 3327 c.closed = true 3328 return nil 3329 } 3330 3331 func (c *issue53Conn) LocalAddr() net.Addr { 3332 return &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 49706} 3333 } 3334 func (c *issue53Conn) RemoteAddr() net.Addr { 3335 return &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 49706} 3336 } 3337 func (c *issue53Conn) SetDeadline(t time.Time) error { return nil } 3338 func (c *issue53Conn) SetReadDeadline(t time.Time) error { return nil } 3339 func (c *issue53Conn) SetWriteDeadline(t time.Time) error { return nil } 3340 3341 // golang.org/issue/33839 3342 func TestServeConnOptsNilReceiverBehavior(t *testing.T) { 3343 defer func() { 3344 if r := recover(); r != nil { 3345 t.Errorf("got a panic that should not happen: %v", r) 3346 } 3347 }() 3348 3349 var o *ServeConnOpts 3350 if o.context() == nil { 3351 t.Error("o.context should not return nil") 3352 } 3353 if o.baseConfig() == nil { 3354 t.Error("o.baseConfig should not return nil") 3355 } 3356 if o.handler() == nil { 3357 t.Error("o.handler should not return nil") 3358 } 3359 } 3360 3361 // golang.org/issue/12895 3362 func TestConfigureServer(t *testing.T) { 3363 tests := []struct { 3364 name string 3365 tlsConfig *tls.Config 3366 wantErr string 3367 }{ 3368 { 3369 name: "empty server", 3370 }, 3371 { 3372 name: "just the required cipher suite", 3373 tlsConfig: &tls.Config{ 3374 CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3375 }, 3376 }, 3377 { 3378 name: "just the alternative required cipher suite", 3379 tlsConfig: &tls.Config{ 3380 CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 3381 }, 3382 }, 3383 { 3384 name: "missing required cipher suite", 3385 tlsConfig: &tls.Config{ 3386 CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, 3387 }, 3388 wantErr: "is missing an HTTP/2-required", 3389 }, 3390 { 3391 name: "required after bad", 3392 tlsConfig: &tls.Config{ 3393 CipherSuites: []uint16{tls.TLS_RSA_WITH_RC4_128_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3394 }, 3395 wantErr: "contains an HTTP/2-approved cipher suite (0xc02f), but it comes after", 3396 }, 3397 { 3398 name: "bad after required", 3399 tlsConfig: &tls.Config{ 3400 CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_RSA_WITH_RC4_128_SHA}, 3401 }, 3402 }, 3403 } 3404 for _, tt := range tests { 3405 srv := &http.Server{TLSConfig: tt.tlsConfig} 3406 err := ConfigureServer(srv, nil) 3407 if (err != nil) != (tt.wantErr != "") { 3408 if tt.wantErr != "" { 3409 t.Errorf("%s: success, but want error", tt.name) 3410 } else { 3411 t.Errorf("%s: unexpected error: %v", tt.name, err) 3412 } 3413 } 3414 if err != nil && tt.wantErr != "" && !strings.Contains(err.Error(), tt.wantErr) { 3415 t.Errorf("%s: err = %v; want substring %q", tt.name, err, tt.wantErr) 3416 } 3417 if err == nil && !srv.TLSConfig.PreferServerCipherSuites { 3418 t.Errorf("%s: PreferServerCipherSuite is false; want true", tt.name) 3419 } 3420 } 3421 } 3422 3423 func TestServerRejectHeadWithBody(t *testing.T) { 3424 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3425 // No response body. 3426 }) 3427 defer st.Close() 3428 st.greet() 3429 st.writeHeaders(HeadersFrameParam{ 3430 StreamID: 1, // clients send odd numbers 3431 BlockFragment: st.encodeHeader(":method", "HEAD"), 3432 EndStream: false, // what we're testing, a bogus HEAD request with body 3433 EndHeaders: true, 3434 }) 3435 st.wantRSTStream(1, ErrCodeProtocol) 3436 } 3437 3438 func TestServerNoAutoContentLengthOnHead(t *testing.T) { 3439 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3440 // No response body. (or smaller than one frame) 3441 }) 3442 defer st.Close() 3443 st.greet() 3444 st.writeHeaders(HeadersFrameParam{ 3445 StreamID: 1, // clients send odd numbers 3446 BlockFragment: st.encodeHeader(":method", "HEAD"), 3447 EndStream: true, 3448 EndHeaders: true, 3449 }) 3450 h := st.wantHeaders() 3451 headers := st.decodeHeader(h.HeaderBlockFragment()) 3452 want := [][2]string{ 3453 {":status", "200"}, 3454 } 3455 if !reflect.DeepEqual(headers, want) { 3456 t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want) 3457 } 3458 } 3459 3460 // golang.org/issue/13495 3461 func TestServerNoDuplicateContentType(t *testing.T) { 3462 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3463 w.Header()["Content-Type"] = []string{""} 3464 fmt.Fprintf(w, "<html><head></head><body>hi</body></html>") 3465 }) 3466 defer st.Close() 3467 st.greet() 3468 st.writeHeaders(HeadersFrameParam{ 3469 StreamID: 1, 3470 BlockFragment: st.encodeHeader(), 3471 EndStream: true, 3472 EndHeaders: true, 3473 }) 3474 h := st.wantHeaders() 3475 headers := st.decodeHeader(h.HeaderBlockFragment()) 3476 want := [][2]string{ 3477 {":status", "200"}, 3478 {"content-type", ""}, 3479 {"content-length", "41"}, 3480 } 3481 if !reflect.DeepEqual(headers, want) { 3482 t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want) 3483 } 3484 } 3485 3486 func disableGoroutineTracking() (restore func()) { 3487 old := DebugGoroutines 3488 DebugGoroutines = false 3489 return func() { DebugGoroutines = old } 3490 } 3491 3492 func BenchmarkServer_GetRequest(b *testing.B) { 3493 defer disableGoroutineTracking()() 3494 b.ReportAllocs() 3495 const msg = "Hello, world." 3496 st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) { 3497 n, err := io.Copy(ioutil.Discard, r.Body) 3498 if err != nil || n > 0 { 3499 b.Errorf("Read %d bytes, error %v; want 0 bytes.", n, err) 3500 } 3501 io.WriteString(w, msg) 3502 }) 3503 defer st.Close() 3504 3505 st.greet() 3506 // Give the server quota to reply. (plus it has the 64KB) 3507 if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil { 3508 b.Fatal(err) 3509 } 3510 hbf := st.encodeHeader(":method", "GET") 3511 for i := 0; i < b.N; i++ { 3512 streamID := uint32(1 + 2*i) 3513 st.writeHeaders(HeadersFrameParam{ 3514 StreamID: streamID, 3515 BlockFragment: hbf, 3516 EndStream: true, 3517 EndHeaders: true, 3518 }) 3519 st.wantHeaders() 3520 st.wantData() 3521 } 3522 } 3523 3524 func BenchmarkServer_PostRequest(b *testing.B) { 3525 defer disableGoroutineTracking()() 3526 b.ReportAllocs() 3527 const msg = "Hello, world." 3528 st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) { 3529 n, err := io.Copy(ioutil.Discard, r.Body) 3530 if err != nil || n > 0 { 3531 b.Errorf("Read %d bytes, error %v; want 0 bytes.", n, err) 3532 } 3533 io.WriteString(w, msg) 3534 }) 3535 defer st.Close() 3536 st.greet() 3537 // Give the server quota to reply. (plus it has the 64KB) 3538 if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil { 3539 b.Fatal(err) 3540 } 3541 hbf := st.encodeHeader(":method", "POST") 3542 for i := 0; i < b.N; i++ { 3543 streamID := uint32(1 + 2*i) 3544 st.writeHeaders(HeadersFrameParam{ 3545 StreamID: streamID, 3546 BlockFragment: hbf, 3547 EndStream: false, 3548 EndHeaders: true, 3549 }) 3550 st.writeData(streamID, true, nil) 3551 st.wantHeaders() 3552 st.wantData() 3553 } 3554 } 3555 3556 type connStateConn struct { 3557 net.Conn 3558 cs tls.ConnectionState 3559 } 3560 3561 func (c connStateConn) ConnectionState() tls.ConnectionState { return c.cs } 3562 3563 // golang.org/issue/12737 -- handle any net.Conn, not just 3564 // *tls.Conn. 3565 func TestServerHandleCustomConn(t *testing.T) { 3566 var s Server 3567 c1, c2 := net.Pipe() 3568 clientDone := make(chan struct{}) 3569 handlerDone := make(chan struct{}) 3570 var req *http.Request 3571 go func() { 3572 defer close(clientDone) 3573 defer c2.Close() 3574 fr := NewFramer(c2, c2) 3575 io.WriteString(c2, ClientPreface) 3576 fr.WriteSettings() 3577 fr.WriteSettingsAck() 3578 f, err := fr.ReadFrame() 3579 if err != nil { 3580 t.Error(err) 3581 return 3582 } 3583 if sf, ok := f.(*SettingsFrame); !ok || sf.IsAck() { 3584 t.Errorf("Got %v; want non-ACK SettingsFrame", summarizeFrame(f)) 3585 return 3586 } 3587 f, err = fr.ReadFrame() 3588 if err != nil { 3589 t.Error(err) 3590 return 3591 } 3592 if sf, ok := f.(*SettingsFrame); !ok || !sf.IsAck() { 3593 t.Errorf("Got %v; want ACK SettingsFrame", summarizeFrame(f)) 3594 return 3595 } 3596 var henc hpackEncoder 3597 fr.WriteHeaders(HeadersFrameParam{ 3598 StreamID: 1, 3599 BlockFragment: henc.encodeHeaderRaw(t, ":method", "GET", ":path", "/", ":scheme", "https", ":authority", "foo.com"), 3600 EndStream: true, 3601 EndHeaders: true, 3602 }) 3603 go io.Copy(ioutil.Discard, c2) 3604 <-handlerDone 3605 }() 3606 const testString = "my custom ConnectionState" 3607 fakeConnState := tls.ConnectionState{ 3608 ServerName: testString, 3609 Version: tls.VersionTLS12, 3610 CipherSuite: cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 3611 } 3612 go s.ServeConn(connStateConn{c1, fakeConnState}, &ServeConnOpts{ 3613 BaseConfig: &http.Server{ 3614 Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 3615 defer close(handlerDone) 3616 req = r 3617 }), 3618 }}) 3619 select { 3620 case <-clientDone: 3621 case <-time.After(5 * time.Second): 3622 t.Fatal("timeout waiting for handler") 3623 } 3624 if req.TLS == nil { 3625 t.Fatalf("Request.TLS is nil. Got: %#v", req) 3626 } 3627 if req.TLS.ServerName != testString { 3628 t.Fatalf("Request.TLS = %+v; want ServerName of %q", req.TLS, testString) 3629 } 3630 } 3631 3632 // golang.org/issue/14214 3633 func TestServer_Rejects_ConnHeaders(t *testing.T) { 3634 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3635 t.Error("should not get to Handler") 3636 }) 3637 defer st.Close() 3638 st.greet() 3639 st.bodylessReq1("connection", "foo") 3640 hf := st.wantHeaders() 3641 goth := st.decodeHeader(hf.HeaderBlockFragment()) 3642 wanth := [][2]string{ 3643 {":status", "400"}, 3644 {"content-type", "text/plain; charset=utf-8"}, 3645 {"x-content-type-options", "nosniff"}, 3646 {"content-length", "51"}, 3647 } 3648 if !reflect.DeepEqual(goth, wanth) { 3649 t.Errorf("Got headers %v; want %v", goth, wanth) 3650 } 3651 } 3652 3653 type hpackEncoder struct { 3654 enc *hpack.Encoder 3655 buf bytes.Buffer 3656 } 3657 3658 func (he *hpackEncoder) encodeHeaderRaw(t *testing.T, headers ...string) []byte { 3659 if len(headers)%2 == 1 { 3660 panic("odd number of kv args") 3661 } 3662 he.buf.Reset() 3663 if he.enc == nil { 3664 he.enc = hpack.NewEncoder(&he.buf) 3665 } 3666 for len(headers) > 0 { 3667 k, v := headers[0], headers[1] 3668 err := he.enc.WriteField(hpack.HeaderField{Name: k, Value: v}) 3669 if err != nil { 3670 t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err) 3671 } 3672 headers = headers[2:] 3673 } 3674 return he.buf.Bytes() 3675 } 3676 3677 func TestCheckValidHTTP2Request(t *testing.T) { 3678 tests := []struct { 3679 h http.Header 3680 want error 3681 }{ 3682 { 3683 h: http.Header{"Te": {"trailers"}}, 3684 want: nil, 3685 }, 3686 { 3687 h: http.Header{"Te": {"trailers", "bogus"}}, 3688 want: errors.New(`request header "TE" may only be "trailers" in HTTP/2`), 3689 }, 3690 { 3691 h: http.Header{"Foo": {""}}, 3692 want: nil, 3693 }, 3694 { 3695 h: http.Header{"Connection": {""}}, 3696 want: errors.New(`request header "Connection" is not valid in HTTP/2`), 3697 }, 3698 { 3699 h: http.Header{"Proxy-Connection": {""}}, 3700 want: errors.New(`request header "Proxy-Connection" is not valid in HTTP/2`), 3701 }, 3702 { 3703 h: http.Header{"Keep-Alive": {""}}, 3704 want: errors.New(`request header "Keep-Alive" is not valid in HTTP/2`), 3705 }, 3706 { 3707 h: http.Header{"Upgrade": {""}}, 3708 want: errors.New(`request header "Upgrade" is not valid in HTTP/2`), 3709 }, 3710 } 3711 for i, tt := range tests { 3712 got := checkValidHTTP2RequestHeaders(tt.h) 3713 if !equalError(got, tt.want) { 3714 t.Errorf("%d. checkValidHTTP2Request = %v; want %v", i, got, tt.want) 3715 } 3716 } 3717 } 3718 3719 func TestCheckValidPushPromiseRequest(t *testing.T) { 3720 tests := []struct { 3721 h http.Header 3722 want error 3723 }{ 3724 { 3725 h: http.Header{"Foo": {""}}, 3726 want: nil, 3727 }, 3728 { 3729 h: http.Header{"Content-Encoding": {""}}, 3730 want: errors.New(`promised request cannot include body related header "Content-Encoding"`), 3731 }, 3732 { 3733 h: http.Header{"Content-Length": {""}}, 3734 want: errors.New(`promised request cannot include body related header "Content-Length"`), 3735 }, 3736 { 3737 h: http.Header{"Expect": {""}}, 3738 want: errors.New(`promised request cannot include body related header "Expect"`), 3739 }, 3740 { 3741 h: http.Header{"Te": {""}}, 3742 want: errors.New(`promised request cannot include body related header "Te"`), 3743 }, 3744 { 3745 h: http.Header{"Trailer": {""}}, 3746 want: errors.New(`promised request cannot include body related header "Trailer"`), 3747 }, 3748 { 3749 h: http.Header{"Host": {""}}, 3750 want: errors.New(`promised URL must be absolute so "Host" header disallowed`), 3751 }, 3752 } 3753 for i, tt := range tests { 3754 got := checkValidPushPromiseRequestHeaders(tt.h) 3755 if !reflect.DeepEqual(got, tt.want) { 3756 t.Errorf("%d. checkValidPushPromiseRequest = %v; want %v", i, got, tt.want) 3757 } 3758 } 3759 } 3760 3761 // golang.org/issue/14030 3762 func TestExpect100ContinueAfterHandlerWrites(t *testing.T) { 3763 const msg = "Hello" 3764 const msg2 = "World" 3765 3766 doRead := make(chan bool, 1) 3767 defer close(doRead) // fallback cleanup 3768 3769 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3770 io.WriteString(w, msg) 3771 w.(http.Flusher).Flush() 3772 3773 // Do a read, which might force a 100-continue status to be sent. 3774 <-doRead 3775 r.Body.Read(make([]byte, 10)) 3776 3777 io.WriteString(w, msg2) 3778 3779 }, optOnlyServer) 3780 defer st.Close() 3781 3782 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3783 defer tr.CloseIdleConnections() 3784 3785 req, _ := http.NewRequest("POST", st.ts.URL, io.LimitReader(neverEnding('A'), 2<<20)) 3786 req.Header.Set("Expect", "100-continue") 3787 3788 res, err := tr.RoundTrip(req) 3789 if err != nil { 3790 t.Fatal(err) 3791 } 3792 defer res.Body.Close() 3793 3794 buf := make([]byte, len(msg)) 3795 if _, err := io.ReadFull(res.Body, buf); err != nil { 3796 t.Fatal(err) 3797 } 3798 if string(buf) != msg { 3799 t.Fatalf("msg = %q; want %q", buf, msg) 3800 } 3801 3802 doRead <- true 3803 3804 if _, err := io.ReadFull(res.Body, buf); err != nil { 3805 t.Fatal(err) 3806 } 3807 if string(buf) != msg2 { 3808 t.Fatalf("second msg = %q; want %q", buf, msg2) 3809 } 3810 } 3811 3812 type funcReader func([]byte) (n int, err error) 3813 3814 func (f funcReader) Read(p []byte) (n int, err error) { return f(p) } 3815 3816 // golang.org/issue/16481 -- return flow control when streams close with unread data. 3817 // (The Server version of the bug. See also TestUnreadFlowControlReturned_Transport) 3818 func TestUnreadFlowControlReturned_Server(t *testing.T) { 3819 for _, tt := range []struct { 3820 name string 3821 reqFn func(r *http.Request) 3822 }{ 3823 { 3824 "body-open", 3825 func(r *http.Request) {}, 3826 }, 3827 { 3828 "body-closed", 3829 func(r *http.Request) { 3830 r.Body.Close() 3831 }, 3832 }, 3833 { 3834 "read-1-byte-and-close", 3835 func(r *http.Request) { 3836 b := make([]byte, 1) 3837 r.Body.Read(b) 3838 r.Body.Close() 3839 }, 3840 }, 3841 } { 3842 t.Run(tt.name, func(t *testing.T) { 3843 unblock := make(chan bool, 1) 3844 defer close(unblock) 3845 3846 timeOut := time.NewTimer(5 * time.Second) 3847 defer timeOut.Stop() 3848 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3849 // Don't read the 16KB request body. Wait until the client's 3850 // done sending it and then return. This should cause the Server 3851 // to then return those 16KB of flow control to the client. 3852 tt.reqFn(r) 3853 select { 3854 case <-unblock: 3855 case <-timeOut.C: 3856 t.Fatal(tt.name, "timedout") 3857 } 3858 }, optOnlyServer) 3859 defer st.Close() 3860 3861 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3862 defer tr.CloseIdleConnections() 3863 3864 // This previously hung on the 4th iteration. 3865 iters := 100 3866 if testing.Short() { 3867 iters = 20 3868 } 3869 for i := 0; i < iters; i++ { 3870 body := io.MultiReader( 3871 io.LimitReader(neverEnding('A'), 16<<10), 3872 funcReader(func([]byte) (n int, err error) { 3873 unblock <- true 3874 return 0, io.EOF 3875 }), 3876 ) 3877 req, _ := http.NewRequest("POST", st.ts.URL, body) 3878 res, err := tr.RoundTrip(req) 3879 if err != nil { 3880 t.Fatal(tt.name, err) 3881 } 3882 res.Body.Close() 3883 } 3884 }) 3885 } 3886 } 3887 3888 func TestServerIdleTimeout(t *testing.T) { 3889 if testing.Short() { 3890 t.Skip("skipping in short mode") 3891 } 3892 3893 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3894 }, func(h2s *Server) { 3895 h2s.IdleTimeout = 500 * time.Millisecond 3896 }) 3897 defer st.Close() 3898 3899 st.greet() 3900 ga := st.wantGoAway() 3901 if ga.ErrCode != ErrCodeNo { 3902 t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode) 3903 } 3904 } 3905 3906 func TestServerIdleTimeout_AfterRequest(t *testing.T) { 3907 if testing.Short() { 3908 t.Skip("skipping in short mode") 3909 } 3910 const timeout = 250 * time.Millisecond 3911 3912 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3913 time.Sleep(timeout * 2) 3914 }, func(h2s *Server) { 3915 h2s.IdleTimeout = timeout 3916 }) 3917 defer st.Close() 3918 3919 st.greet() 3920 3921 // Send a request which takes twice the timeout. Verifies the 3922 // idle timeout doesn't fire while we're in a request: 3923 st.bodylessReq1() 3924 st.wantHeaders() 3925 3926 // But the idle timeout should be rearmed after the request 3927 // is done: 3928 ga := st.wantGoAway() 3929 if ga.ErrCode != ErrCodeNo { 3930 t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode) 3931 } 3932 } 3933 3934 // grpc-go closes the Request.Body currently with a Read. 3935 // Verify that it doesn't race. 3936 // See https://github.com/grpc/grpc-go/pull/938 3937 func TestRequestBodyReadCloseRace(t *testing.T) { 3938 for i := 0; i < 100; i++ { 3939 body := &requestBody{ 3940 pipe: &pipe{ 3941 b: new(bytes.Buffer), 3942 }, 3943 } 3944 body.pipe.CloseWithError(io.EOF) 3945 3946 done := make(chan bool, 1) 3947 buf := make([]byte, 10) 3948 go func() { 3949 time.Sleep(1 * time.Millisecond) 3950 body.Close() 3951 done <- true 3952 }() 3953 body.Read(buf) 3954 <-done 3955 } 3956 } 3957 3958 func TestIssue20704Race(t *testing.T) { 3959 if testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" { 3960 t.Skip("skipping in short mode") 3961 } 3962 const ( 3963 itemSize = 1 << 10 3964 itemCount = 100 3965 ) 3966 3967 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 3968 for i := 0; i < itemCount; i++ { 3969 _, err := w.Write(make([]byte, itemSize)) 3970 if err != nil { 3971 return 3972 } 3973 } 3974 }, optOnlyServer) 3975 defer st.Close() 3976 3977 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 3978 defer tr.CloseIdleConnections() 3979 cl := &http.Client{Transport: tr} 3980 3981 for i := 0; i < 1000; i++ { 3982 resp, err := cl.Get(st.ts.URL) 3983 if err != nil { 3984 t.Fatal(err) 3985 } 3986 // Force a RST stream to the server by closing without 3987 // reading the body: 3988 resp.Body.Close() 3989 } 3990 } 3991 3992 func TestServer_Rejects_TooSmall(t *testing.T) { 3993 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 3994 ioutil.ReadAll(r.Body) 3995 return nil 3996 }, func(st *serverTester) { 3997 st.writeHeaders(HeadersFrameParam{ 3998 StreamID: 1, // clients send odd numbers 3999 BlockFragment: st.encodeHeader( 4000 ":method", "POST", 4001 "content-length", "4", 4002 ), 4003 EndStream: false, // to say DATA frames are coming 4004 EndHeaders: true, 4005 }) 4006 st.writeData(1, true, []byte("12345")) 4007 4008 st.wantRSTStream(1, ErrCodeProtocol) 4009 }) 4010 } 4011 4012 // Tests that a handler setting "Connection: close" results in a GOAWAY being sent, 4013 // and the connection still completing. 4014 func TestServerHandlerConnectionClose(t *testing.T) { 4015 unblockHandler := make(chan bool, 1) 4016 defer close(unblockHandler) // backup; in case of errors 4017 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { 4018 w.Header().Set("Connection", "close") 4019 w.Header().Set("Foo", "bar") 4020 w.(http.Flusher).Flush() 4021 <-unblockHandler 4022 return nil 4023 }, func(st *serverTester) { 4024 st.writeHeaders(HeadersFrameParam{ 4025 StreamID: 1, 4026 BlockFragment: st.encodeHeader(), 4027 EndStream: true, 4028 EndHeaders: true, 4029 }) 4030 var sawGoAway bool 4031 var sawRes bool 4032 for { 4033 f, err := st.readFrame() 4034 if err == io.EOF { 4035 break 4036 } 4037 if err != nil { 4038 t.Fatal(err) 4039 } 4040 switch f := f.(type) { 4041 case *GoAwayFrame: 4042 sawGoAway = true 4043 unblockHandler <- true 4044 if f.LastStreamID != 1 || f.ErrCode != ErrCodeNo { 4045 t.Errorf("unexpected GOAWAY frame: %v", summarizeFrame(f)) 4046 } 4047 case *HeadersFrame: 4048 goth := st.decodeHeader(f.HeaderBlockFragment()) 4049 wanth := [][2]string{ 4050 {":status", "200"}, 4051 {"foo", "bar"}, 4052 } 4053 if !reflect.DeepEqual(goth, wanth) { 4054 t.Errorf("got headers %v; want %v", goth, wanth) 4055 } 4056 sawRes = true 4057 case *DataFrame: 4058 if f.StreamID != 1 || !f.StreamEnded() || len(f.Data()) != 0 { 4059 t.Errorf("unexpected DATA frame: %v", summarizeFrame(f)) 4060 } 4061 default: 4062 t.Logf("unexpected frame: %v", summarizeFrame(f)) 4063 } 4064 } 4065 if !sawGoAway { 4066 t.Errorf("didn't see GOAWAY") 4067 } 4068 if !sawRes { 4069 t.Errorf("didn't see response") 4070 } 4071 }) 4072 } 4073 4074 func TestServer_Headers_HalfCloseRemote(t *testing.T) { 4075 var st *serverTester 4076 writeData := make(chan bool) 4077 writeHeaders := make(chan bool) 4078 leaveHandler := make(chan bool) 4079 st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 4080 if st.stream(1) == nil { 4081 t.Errorf("nil stream 1 in handler") 4082 } 4083 if got, want := st.streamState(1), stateOpen; got != want { 4084 t.Errorf("in handler, state is %v; want %v", got, want) 4085 } 4086 writeData <- true 4087 if n, err := r.Body.Read(make([]byte, 1)); n != 0 || err != io.EOF { 4088 t.Errorf("body read = %d, %v; want 0, EOF", n, err) 4089 } 4090 if got, want := st.streamState(1), stateHalfClosedRemote; got != want { 4091 t.Errorf("in handler, state is %v; want %v", got, want) 4092 } 4093 writeHeaders <- true 4094 4095 <-leaveHandler 4096 }) 4097 st.greet() 4098 4099 st.writeHeaders(HeadersFrameParam{ 4100 StreamID: 1, 4101 BlockFragment: st.encodeHeader(), 4102 EndStream: false, // keep it open 4103 EndHeaders: true, 4104 }) 4105 <-writeData 4106 st.writeData(1, true, nil) 4107 4108 <-writeHeaders 4109 4110 st.writeHeaders(HeadersFrameParam{ 4111 StreamID: 1, 4112 BlockFragment: st.encodeHeader(), 4113 EndStream: false, // keep it open 4114 EndHeaders: true, 4115 }) 4116 4117 defer close(leaveHandler) 4118 4119 st.wantRSTStream(1, ErrCodeStreamClosed) 4120 } 4121 4122 func TestServerGracefulShutdown(t *testing.T) { 4123 var st *serverTester 4124 handlerDone := make(chan struct{}) 4125 st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 4126 defer close(handlerDone) 4127 go st.ts.Config.Shutdown(context.Background()) 4128 4129 ga := st.wantGoAway() 4130 if ga.ErrCode != ErrCodeNo { 4131 t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode) 4132 } 4133 if ga.LastStreamID != 1 { 4134 t.Errorf("GOAWAY LastStreamID = %v; want 1", ga.LastStreamID) 4135 } 4136 4137 w.Header().Set("x-foo", "bar") 4138 }) 4139 defer st.Close() 4140 4141 st.greet() 4142 st.bodylessReq1() 4143 4144 select { 4145 case <-handlerDone: 4146 case <-time.After(5 * time.Second): 4147 t.Fatalf("server did not shutdown?") 4148 } 4149 hf := st.wantHeaders() 4150 goth := st.decodeHeader(hf.HeaderBlockFragment()) 4151 wanth := [][2]string{ 4152 {":status", "200"}, 4153 {"x-foo", "bar"}, 4154 {"content-length", "0"}, 4155 } 4156 if !reflect.DeepEqual(goth, wanth) { 4157 t.Errorf("Got headers %v; want %v", goth, wanth) 4158 } 4159 4160 n, err := st.cc.Read([]byte{0}) 4161 if n != 0 || err == nil { 4162 t.Errorf("Read = %v, %v; want 0, non-nil", n, err) 4163 } 4164 } 4165 4166 // Issue 31753: don't sniff when Content-Encoding is set 4167 func TestContentEncodingNoSniffing(t *testing.T) { 4168 type resp struct { 4169 name string 4170 body []byte 4171 // setting Content-Encoding as an interface instead of a string 4172 // directly, so as to differentiate between 3 states: 4173 // unset, empty string "" and set string "foo/bar". 4174 contentEncoding interface{} 4175 wantContentType string 4176 } 4177 4178 resps := []*resp{ 4179 { 4180 name: "gzip content-encoding, gzipped", // don't sniff. 4181 contentEncoding: "application/gzip", 4182 wantContentType: "", 4183 body: func() []byte { 4184 buf := new(bytes.Buffer) 4185 gzw := gzip.NewWriter(buf) 4186 gzw.Write([]byte("doctype html><p>Hello</p>")) 4187 gzw.Close() 4188 return buf.Bytes() 4189 }(), 4190 }, 4191 { 4192 name: "zlib content-encoding, zlibbed", // don't sniff. 4193 contentEncoding: "application/zlib", 4194 wantContentType: "", 4195 body: func() []byte { 4196 buf := new(bytes.Buffer) 4197 zw := zlib.NewWriter(buf) 4198 zw.Write([]byte("doctype html><p>Hello</p>")) 4199 zw.Close() 4200 return buf.Bytes() 4201 }(), 4202 }, 4203 { 4204 name: "no content-encoding", // must sniff. 4205 wantContentType: "application/x-gzip", 4206 body: func() []byte { 4207 buf := new(bytes.Buffer) 4208 gzw := gzip.NewWriter(buf) 4209 gzw.Write([]byte("doctype html><p>Hello</p>")) 4210 gzw.Close() 4211 return buf.Bytes() 4212 }(), 4213 }, 4214 { 4215 name: "phony content-encoding", // don't sniff. 4216 contentEncoding: "foo/bar", 4217 body: []byte("doctype html><p>Hello</p>"), 4218 }, 4219 { 4220 name: "empty but set content-encoding", 4221 contentEncoding: "", 4222 wantContentType: "audio/mpeg", 4223 body: []byte("ID3"), 4224 }, 4225 } 4226 4227 tr := &Transport{TLSClientConfig: tlsConfigInsecure} 4228 defer tr.CloseIdleConnections() 4229 4230 for _, tt := range resps { 4231 t.Run(tt.name, func(t *testing.T) { 4232 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 4233 if tt.contentEncoding != nil { 4234 w.Header().Set("Content-Encoding", tt.contentEncoding.(string)) 4235 } 4236 w.Write(tt.body) 4237 }, optOnlyServer) 4238 defer st.Close() 4239 4240 req, _ := http.NewRequest("GET", st.ts.URL, nil) 4241 res, err := tr.RoundTrip(req) 4242 if err != nil { 4243 t.Fatalf("Failed to fetch URL: %v", err) 4244 } 4245 defer res.Body.Close() 4246 if g, w := res.Header.Get("Content-Encoding"), tt.contentEncoding; g != w { 4247 if w != nil { // The case where contentEncoding was set explicitly. 4248 t.Errorf("Content-Encoding mismatch\n\tgot: %q\n\twant: %q", g, w) 4249 } else if g != "" { // "" should be the equivalent when the contentEncoding is unset. 4250 t.Errorf("Unexpected Content-Encoding %q", g) 4251 } 4252 } 4253 if g, w := res.Header.Get("Content-Type"), tt.wantContentType; g != w { 4254 t.Errorf("Content-Type mismatch\n\tgot: %q\n\twant: %q", g, w) 4255 } 4256 }) 4257 } 4258 } 4259 4260 func TestServerWindowUpdateOnBodyClose(t *testing.T) { 4261 const content = "12345678" 4262 blockCh := make(chan bool) 4263 errc := make(chan error, 1) 4264 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { 4265 buf := make([]byte, 4) 4266 n, err := io.ReadFull(r.Body, buf) 4267 if err != nil { 4268 errc <- err 4269 return 4270 } 4271 if n != len(buf) { 4272 errc <- fmt.Errorf("too few bytes read: %d", n) 4273 return 4274 } 4275 blockCh <- true 4276 <-blockCh 4277 errc <- nil 4278 }) 4279 defer st.Close() 4280 4281 st.greet() 4282 st.writeHeaders(HeadersFrameParam{ 4283 StreamID: 1, // clients send odd numbers 4284 BlockFragment: st.encodeHeader( 4285 ":method", "POST", 4286 "content-length", strconv.Itoa(len(content)), 4287 ), 4288 EndStream: false, // to say DATA frames are coming 4289 EndHeaders: true, 4290 }) 4291 st.writeData(1, false, []byte(content[:5])) 4292 <-blockCh 4293 st.stream(1).body.CloseWithError(io.EOF) 4294 st.writeData(1, false, []byte(content[5:])) 4295 blockCh <- true 4296 4297 increments := len(content) 4298 for { 4299 f, err := st.readFrame() 4300 if err == io.EOF { 4301 break 4302 } 4303 if err != nil { 4304 t.Fatal(err) 4305 } 4306 if wu, ok := f.(*WindowUpdateFrame); ok && wu.StreamID == 0 { 4307 increments -= int(wu.Increment) 4308 if increments == 0 { 4309 break 4310 } 4311 } 4312 } 4313 4314 if err := <-errc; err != nil { 4315 t.Error(err) 4316 } 4317 }