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