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.
30 "golang.org/x/net/http2/hpack"
33 var stderrVerbose = flag.Bool("stderr_verbose", false, "Mirror verbosity to stderr, unbuffered")
35 func stderrv() io.Writer {
43 type serverTester struct {
44 cc net.Conn // client conn
48 serverLogBuf bytes.Buffer // logger for httptest.Server
49 logFilter []string // substrings to filter out
50 scMu sync.Mutex // guards sc
52 hpackDec *hpack.Decoder
53 decodedHeaders [][2]string
55 // If http2debug!=2, then we capture Frame debug logs that will be written
56 // to t.Log after a test fails. The read and write logs use separate locks
57 // and buffers so we don't accidentally introduce synchronization between
58 // the read and write goroutines, which may hide data races.
59 frameReadLogMu sync.Mutex
60 frameReadLogBuf bytes.Buffer
61 frameWriteLogMu sync.Mutex
62 frameWriteLogBuf bytes.Buffer
65 headerBuf bytes.Buffer
66 hpackEnc *hpack.Encoder
70 testHookOnPanicMu = new(sync.Mutex)
74 testHookOnPanicMu.Lock()
76 testHookOnPanicMu.Unlock()
79 type serverTesterOpt string
81 var optOnlyServer = serverTesterOpt("only_server")
82 var optQuiet = serverTesterOpt("quiet_logging")
83 var optFramerReuseFrames = serverTesterOpt("frame_reuse_frames")
85 func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}) *serverTester {
88 ts := httptest.NewUnstartedServer(handler)
90 tlsConfig := &tls.Config{
91 InsecureSkipVerify: true,
92 NextProtos: []string{NextProtoTLS},
95 var onlyServer, quiet, framerReuseFrames bool
96 h2server := new(Server)
97 for _, opt := range opts {
98 switch v := opt.(type) {
99 case func(*tls.Config):
101 case func(*httptest.Server):
105 case serverTesterOpt:
111 case optFramerReuseFrames:
112 framerReuseFrames = true
114 case func(net.Conn, http.ConnState):
115 ts.Config.ConnState = v
117 t.Fatalf("unknown newServerTester option type %T", v)
121 ConfigureServer(ts.Config, h2server)
127 st.hpackEnc = hpack.NewEncoder(&st.headerBuf)
128 st.hpackDec = hpack.NewDecoder(initialHeaderTableSize, st.onHeaderField)
130 ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config
132 ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
134 ts.Config.ErrorLog = log.New(io.MultiWriter(stderrv(), twriter{t: t, st: st}, &st.serverLogBuf), "", log.LstdFlags)
139 t.Logf("Running test server at: %s", ts.URL)
141 testHookGetServerConn = func(v *serverConn) {
143 defer st.scMu.Unlock()
146 log.SetOutput(io.MultiWriter(stderrv(), twriter{t: t, st: st}))
148 cc, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig)
153 st.fr = NewFramer(cc, cc)
154 if framerReuseFrames {
155 st.fr.SetReuseFrames()
157 if !logFrameReads && !logFrameWrites {
158 st.fr.debugReadLoggerf = func(m string, v ...interface{}) {
159 m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
160 st.frameReadLogMu.Lock()
161 fmt.Fprintf(&st.frameReadLogBuf, m, v...)
162 st.frameReadLogMu.Unlock()
164 st.fr.debugWriteLoggerf = func(m string, v ...interface{}) {
165 m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
166 st.frameWriteLogMu.Lock()
167 fmt.Fprintf(&st.frameWriteLogBuf, m, v...)
168 st.frameWriteLogMu.Unlock()
170 st.fr.logReads = true
171 st.fr.logWrites = true
177 func (st *serverTester) closeConn() {
179 defer st.scMu.Unlock()
183 func (st *serverTester) addLogFilter(phrase string) {
184 st.logFilter = append(st.logFilter, phrase)
187 func (st *serverTester) stream(id uint32) *stream {
188 ch := make(chan *stream, 1)
189 st.sc.serveMsgCh <- func(int) {
190 ch <- st.sc.streams[id]
195 func (st *serverTester) streamState(id uint32) streamState {
196 ch := make(chan streamState, 1)
197 st.sc.serveMsgCh <- func(int) {
198 state, _ := st.sc.state(id)
204 // loopNum reports how many times this conn's select loop has gone around.
205 func (st *serverTester) loopNum() int {
206 lastc := make(chan int, 1)
207 st.sc.serveMsgCh <- func(loopNum int) {
213 // awaitIdle heuristically awaits for the server conn's select loop to be idle.
214 // The heuristic is that the server connection's serve loop must schedule
215 // 50 times in a row without any channel sends or receives occurring.
216 func (st *serverTester) awaitIdle() {
230 func (st *serverTester) Close() {
232 st.frameReadLogMu.Lock()
233 if st.frameReadLogBuf.Len() > 0 {
234 st.t.Logf("Framer read log:\n%s", st.frameReadLogBuf.String())
236 st.frameReadLogMu.Unlock()
238 st.frameWriteLogMu.Lock()
239 if st.frameWriteLogBuf.Len() > 0 {
240 st.t.Logf("Framer write log:\n%s", st.frameWriteLogBuf.String())
242 st.frameWriteLogMu.Unlock()
244 // If we failed already (and are likely in a Fatal,
245 // unwindowing), force close the connection, so the
246 // httptest.Server doesn't wait forever for the conn
256 log.SetOutput(os.Stderr)
259 // greet initiates the client's HTTP/2 connection into a state where
260 // frames may be sent.
261 func (st *serverTester) greet() {
262 st.greetAndCheckSettings(func(Setting) error { return nil })
265 func (st *serverTester) greetAndCheckSettings(checkSetting func(s Setting) error) {
267 st.writeInitialSettings()
268 st.wantSettings().ForeachSetting(checkSetting)
269 st.writeSettingsAck()
271 // The initial WINDOW_UPDATE and SETTINGS ACK can come in any order.
272 var gotSettingsAck bool
273 var gotWindowUpdate bool
275 for i := 0; i < 2; i++ {
276 f, err := st.readFrame()
280 switch f := f.(type) {
282 if !f.Header().Flags.Has(FlagSettingsAck) {
283 st.t.Fatal("Settings Frame didn't have ACK set")
285 gotSettingsAck = true
287 case *WindowUpdateFrame:
288 if f.FrameHeader.StreamID != 0 {
289 st.t.Fatalf("WindowUpdate StreamID = %d; want 0", f.FrameHeader.StreamID)
291 incr := uint32((&Server{}).initialConnRecvWindowSize() - initialWindowSize)
292 if f.Increment != incr {
293 st.t.Fatalf("WindowUpdate increment = %d; want %d", f.Increment, incr)
295 gotWindowUpdate = true
298 st.t.Fatalf("Wanting a settings ACK or window update, received a %T", f)
303 st.t.Fatalf("Didn't get a settings ACK")
305 if !gotWindowUpdate {
306 st.t.Fatalf("Didn't get a window update")
310 func (st *serverTester) writePreface() {
311 n, err := st.cc.Write(clientPreface)
313 st.t.Fatalf("Error writing client preface: %v", err)
315 if n != len(clientPreface) {
316 st.t.Fatalf("Writing client preface, wrote %d bytes; want %d", n, len(clientPreface))
320 func (st *serverTester) writeInitialSettings() {
321 if err := st.fr.WriteSettings(); err != nil {
322 st.t.Fatalf("Error writing initial SETTINGS frame from client to server: %v", err)
326 func (st *serverTester) writeSettingsAck() {
327 if err := st.fr.WriteSettingsAck(); err != nil {
328 st.t.Fatalf("Error writing ACK of server's SETTINGS: %v", err)
332 func (st *serverTester) writeHeaders(p HeadersFrameParam) {
333 if err := st.fr.WriteHeaders(p); err != nil {
334 st.t.Fatalf("Error writing HEADERS: %v", err)
338 func (st *serverTester) writePriority(id uint32, p PriorityParam) {
339 if err := st.fr.WritePriority(id, p); err != nil {
340 st.t.Fatalf("Error writing PRIORITY: %v", err)
344 func (st *serverTester) encodeHeaderField(k, v string) {
345 err := st.hpackEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
347 st.t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err)
351 // encodeHeaderRaw is the magic-free version of encodeHeader.
352 // It takes 0 or more (k, v) pairs and encodes them.
353 func (st *serverTester) encodeHeaderRaw(headers ...string) []byte {
354 if len(headers)%2 == 1 {
355 panic("odd number of kv args")
358 for len(headers) > 0 {
359 k, v := headers[0], headers[1]
360 st.encodeHeaderField(k, v)
361 headers = headers[2:]
363 return st.headerBuf.Bytes()
366 // encodeHeader encodes headers and returns their HPACK bytes. headers
367 // must contain an even number of key/value pairs. There may be
368 // multiple pairs for keys (e.g. "cookie"). The :method, :path, and
369 // :scheme headers default to GET, / and https. The :authority header
370 // defaults to st.ts.Listener.Addr().
371 func (st *serverTester) encodeHeader(headers ...string) []byte {
372 if len(headers)%2 == 1 {
373 panic("odd number of kv args")
377 defaultAuthority := st.ts.Listener.Addr().String()
379 if len(headers) == 0 {
380 // Fast path, mostly for benchmarks, so test code doesn't pollute
381 // profiles when we're looking to improve server allocations.
382 st.encodeHeaderField(":method", "GET")
383 st.encodeHeaderField(":scheme", "https")
384 st.encodeHeaderField(":authority", defaultAuthority)
385 st.encodeHeaderField(":path", "/")
386 return st.headerBuf.Bytes()
389 if len(headers) == 2 && headers[0] == ":method" {
390 // Another fast path for benchmarks.
391 st.encodeHeaderField(":method", headers[1])
392 st.encodeHeaderField(":scheme", "https")
393 st.encodeHeaderField(":authority", defaultAuthority)
394 st.encodeHeaderField(":path", "/")
395 return st.headerBuf.Bytes()
398 pseudoCount := map[string]int{}
399 keys := []string{":method", ":scheme", ":authority", ":path"}
400 vals := map[string][]string{
402 ":scheme": {"https"},
403 ":authority": {defaultAuthority},
406 for len(headers) > 0 {
407 k, v := headers[0], headers[1]
408 headers = headers[2:]
409 if _, ok := vals[k]; !ok {
410 keys = append(keys, k)
412 if strings.HasPrefix(k, ":") {
414 if pseudoCount[k] == 1 {
415 vals[k] = []string{v}
417 // Allows testing of invalid headers w/ dup pseudo fields.
418 vals[k] = append(vals[k], v)
421 vals[k] = append(vals[k], v)
424 for _, k := range keys {
425 for _, v := range vals[k] {
426 st.encodeHeaderField(k, v)
429 return st.headerBuf.Bytes()
432 // bodylessReq1 writes a HEADERS frames with StreamID 1 and EndStream and EndHeaders set.
433 func (st *serverTester) bodylessReq1(headers ...string) {
434 st.writeHeaders(HeadersFrameParam{
435 StreamID: 1, // clients send odd numbers
436 BlockFragment: st.encodeHeader(headers...),
442 func (st *serverTester) writeData(streamID uint32, endStream bool, data []byte) {
443 if err := st.fr.WriteData(streamID, endStream, data); err != nil {
444 st.t.Fatalf("Error writing DATA: %v", err)
448 func (st *serverTester) writeDataPadded(streamID uint32, endStream bool, data, pad []byte) {
449 if err := st.fr.WriteDataPadded(streamID, endStream, data, pad); err != nil {
450 st.t.Fatalf("Error writing DATA: %v", err)
454 func readFrameTimeout(fr *Framer, wait time.Duration) (Frame, error) {
455 ch := make(chan interface{}, 1)
457 fr, err := fr.ReadFrame()
464 t := time.NewTimer(wait)
468 if fr, ok := v.(Frame); ok {
471 return nil, v.(error)
473 return nil, errors.New("timeout waiting for frame")
477 func (st *serverTester) readFrame() (Frame, error) {
478 return readFrameTimeout(st.fr, 2*time.Second)
481 func (st *serverTester) wantHeaders() *HeadersFrame {
482 f, err := st.readFrame()
484 st.t.Fatalf("Error while expecting a HEADERS frame: %v", err)
486 hf, ok := f.(*HeadersFrame)
488 st.t.Fatalf("got a %T; want *HeadersFrame", f)
493 func (st *serverTester) wantContinuation() *ContinuationFrame {
494 f, err := st.readFrame()
496 st.t.Fatalf("Error while expecting a CONTINUATION frame: %v", err)
498 cf, ok := f.(*ContinuationFrame)
500 st.t.Fatalf("got a %T; want *ContinuationFrame", f)
505 func (st *serverTester) wantData() *DataFrame {
506 f, err := st.readFrame()
508 st.t.Fatalf("Error while expecting a DATA frame: %v", err)
510 df, ok := f.(*DataFrame)
512 st.t.Fatalf("got a %T; want *DataFrame", f)
517 func (st *serverTester) wantSettings() *SettingsFrame {
518 f, err := st.readFrame()
520 st.t.Fatalf("Error while expecting a SETTINGS frame: %v", err)
522 sf, ok := f.(*SettingsFrame)
524 st.t.Fatalf("got a %T; want *SettingsFrame", f)
529 func (st *serverTester) wantPing() *PingFrame {
530 f, err := st.readFrame()
532 st.t.Fatalf("Error while expecting a PING frame: %v", err)
534 pf, ok := f.(*PingFrame)
536 st.t.Fatalf("got a %T; want *PingFrame", f)
541 func (st *serverTester) wantGoAway() *GoAwayFrame {
542 f, err := st.readFrame()
544 st.t.Fatalf("Error while expecting a GOAWAY frame: %v", err)
546 gf, ok := f.(*GoAwayFrame)
548 st.t.Fatalf("got a %T; want *GoAwayFrame", f)
553 func (st *serverTester) wantRSTStream(streamID uint32, errCode ErrCode) {
554 f, err := st.readFrame()
556 st.t.Fatalf("Error while expecting an RSTStream frame: %v", err)
558 rs, ok := f.(*RSTStreamFrame)
560 st.t.Fatalf("got a %T; want *RSTStreamFrame", f)
562 if rs.FrameHeader.StreamID != streamID {
563 st.t.Fatalf("RSTStream StreamID = %d; want %d", rs.FrameHeader.StreamID, streamID)
565 if rs.ErrCode != errCode {
566 st.t.Fatalf("RSTStream ErrCode = %d (%s); want %d (%s)", rs.ErrCode, rs.ErrCode, errCode, errCode)
570 func (st *serverTester) wantWindowUpdate(streamID, incr uint32) {
571 f, err := st.readFrame()
573 st.t.Fatalf("Error while expecting a WINDOW_UPDATE frame: %v", err)
575 wu, ok := f.(*WindowUpdateFrame)
577 st.t.Fatalf("got a %T; want *WindowUpdateFrame", f)
579 if wu.FrameHeader.StreamID != streamID {
580 st.t.Fatalf("WindowUpdate StreamID = %d; want %d", wu.FrameHeader.StreamID, streamID)
582 if wu.Increment != incr {
583 st.t.Fatalf("WindowUpdate increment = %d; want %d", wu.Increment, incr)
587 func (st *serverTester) wantSettingsAck() {
588 f, err := st.readFrame()
592 sf, ok := f.(*SettingsFrame)
594 st.t.Fatalf("Wanting a settings ACK, received a %T", f)
596 if !sf.Header().Flags.Has(FlagSettingsAck) {
597 st.t.Fatal("Settings Frame didn't have ACK set")
601 func (st *serverTester) wantPushPromise() *PushPromiseFrame {
602 f, err := st.readFrame()
606 ppf, ok := f.(*PushPromiseFrame)
608 st.t.Fatalf("Wanted PushPromise, received %T", ppf)
613 func TestServer(t *testing.T) {
614 gotReq := make(chan bool, 1)
615 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
616 w.Header().Set("Foo", "Bar")
622 The server connection preface consists of a potentially empty
623 SETTINGS frame ([SETTINGS]) that MUST be the first frame the
624 server sends in the HTTP/2 connection.
628 st.writeHeaders(HeadersFrameParam{
629 StreamID: 1, // clients send odd numbers
630 BlockFragment: st.encodeHeader(),
631 EndStream: true, // no DATA frames
637 case <-time.After(2 * time.Second):
638 t.Error("timeout waiting for request")
642 func TestServer_Request_Get(t *testing.T) {
643 testServerRequest(t, func(st *serverTester) {
644 st.writeHeaders(HeadersFrameParam{
645 StreamID: 1, // clients send odd numbers
646 BlockFragment: st.encodeHeader("foo-bar", "some-value"),
647 EndStream: true, // no DATA frames
650 }, func(r *http.Request) {
651 if r.Method != "GET" {
652 t.Errorf("Method = %q; want GET", r.Method)
654 if r.URL.Path != "/" {
655 t.Errorf("URL.Path = %q; want /", r.URL.Path)
657 if r.ContentLength != 0 {
658 t.Errorf("ContentLength = %v; want 0", r.ContentLength)
661 t.Error("Close = true; want false")
663 if !strings.Contains(r.RemoteAddr, ":") {
664 t.Errorf("RemoteAddr = %q; want something with a colon", r.RemoteAddr)
666 if r.Proto != "HTTP/2.0" || r.ProtoMajor != 2 || r.ProtoMinor != 0 {
667 t.Errorf("Proto = %q Major=%v,Minor=%v; want HTTP/2.0", r.Proto, r.ProtoMajor, r.ProtoMinor)
669 wantHeader := http.Header{
670 "Foo-Bar": []string{"some-value"},
672 if !reflect.DeepEqual(r.Header, wantHeader) {
673 t.Errorf("Header = %#v; want %#v", r.Header, wantHeader)
675 if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 {
676 t.Errorf("Read = %d, %v; want 0, EOF", n, err)
681 func TestServer_Request_Get_PathSlashes(t *testing.T) {
682 testServerRequest(t, func(st *serverTester) {
683 st.writeHeaders(HeadersFrameParam{
684 StreamID: 1, // clients send odd numbers
685 BlockFragment: st.encodeHeader(":path", "/%2f/"),
686 EndStream: true, // no DATA frames
689 }, func(r *http.Request) {
690 if r.RequestURI != "/%2f/" {
691 t.Errorf("RequestURI = %q; want /%%2f/", r.RequestURI)
693 if r.URL.Path != "///" {
694 t.Errorf("URL.Path = %q; want ///", r.URL.Path)
699 // TODO: add a test with EndStream=true on the HEADERS but setting a
700 // Content-Length anyway. Should we just omit it and force it to
703 func TestServer_Request_Post_NoContentLength_EndStream(t *testing.T) {
704 testServerRequest(t, func(st *serverTester) {
705 st.writeHeaders(HeadersFrameParam{
706 StreamID: 1, // clients send odd numbers
707 BlockFragment: st.encodeHeader(":method", "POST"),
711 }, func(r *http.Request) {
712 if r.Method != "POST" {
713 t.Errorf("Method = %q; want POST", r.Method)
715 if r.ContentLength != 0 {
716 t.Errorf("ContentLength = %v; want 0", r.ContentLength)
718 if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 {
719 t.Errorf("Read = %d, %v; want 0, EOF", n, err)
724 func TestServer_Request_Post_Body_ImmediateEOF(t *testing.T) {
725 testBodyContents(t, -1, "", func(st *serverTester) {
726 st.writeHeaders(HeadersFrameParam{
727 StreamID: 1, // clients send odd numbers
728 BlockFragment: st.encodeHeader(":method", "POST"),
729 EndStream: false, // to say DATA frames are coming
732 st.writeData(1, true, nil) // just kidding. empty body.
736 func TestServer_Request_Post_Body_OneData(t *testing.T) {
737 const content = "Some content"
738 testBodyContents(t, -1, content, func(st *serverTester) {
739 st.writeHeaders(HeadersFrameParam{
740 StreamID: 1, // clients send odd numbers
741 BlockFragment: st.encodeHeader(":method", "POST"),
742 EndStream: false, // to say DATA frames are coming
745 st.writeData(1, true, []byte(content))
749 func TestServer_Request_Post_Body_TwoData(t *testing.T) {
750 const content = "Some content"
751 testBodyContents(t, -1, content, func(st *serverTester) {
752 st.writeHeaders(HeadersFrameParam{
753 StreamID: 1, // clients send odd numbers
754 BlockFragment: st.encodeHeader(":method", "POST"),
755 EndStream: false, // to say DATA frames are coming
758 st.writeData(1, false, []byte(content[:5]))
759 st.writeData(1, true, []byte(content[5:]))
763 func TestServer_Request_Post_Body_ContentLength_Correct(t *testing.T) {
764 const content = "Some content"
765 testBodyContents(t, int64(len(content)), content, func(st *serverTester) {
766 st.writeHeaders(HeadersFrameParam{
767 StreamID: 1, // clients send odd numbers
768 BlockFragment: st.encodeHeader(
770 "content-length", strconv.Itoa(len(content)),
772 EndStream: false, // to say DATA frames are coming
775 st.writeData(1, true, []byte(content))
779 func TestServer_Request_Post_Body_ContentLength_TooLarge(t *testing.T) {
780 testBodyContentsFail(t, 3, "request declared a Content-Length of 3 but only wrote 2 bytes",
781 func(st *serverTester) {
782 st.writeHeaders(HeadersFrameParam{
783 StreamID: 1, // clients send odd numbers
784 BlockFragment: st.encodeHeader(
786 "content-length", "3",
788 EndStream: false, // to say DATA frames are coming
791 st.writeData(1, true, []byte("12"))
795 func TestServer_Request_Post_Body_ContentLength_TooSmall(t *testing.T) {
796 testBodyContentsFail(t, 4, "sender tried to send more than declared Content-Length of 4 bytes",
797 func(st *serverTester) {
798 st.writeHeaders(HeadersFrameParam{
799 StreamID: 1, // clients send odd numbers
800 BlockFragment: st.encodeHeader(
802 "content-length", "4",
804 EndStream: false, // to say DATA frames are coming
807 st.writeData(1, true, []byte("12345"))
811 func testBodyContents(t *testing.T, wantContentLength int64, wantBody string, write func(st *serverTester)) {
812 testServerRequest(t, write, func(r *http.Request) {
813 if r.Method != "POST" {
814 t.Errorf("Method = %q; want POST", r.Method)
816 if r.ContentLength != wantContentLength {
817 t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength)
819 all, err := ioutil.ReadAll(r.Body)
823 if string(all) != wantBody {
824 t.Errorf("Read = %q; want %q", all, wantBody)
826 if err := r.Body.Close(); err != nil {
827 t.Fatalf("Close: %v", err)
832 func testBodyContentsFail(t *testing.T, wantContentLength int64, wantReadError string, write func(st *serverTester)) {
833 testServerRequest(t, write, func(r *http.Request) {
834 if r.Method != "POST" {
835 t.Errorf("Method = %q; want POST", r.Method)
837 if r.ContentLength != wantContentLength {
838 t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength)
840 all, err := ioutil.ReadAll(r.Body)
842 t.Fatalf("expected an error (%q) reading from the body. Successfully read %q instead.",
845 if !strings.Contains(err.Error(), wantReadError) {
846 t.Fatalf("Body.Read = %v; want substring %q", err, wantReadError)
848 if err := r.Body.Close(); err != nil {
849 t.Fatalf("Close: %v", err)
854 // Using a Host header, instead of :authority
855 func TestServer_Request_Get_Host(t *testing.T) {
856 const host = "example.com"
857 testServerRequest(t, func(st *serverTester) {
858 st.writeHeaders(HeadersFrameParam{
859 StreamID: 1, // clients send odd numbers
860 BlockFragment: st.encodeHeader(":authority", "", "host", host),
864 }, func(r *http.Request) {
866 t.Errorf("Host = %q; want %q", r.Host, host)
871 // Using an :authority pseudo-header, instead of Host
872 func TestServer_Request_Get_Authority(t *testing.T) {
873 const host = "example.com"
874 testServerRequest(t, func(st *serverTester) {
875 st.writeHeaders(HeadersFrameParam{
876 StreamID: 1, // clients send odd numbers
877 BlockFragment: st.encodeHeader(":authority", host),
881 }, func(r *http.Request) {
883 t.Errorf("Host = %q; want %q", r.Host, host)
888 func TestServer_Request_WithContinuation(t *testing.T) {
889 wantHeader := http.Header{
890 "Foo-One": []string{"value-one"},
891 "Foo-Two": []string{"value-two"},
892 "Foo-Three": []string{"value-three"},
894 testServerRequest(t, func(st *serverTester) {
895 fullHeaders := st.encodeHeader(
896 "foo-one", "value-one",
897 "foo-two", "value-two",
898 "foo-three", "value-three",
900 remain := fullHeaders
902 for len(remain) > 0 {
903 const maxChunkSize = 5
905 if len(chunk) > maxChunkSize {
906 chunk = chunk[:maxChunkSize]
908 remain = remain[len(chunk):]
911 st.writeHeaders(HeadersFrameParam{
912 StreamID: 1, // clients send odd numbers
913 BlockFragment: chunk,
914 EndStream: true, // no DATA frames
915 EndHeaders: false, // we'll have continuation frames
918 err := st.fr.WriteContinuation(1, len(remain) == 0, chunk)
926 t.Fatal("too few chunks")
928 }, func(r *http.Request) {
929 if !reflect.DeepEqual(r.Header, wantHeader) {
930 t.Errorf("Header = %#v; want %#v", r.Header, wantHeader)
935 // Concatenated cookie headers. ("8.1.2.5 Compressing the Cookie Header Field")
936 func TestServer_Request_CookieConcat(t *testing.T) {
937 const host = "example.com"
938 testServerRequest(t, func(st *serverTester) {
945 }, func(r *http.Request) {
946 const want = "a=b; c=d; e=f"
947 if got := r.Header.Get("Cookie"); got != want {
948 t.Errorf("Cookie = %q; want %q", got, want)
953 func TestServer_Request_Reject_CapitalHeader(t *testing.T) {
954 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("UPPER", "v") })
957 func TestServer_Request_Reject_HeaderFieldNameColon(t *testing.T) {
958 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("has:colon", "v") })
961 func TestServer_Request_Reject_HeaderFieldNameNULL(t *testing.T) {
962 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("has\x00null", "v") })
965 func TestServer_Request_Reject_HeaderFieldNameEmpty(t *testing.T) {
966 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("", "v") })
969 func TestServer_Request_Reject_HeaderFieldValueNewline(t *testing.T) {
970 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\nnewline") })
973 func TestServer_Request_Reject_HeaderFieldValueCR(t *testing.T) {
974 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\rcarriage") })
977 func TestServer_Request_Reject_HeaderFieldValueDEL(t *testing.T) {
978 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\x7fdel") })
981 func TestServer_Request_Reject_Pseudo_Missing_method(t *testing.T) {
982 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":method", "") })
985 func TestServer_Request_Reject_Pseudo_ExactlyOne(t *testing.T) {
986 // 8.1.2.3 Request Pseudo-Header Fields
987 // "All HTTP/2 requests MUST include exactly one valid value" ...
988 testRejectRequest(t, func(st *serverTester) {
989 st.addLogFilter("duplicate pseudo-header")
990 st.bodylessReq1(":method", "GET", ":method", "POST")
994 func TestServer_Request_Reject_Pseudo_AfterRegular(t *testing.T) {
995 // 8.1.2.3 Request Pseudo-Header Fields
996 // "All pseudo-header fields MUST appear in the header block
997 // before regular header fields. Any request or response that
998 // contains a pseudo-header field that appears in a header
999 // block after a regular header field MUST be treated as
1000 // malformed (Section 8.1.2.6)."
1001 testRejectRequest(t, func(st *serverTester) {
1002 st.addLogFilter("pseudo-header after regular header")
1003 var buf bytes.Buffer
1004 enc := hpack.NewEncoder(&buf)
1005 enc.WriteField(hpack.HeaderField{Name: ":method", Value: "GET"})
1006 enc.WriteField(hpack.HeaderField{Name: "regular", Value: "foobar"})
1007 enc.WriteField(hpack.HeaderField{Name: ":path", Value: "/"})
1008 enc.WriteField(hpack.HeaderField{Name: ":scheme", Value: "https"})
1009 st.writeHeaders(HeadersFrameParam{
1010 StreamID: 1, // clients send odd numbers
1011 BlockFragment: buf.Bytes(),
1018 func TestServer_Request_Reject_Pseudo_Missing_path(t *testing.T) {
1019 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":path", "") })
1022 func TestServer_Request_Reject_Pseudo_Missing_scheme(t *testing.T) {
1023 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "") })
1026 func TestServer_Request_Reject_Pseudo_scheme_invalid(t *testing.T) {
1027 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "bogus") })
1030 func TestServer_Request_Reject_Pseudo_Unknown(t *testing.T) {
1031 testRejectRequest(t, func(st *serverTester) {
1032 st.addLogFilter(`invalid pseudo-header ":unknown_thing"`)
1033 st.bodylessReq1(":unknown_thing", "")
1037 func testRejectRequest(t *testing.T, send func(*serverTester)) {
1038 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1039 t.Error("server request made it to handler; should've been rejected")
1045 st.wantRSTStream(1, ErrCodeProtocol)
1048 func testRejectRequestWithProtocolError(t *testing.T, send func(*serverTester)) {
1049 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1050 t.Error("server request made it to handler; should've been rejected")
1056 gf := st.wantGoAway()
1057 if gf.ErrCode != ErrCodeProtocol {
1058 t.Errorf("err code = %v; want %v", gf.ErrCode, ErrCodeProtocol)
1062 // Section 5.1, on idle connections: "Receiving any frame other than
1063 // HEADERS or PRIORITY on a stream in this state MUST be treated as a
1064 // connection error (Section 5.4.1) of type PROTOCOL_ERROR."
1065 func TestRejectFrameOnIdle_WindowUpdate(t *testing.T) {
1066 testRejectRequestWithProtocolError(t, func(st *serverTester) {
1067 st.fr.WriteWindowUpdate(123, 456)
1070 func TestRejectFrameOnIdle_Data(t *testing.T) {
1071 testRejectRequestWithProtocolError(t, func(st *serverTester) {
1072 st.fr.WriteData(123, true, nil)
1075 func TestRejectFrameOnIdle_RSTStream(t *testing.T) {
1076 testRejectRequestWithProtocolError(t, func(st *serverTester) {
1077 st.fr.WriteRSTStream(123, ErrCodeCancel)
1081 func TestServer_Request_Connect(t *testing.T) {
1082 testServerRequest(t, func(st *serverTester) {
1083 st.writeHeaders(HeadersFrameParam{
1085 BlockFragment: st.encodeHeaderRaw(
1086 ":method", "CONNECT",
1087 ":authority", "example.com:123",
1092 }, func(r *http.Request) {
1093 if g, w := r.Method, "CONNECT"; g != w {
1094 t.Errorf("Method = %q; want %q", g, w)
1096 if g, w := r.RequestURI, "example.com:123"; g != w {
1097 t.Errorf("RequestURI = %q; want %q", g, w)
1099 if g, w := r.URL.Host, "example.com:123"; g != w {
1100 t.Errorf("URL.Host = %q; want %q", g, w)
1105 func TestServer_Request_Connect_InvalidPath(t *testing.T) {
1106 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
1107 st.writeHeaders(HeadersFrameParam{
1109 BlockFragment: st.encodeHeaderRaw(
1110 ":method", "CONNECT",
1111 ":authority", "example.com:123",
1120 func TestServer_Request_Connect_InvalidScheme(t *testing.T) {
1121 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
1122 st.writeHeaders(HeadersFrameParam{
1124 BlockFragment: st.encodeHeaderRaw(
1125 ":method", "CONNECT",
1126 ":authority", "example.com:123",
1135 func TestServer_Ping(t *testing.T) {
1136 st := newServerTester(t, nil)
1140 // Server should ignore this one, since it has ACK set.
1141 ackPingData := [8]byte{1, 2, 4, 8, 16, 32, 64, 128}
1142 if err := st.fr.WritePing(true, ackPingData); err != nil {
1146 // But the server should reply to this one, since ACK is false.
1147 pingData := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
1148 if err := st.fr.WritePing(false, pingData); err != nil {
1153 if !pf.Flags.Has(FlagPingAck) {
1154 t.Error("response ping doesn't have ACK set")
1156 if pf.Data != pingData {
1157 t.Errorf("response ping has data %q; want %q", pf.Data, pingData)
1161 func TestServer_RejectsLargeFrames(t *testing.T) {
1162 if runtime.GOOS == "windows" {
1163 t.Skip("see golang.org/issue/13434")
1166 st := newServerTester(t, nil)
1170 // Write too large of a frame (too large by one byte)
1171 // We ignore the return value because it's expected that the server
1172 // will only read the first 9 bytes (the headre) and then disconnect.
1173 st.fr.WriteRawFrame(0xff, 0, 0, make([]byte, defaultMaxReadFrameSize+1))
1175 gf := st.wantGoAway()
1176 if gf.ErrCode != ErrCodeFrameSize {
1177 t.Errorf("GOAWAY err = %v; want %v", gf.ErrCode, ErrCodeFrameSize)
1179 if st.serverLogBuf.Len() != 0 {
1180 // Previously we spun here for a bit until the GOAWAY disconnect
1181 // timer fired, logging while we fired.
1182 t.Errorf("unexpected server output: %.500s\n", st.serverLogBuf.Bytes())
1186 func TestServer_Handler_Sends_WindowUpdate(t *testing.T) {
1187 puppet := newHandlerPuppet()
1188 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1196 st.writeHeaders(HeadersFrameParam{
1197 StreamID: 1, // clients send odd numbers
1198 BlockFragment: st.encodeHeader(":method", "POST"),
1199 EndStream: false, // data coming
1202 st.writeData(1, false, []byte("abcdef"))
1203 puppet.do(readBodyHandler(t, "abc"))
1204 st.wantWindowUpdate(0, 3)
1205 st.wantWindowUpdate(1, 3)
1207 puppet.do(readBodyHandler(t, "def"))
1208 st.wantWindowUpdate(0, 3)
1209 st.wantWindowUpdate(1, 3)
1211 st.writeData(1, true, []byte("ghijkl")) // END_STREAM here
1212 puppet.do(readBodyHandler(t, "ghi"))
1213 puppet.do(readBodyHandler(t, "jkl"))
1214 st.wantWindowUpdate(0, 3)
1215 st.wantWindowUpdate(0, 3) // no more stream-level, since END_STREAM
1218 // the version of the TestServer_Handler_Sends_WindowUpdate with padding.
1219 // See golang.org/issue/16556
1220 func TestServer_Handler_Sends_WindowUpdate_Padding(t *testing.T) {
1221 puppet := newHandlerPuppet()
1222 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1230 st.writeHeaders(HeadersFrameParam{
1232 BlockFragment: st.encodeHeader(":method", "POST"),
1236 st.writeDataPadded(1, false, []byte("abcdef"), []byte{0, 0, 0, 0})
1238 // Expect to immediately get our 5 bytes of padding back for
1239 // both the connection and stream (4 bytes of padding + 1 byte of length)
1240 st.wantWindowUpdate(0, 5)
1241 st.wantWindowUpdate(1, 5)
1243 puppet.do(readBodyHandler(t, "abc"))
1244 st.wantWindowUpdate(0, 3)
1245 st.wantWindowUpdate(1, 3)
1247 puppet.do(readBodyHandler(t, "def"))
1248 st.wantWindowUpdate(0, 3)
1249 st.wantWindowUpdate(1, 3)
1252 func TestServer_Send_GoAway_After_Bogus_WindowUpdate(t *testing.T) {
1253 st := newServerTester(t, nil)
1256 if err := st.fr.WriteWindowUpdate(0, 1<<31-1); err != nil {
1259 gf := st.wantGoAway()
1260 if gf.ErrCode != ErrCodeFlowControl {
1261 t.Errorf("GOAWAY err = %v; want %v", gf.ErrCode, ErrCodeFlowControl)
1263 if gf.LastStreamID != 0 {
1264 t.Errorf("GOAWAY last stream ID = %v; want %v", gf.LastStreamID, 0)
1268 func TestServer_Send_RstStream_After_Bogus_WindowUpdate(t *testing.T) {
1269 inHandler := make(chan bool)
1270 blockHandler := make(chan bool)
1271 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1276 defer close(blockHandler)
1278 st.writeHeaders(HeadersFrameParam{
1280 BlockFragment: st.encodeHeader(":method", "POST"),
1281 EndStream: false, // keep it open
1285 // Send a bogus window update:
1286 if err := st.fr.WriteWindowUpdate(1, 1<<31-1); err != nil {
1289 st.wantRSTStream(1, ErrCodeFlowControl)
1292 // testServerPostUnblock sends a hanging POST with unsent data to handler,
1293 // then runs fn once in the handler, and verifies that the error returned from
1294 // handler is acceptable. It fails if takes over 5 seconds for handler to exit.
1295 func testServerPostUnblock(t *testing.T,
1296 handler func(http.ResponseWriter, *http.Request) error,
1297 fn func(*serverTester),
1298 checkErr func(error),
1299 otherHeaders ...string) {
1300 inHandler := make(chan bool)
1301 errc := make(chan error, 1)
1302 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1304 errc <- handler(w, r)
1308 st.writeHeaders(HeadersFrameParam{
1310 BlockFragment: st.encodeHeader(append([]string{":method", "POST"}, otherHeaders...)...),
1311 EndStream: false, // keep it open
1318 if checkErr != nil {
1321 case <-time.After(5 * time.Second):
1322 t.Fatal("timeout waiting for Handler to return")
1326 func TestServer_RSTStream_Unblocks_Read(t *testing.T) {
1327 testServerPostUnblock(t,
1328 func(w http.ResponseWriter, r *http.Request) (err error) {
1329 _, err = r.Body.Read(make([]byte, 1))
1332 func(st *serverTester) {
1333 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
1338 want := StreamError{StreamID: 0x1, Code: 0x8}
1339 if !reflect.DeepEqual(err, want) {
1340 t.Errorf("Read error = %v; want %v", err, want)
1346 func TestServer_RSTStream_Unblocks_Header_Write(t *testing.T) {
1347 // Run this test a bunch, because it doesn't always
1348 // deadlock. But with a bunch, it did.
1350 if testing.Short() {
1353 for i := 0; i < n; i++ {
1354 testServer_RSTStream_Unblocks_Header_Write(t)
1358 func testServer_RSTStream_Unblocks_Header_Write(t *testing.T) {
1359 inHandler := make(chan bool, 1)
1360 unblockHandler := make(chan bool, 1)
1361 headerWritten := make(chan bool, 1)
1362 wroteRST := make(chan bool, 1)
1364 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1367 w.Header().Set("foo", "bar")
1369 w.(http.Flusher).Flush()
1370 headerWritten <- true
1376 st.writeHeaders(HeadersFrameParam{
1378 BlockFragment: st.encodeHeader(":method", "POST"),
1379 EndStream: false, // keep it open
1383 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
1389 case <-headerWritten:
1390 case <-time.After(2 * time.Second):
1391 t.Error("timeout waiting for header write")
1393 unblockHandler <- true
1396 func TestServer_DeadConn_Unblocks_Read(t *testing.T) {
1397 testServerPostUnblock(t,
1398 func(w http.ResponseWriter, r *http.Request) (err error) {
1399 _, err = r.Body.Read(make([]byte, 1))
1402 func(st *serverTester) { st.cc.Close() },
1405 t.Error("unexpected nil error from Request.Body.Read")
1411 var blockUntilClosed = func(w http.ResponseWriter, r *http.Request) error {
1412 <-w.(http.CloseNotifier).CloseNotify()
1416 func TestServer_CloseNotify_After_RSTStream(t *testing.T) {
1417 testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) {
1418 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
1424 func TestServer_CloseNotify_After_ConnClose(t *testing.T) {
1425 testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) { st.cc.Close() }, nil)
1428 // that CloseNotify unblocks after a stream error due to the client's
1429 // problem that's unrelated to them explicitly canceling it (which is
1430 // TestServer_CloseNotify_After_RSTStream above)
1431 func TestServer_CloseNotify_After_StreamError(t *testing.T) {
1432 testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) {
1433 // data longer than declared Content-Length => stream error
1434 st.writeData(1, true, []byte("1234"))
1435 }, nil, "content-length", "3")
1438 func TestServer_StateTransitions(t *testing.T) {
1439 var st *serverTester
1440 inHandler := make(chan bool)
1441 writeData := make(chan bool)
1442 leaveHandler := make(chan bool)
1443 st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1445 if st.stream(1) == nil {
1446 t.Errorf("nil stream 1 in handler")
1448 if got, want := st.streamState(1), stateOpen; got != want {
1449 t.Errorf("in handler, state is %v; want %v", got, want)
1452 if n, err := r.Body.Read(make([]byte, 1)); n != 0 || err != io.EOF {
1453 t.Errorf("body read = %d, %v; want 0, EOF", n, err)
1455 if got, want := st.streamState(1), stateHalfClosedRemote; got != want {
1456 t.Errorf("in handler, state is %v; want %v", got, want)
1462 if st.stream(1) != nil {
1463 t.Fatal("stream 1 should be empty")
1465 if got := st.streamState(1); got != stateIdle {
1466 t.Fatalf("stream 1 should be idle; got %v", got)
1469 st.writeHeaders(HeadersFrameParam{
1471 BlockFragment: st.encodeHeader(":method", "POST"),
1472 EndStream: false, // keep it open
1477 st.writeData(1, true, nil)
1479 leaveHandler <- true
1480 hf := st.wantHeaders()
1481 if !hf.StreamEnded() {
1482 t.Fatal("expected END_STREAM flag")
1485 if got, want := st.streamState(1), stateClosed; got != want {
1486 t.Errorf("at end, state is %v; want %v", got, want)
1488 if st.stream(1) != nil {
1489 t.Fatal("at end, stream 1 should be gone")
1493 // test HEADERS w/o EndHeaders + another HEADERS (should get rejected)
1494 func TestServer_Rejects_HeadersNoEnd_Then_Headers(t *testing.T) {
1495 testServerRejectsConn(t, func(st *serverTester) {
1496 st.writeHeaders(HeadersFrameParam{
1498 BlockFragment: st.encodeHeader(),
1502 st.writeHeaders(HeadersFrameParam{ // Not a continuation.
1503 StreamID: 3, // different stream.
1504 BlockFragment: st.encodeHeader(),
1511 // test HEADERS w/o EndHeaders + PING (should get rejected)
1512 func TestServer_Rejects_HeadersNoEnd_Then_Ping(t *testing.T) {
1513 testServerRejectsConn(t, func(st *serverTester) {
1514 st.writeHeaders(HeadersFrameParam{
1516 BlockFragment: st.encodeHeader(),
1520 if err := st.fr.WritePing(false, [8]byte{}); err != nil {
1526 // test HEADERS w/ EndHeaders + a continuation HEADERS (should get rejected)
1527 func TestServer_Rejects_HeadersEnd_Then_Continuation(t *testing.T) {
1528 testServerRejectsConn(t, func(st *serverTester) {
1529 st.writeHeaders(HeadersFrameParam{
1531 BlockFragment: st.encodeHeader(),
1536 if err := st.fr.WriteContinuation(1, true, encodeHeaderNoImplicit(t, "foo", "bar")); err != nil {
1542 // test HEADERS w/o EndHeaders + a continuation HEADERS on wrong stream ID
1543 func TestServer_Rejects_HeadersNoEnd_Then_ContinuationWrongStream(t *testing.T) {
1544 testServerRejectsConn(t, func(st *serverTester) {
1545 st.writeHeaders(HeadersFrameParam{
1547 BlockFragment: st.encodeHeader(),
1551 if err := st.fr.WriteContinuation(3, true, encodeHeaderNoImplicit(t, "foo", "bar")); err != nil {
1557 // No HEADERS on stream 0.
1558 func TestServer_Rejects_Headers0(t *testing.T) {
1559 testServerRejectsConn(t, func(st *serverTester) {
1560 st.fr.AllowIllegalWrites = true
1561 st.writeHeaders(HeadersFrameParam{
1563 BlockFragment: st.encodeHeader(),
1570 // No CONTINUATION on stream 0.
1571 func TestServer_Rejects_Continuation0(t *testing.T) {
1572 testServerRejectsConn(t, func(st *serverTester) {
1573 st.fr.AllowIllegalWrites = true
1574 if err := st.fr.WriteContinuation(0, true, st.encodeHeader()); err != nil {
1580 // No PRIORITY on stream 0.
1581 func TestServer_Rejects_Priority0(t *testing.T) {
1582 testServerRejectsConn(t, func(st *serverTester) {
1583 st.fr.AllowIllegalWrites = true
1584 st.writePriority(0, PriorityParam{StreamDep: 1})
1588 // No HEADERS frame with a self-dependence.
1589 func TestServer_Rejects_HeadersSelfDependence(t *testing.T) {
1590 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
1591 st.fr.AllowIllegalWrites = true
1592 st.writeHeaders(HeadersFrameParam{
1594 BlockFragment: st.encodeHeader(),
1597 Priority: PriorityParam{StreamDep: 1},
1602 // No PRIORTY frame with a self-dependence.
1603 func TestServer_Rejects_PrioritySelfDependence(t *testing.T) {
1604 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
1605 st.fr.AllowIllegalWrites = true
1606 st.writePriority(1, PriorityParam{StreamDep: 1})
1610 func TestServer_Rejects_PushPromise(t *testing.T) {
1611 testServerRejectsConn(t, func(st *serverTester) {
1612 pp := PushPromiseParam{
1616 if err := st.fr.WritePushPromise(pp); err != nil {
1622 // testServerRejectsConn tests that the server hangs up with a GOAWAY
1623 // frame and a server close after the client does something
1624 // deserving a CONNECTION_ERROR.
1625 func testServerRejectsConn(t *testing.T, writeReq func(*serverTester)) {
1626 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {})
1627 st.addLogFilter("connection error: PROTOCOL_ERROR")
1633 errc := make(chan error, 1)
1635 fr, err := st.fr.ReadFrame()
1637 err = fmt.Errorf("got frame of type %T", fr)
1644 t.Errorf("ReadFrame = %v; want io.EOF", err)
1646 case <-time.After(2 * time.Second):
1647 t.Error("timeout waiting for disconnect")
1651 // testServerRejectsStream tests that the server sends a RST_STREAM with the provided
1652 // error code after a client sends a bogus request.
1653 func testServerRejectsStream(t *testing.T, code ErrCode, writeReq func(*serverTester)) {
1654 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {})
1658 st.wantRSTStream(1, code)
1661 // testServerRequest sets up an idle HTTP/2 connection and lets you
1662 // write a single request with writeReq, and then verify that the
1663 // *http.Request is built correctly in checkReq.
1664 func testServerRequest(t *testing.T, writeReq func(*serverTester), checkReq func(*http.Request)) {
1665 gotReq := make(chan bool, 1)
1666 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1680 case <-time.After(2 * time.Second):
1681 t.Error("timeout waiting for request")
1685 func getSlash(st *serverTester) { st.bodylessReq1() }
1687 func TestServer_Response_NoData(t *testing.T) {
1688 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1691 }, func(st *serverTester) {
1693 hf := st.wantHeaders()
1694 if !hf.StreamEnded() {
1695 t.Fatal("want END_STREAM flag")
1697 if !hf.HeadersEnded() {
1698 t.Fatal("want END_HEADERS flag")
1703 func TestServer_Response_NoData_Header_FooBar(t *testing.T) {
1704 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1705 w.Header().Set("Foo-Bar", "some-value")
1707 }, func(st *serverTester) {
1709 hf := st.wantHeaders()
1710 if !hf.StreamEnded() {
1711 t.Fatal("want END_STREAM flag")
1713 if !hf.HeadersEnded() {
1714 t.Fatal("want END_HEADERS flag")
1716 goth := st.decodeHeader(hf.HeaderBlockFragment())
1717 wanth := [][2]string{
1719 {"foo-bar", "some-value"},
1720 {"content-type", "text/plain; charset=utf-8"},
1721 {"content-length", "0"},
1723 if !reflect.DeepEqual(goth, wanth) {
1724 t.Errorf("Got headers %v; want %v", goth, wanth)
1729 func TestServer_Response_Data_Sniff_DoesntOverride(t *testing.T) {
1730 const msg = "<html>this is HTML."
1731 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1732 w.Header().Set("Content-Type", "foo/bar")
1733 io.WriteString(w, msg)
1735 }, func(st *serverTester) {
1737 hf := st.wantHeaders()
1738 if hf.StreamEnded() {
1739 t.Fatal("don't want END_STREAM, expecting data")
1741 if !hf.HeadersEnded() {
1742 t.Fatal("want END_HEADERS flag")
1744 goth := st.decodeHeader(hf.HeaderBlockFragment())
1745 wanth := [][2]string{
1747 {"content-type", "foo/bar"},
1748 {"content-length", strconv.Itoa(len(msg))},
1750 if !reflect.DeepEqual(goth, wanth) {
1751 t.Errorf("Got headers %v; want %v", goth, wanth)
1754 if !df.StreamEnded() {
1755 t.Error("expected DATA to have END_STREAM flag")
1757 if got := string(df.Data()); got != msg {
1758 t.Errorf("got DATA %q; want %q", got, msg)
1763 func TestServer_Response_TransferEncoding_chunked(t *testing.T) {
1765 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1766 w.Header().Set("Transfer-Encoding", "chunked") // should be stripped
1767 io.WriteString(w, msg)
1769 }, func(st *serverTester) {
1771 hf := st.wantHeaders()
1772 goth := st.decodeHeader(hf.HeaderBlockFragment())
1773 wanth := [][2]string{
1775 {"content-type", "text/plain; charset=utf-8"},
1776 {"content-length", strconv.Itoa(len(msg))},
1778 if !reflect.DeepEqual(goth, wanth) {
1779 t.Errorf("Got headers %v; want %v", goth, wanth)
1784 // Header accessed only after the initial write.
1785 func TestServer_Response_Data_IgnoreHeaderAfterWrite_After(t *testing.T) {
1786 const msg = "<html>this is HTML."
1787 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1788 io.WriteString(w, msg)
1789 w.Header().Set("foo", "should be ignored")
1791 }, func(st *serverTester) {
1793 hf := st.wantHeaders()
1794 if hf.StreamEnded() {
1795 t.Fatal("unexpected END_STREAM")
1797 if !hf.HeadersEnded() {
1798 t.Fatal("want END_HEADERS flag")
1800 goth := st.decodeHeader(hf.HeaderBlockFragment())
1801 wanth := [][2]string{
1803 {"content-type", "text/html; charset=utf-8"},
1804 {"content-length", strconv.Itoa(len(msg))},
1806 if !reflect.DeepEqual(goth, wanth) {
1807 t.Errorf("Got headers %v; want %v", goth, wanth)
1812 // Header accessed before the initial write and later mutated.
1813 func TestServer_Response_Data_IgnoreHeaderAfterWrite_Overwrite(t *testing.T) {
1814 const msg = "<html>this is HTML."
1815 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1816 w.Header().Set("foo", "proper value")
1817 io.WriteString(w, msg)
1818 w.Header().Set("foo", "should be ignored")
1820 }, func(st *serverTester) {
1822 hf := st.wantHeaders()
1823 if hf.StreamEnded() {
1824 t.Fatal("unexpected END_STREAM")
1826 if !hf.HeadersEnded() {
1827 t.Fatal("want END_HEADERS flag")
1829 goth := st.decodeHeader(hf.HeaderBlockFragment())
1830 wanth := [][2]string{
1832 {"foo", "proper value"},
1833 {"content-type", "text/html; charset=utf-8"},
1834 {"content-length", strconv.Itoa(len(msg))},
1836 if !reflect.DeepEqual(goth, wanth) {
1837 t.Errorf("Got headers %v; want %v", goth, wanth)
1842 func TestServer_Response_Data_SniffLenType(t *testing.T) {
1843 const msg = "<html>this is HTML."
1844 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1845 io.WriteString(w, msg)
1847 }, func(st *serverTester) {
1849 hf := st.wantHeaders()
1850 if hf.StreamEnded() {
1851 t.Fatal("don't want END_STREAM, expecting data")
1853 if !hf.HeadersEnded() {
1854 t.Fatal("want END_HEADERS flag")
1856 goth := st.decodeHeader(hf.HeaderBlockFragment())
1857 wanth := [][2]string{
1859 {"content-type", "text/html; charset=utf-8"},
1860 {"content-length", strconv.Itoa(len(msg))},
1862 if !reflect.DeepEqual(goth, wanth) {
1863 t.Errorf("Got headers %v; want %v", goth, wanth)
1866 if !df.StreamEnded() {
1867 t.Error("expected DATA to have END_STREAM flag")
1869 if got := string(df.Data()); got != msg {
1870 t.Errorf("got DATA %q; want %q", got, msg)
1875 func TestServer_Response_Header_Flush_MidWrite(t *testing.T) {
1876 const msg = "<html>this is HTML"
1877 const msg2 = ", and this is the next chunk"
1878 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1879 io.WriteString(w, msg)
1880 w.(http.Flusher).Flush()
1881 io.WriteString(w, msg2)
1883 }, func(st *serverTester) {
1885 hf := st.wantHeaders()
1886 if hf.StreamEnded() {
1887 t.Fatal("unexpected END_STREAM flag")
1889 if !hf.HeadersEnded() {
1890 t.Fatal("want END_HEADERS flag")
1892 goth := st.decodeHeader(hf.HeaderBlockFragment())
1893 wanth := [][2]string{
1895 {"content-type", "text/html; charset=utf-8"}, // sniffed
1896 // and no content-length
1898 if !reflect.DeepEqual(goth, wanth) {
1899 t.Errorf("Got headers %v; want %v", goth, wanth)
1903 if df.StreamEnded() {
1904 t.Error("unexpected END_STREAM flag")
1906 if got := string(df.Data()); got != msg {
1907 t.Errorf("got DATA %q; want %q", got, msg)
1912 if !df.StreamEnded() {
1913 t.Error("wanted END_STREAM flag on last data chunk")
1915 if got := string(df.Data()); got != msg2 {
1916 t.Errorf("got DATA %q; want %q", got, msg2)
1922 func TestServer_Response_LargeWrite(t *testing.T) {
1923 const size = 1 << 20
1924 const maxFrameSize = 16 << 10
1925 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1926 n, err := w.Write(bytes.Repeat([]byte("a"), size))
1928 return fmt.Errorf("Write error: %v", err)
1931 return fmt.Errorf("wrong size %d from Write", n)
1934 }, func(st *serverTester) {
1935 if err := st.fr.WriteSettings(
1936 Setting{SettingInitialWindowSize, 0},
1937 Setting{SettingMaxFrameSize, maxFrameSize},
1941 st.wantSettingsAck()
1943 getSlash(st) // make the single request
1945 // Give the handler quota to write:
1946 if err := st.fr.WriteWindowUpdate(1, size); err != nil {
1949 // Give the handler quota to write to connection-level
1951 if err := st.fr.WriteWindowUpdate(0, size); err != nil {
1954 hf := st.wantHeaders()
1955 if hf.StreamEnded() {
1956 t.Fatal("unexpected END_STREAM flag")
1958 if !hf.HeadersEnded() {
1959 t.Fatal("want END_HEADERS flag")
1961 goth := st.decodeHeader(hf.HeaderBlockFragment())
1962 wanth := [][2]string{
1964 {"content-type", "text/plain; charset=utf-8"}, // sniffed
1965 // and no content-length
1967 if !reflect.DeepEqual(goth, wanth) {
1968 t.Errorf("Got headers %v; want %v", goth, wanth)
1970 var bytes, frames int
1973 bytes += len(df.Data())
1975 for _, b := range df.Data() {
1977 t.Fatal("non-'a' byte seen in DATA")
1980 if df.StreamEnded() {
1985 t.Errorf("Got %d bytes; want %d", bytes, size)
1987 if want := int(size / maxFrameSize); frames < want || frames > want*2 {
1988 t.Errorf("Got %d frames; want %d", frames, size)
1993 // Test that the handler can't write more than the client allows
1994 func TestServer_Response_LargeWrite_FlowControlled(t *testing.T) {
1995 // Make these reads. Before each read, the client adds exactly enough
1996 // flow-control to satisfy the read. Numbers chosen arbitrarily.
1997 reads := []int{123, 1, 13, 127}
1999 for _, n := range reads {
2003 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2004 w.(http.Flusher).Flush()
2005 n, err := w.Write(bytes.Repeat([]byte("a"), size))
2007 return fmt.Errorf("Write error: %v", err)
2010 return fmt.Errorf("wrong size %d from Write", n)
2013 }, func(st *serverTester) {
2014 // Set the window size to something explicit for this test.
2015 // It's also how much initial data we expect.
2016 if err := st.fr.WriteSettings(Setting{SettingInitialWindowSize, uint32(reads[0])}); err != nil {
2019 st.wantSettingsAck()
2021 getSlash(st) // make the single request
2023 hf := st.wantHeaders()
2024 if hf.StreamEnded() {
2025 t.Fatal("unexpected END_STREAM flag")
2027 if !hf.HeadersEnded() {
2028 t.Fatal("want END_HEADERS flag")
2032 if got := len(df.Data()); got != reads[0] {
2033 t.Fatalf("Initial window size = %d but got DATA with %d bytes", reads[0], got)
2036 for _, quota := range reads[1:] {
2037 if err := st.fr.WriteWindowUpdate(1, uint32(quota)); err != nil {
2041 if int(quota) != len(df.Data()) {
2042 t.Fatalf("read %d bytes after giving %d quota", len(df.Data()), quota)
2048 // Test that the handler blocked in a Write is unblocked if the server sends a RST_STREAM.
2049 func TestServer_Response_RST_Unblocks_LargeWrite(t *testing.T) {
2050 const size = 1 << 20
2051 const maxFrameSize = 16 << 10
2052 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2053 w.(http.Flusher).Flush()
2054 errc := make(chan error, 1)
2056 _, err := w.Write(bytes.Repeat([]byte("a"), size))
2062 return errors.New("unexpected nil error from Write in handler")
2065 case <-time.After(2 * time.Second):
2066 return errors.New("timeout waiting for Write in handler")
2068 }, func(st *serverTester) {
2069 if err := st.fr.WriteSettings(
2070 Setting{SettingInitialWindowSize, 0},
2071 Setting{SettingMaxFrameSize, maxFrameSize},
2075 st.wantSettingsAck()
2077 getSlash(st) // make the single request
2079 hf := st.wantHeaders()
2080 if hf.StreamEnded() {
2081 t.Fatal("unexpected END_STREAM flag")
2083 if !hf.HeadersEnded() {
2084 t.Fatal("want END_HEADERS flag")
2087 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
2093 func TestServer_Response_Empty_Data_Not_FlowControlled(t *testing.T) {
2094 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2095 w.(http.Flusher).Flush()
2096 // Nothing; send empty DATA
2098 }, func(st *serverTester) {
2099 // Handler gets no data quota:
2100 if err := st.fr.WriteSettings(Setting{SettingInitialWindowSize, 0}); err != nil {
2103 st.wantSettingsAck()
2105 getSlash(st) // make the single request
2107 hf := st.wantHeaders()
2108 if hf.StreamEnded() {
2109 t.Fatal("unexpected END_STREAM flag")
2111 if !hf.HeadersEnded() {
2112 t.Fatal("want END_HEADERS flag")
2116 if got := len(df.Data()); got != 0 {
2117 t.Fatalf("unexpected %d DATA bytes; want 0", got)
2119 if !df.StreamEnded() {
2120 t.Fatal("DATA didn't have END_STREAM")
2125 func TestServer_Response_Automatic100Continue(t *testing.T) {
2128 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2129 if v := r.Header.Get("Expect"); v != "" {
2130 t.Errorf("Expect header = %q; want empty", v)
2132 buf := make([]byte, len(msg))
2133 // This read should trigger the 100-continue being sent.
2134 if n, err := io.ReadFull(r.Body, buf); err != nil || n != len(msg) || string(buf) != msg {
2135 return fmt.Errorf("ReadFull = %q, %v; want %q, nil", buf[:n], err, msg)
2137 _, err := io.WriteString(w, reply)
2139 }, func(st *serverTester) {
2140 st.writeHeaders(HeadersFrameParam{
2141 StreamID: 1, // clients send odd numbers
2142 BlockFragment: st.encodeHeader(":method", "POST", "expect", "100-continue"),
2146 hf := st.wantHeaders()
2147 if hf.StreamEnded() {
2148 t.Fatal("unexpected END_STREAM flag")
2150 if !hf.HeadersEnded() {
2151 t.Fatal("want END_HEADERS flag")
2153 goth := st.decodeHeader(hf.HeaderBlockFragment())
2154 wanth := [][2]string{
2157 if !reflect.DeepEqual(goth, wanth) {
2158 t.Fatalf("Got headers %v; want %v", goth, wanth)
2161 // Okay, they sent status 100, so we can send our
2162 // gigantic and/or sensitive "foo" payload now.
2163 st.writeData(1, true, []byte(msg))
2165 st.wantWindowUpdate(0, uint32(len(msg)))
2167 hf = st.wantHeaders()
2168 if hf.StreamEnded() {
2169 t.Fatal("expected data to follow")
2171 if !hf.HeadersEnded() {
2172 t.Fatal("want END_HEADERS flag")
2174 goth = st.decodeHeader(hf.HeaderBlockFragment())
2175 wanth = [][2]string{
2177 {"content-type", "text/plain; charset=utf-8"},
2178 {"content-length", strconv.Itoa(len(reply))},
2180 if !reflect.DeepEqual(goth, wanth) {
2181 t.Errorf("Got headers %v; want %v", goth, wanth)
2185 if string(df.Data()) != reply {
2186 t.Errorf("Client read %q; want %q", df.Data(), reply)
2188 if !df.StreamEnded() {
2189 t.Errorf("expect data stream end")
2194 func TestServer_HandlerWriteErrorOnDisconnect(t *testing.T) {
2195 errc := make(chan error, 1)
2196 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2197 p := []byte("some data.\n")
2199 _, err := w.Write(p)
2205 }, func(st *serverTester) {
2206 st.writeHeaders(HeadersFrameParam{
2208 BlockFragment: st.encodeHeader(),
2212 hf := st.wantHeaders()
2213 if hf.StreamEnded() {
2214 t.Fatal("unexpected END_STREAM flag")
2216 if !hf.HeadersEnded() {
2217 t.Fatal("want END_HEADERS flag")
2219 // Close the connection and wait for the handler to (hopefully) notice.
2223 case <-time.After(5 * time.Second):
2229 func TestServer_Rejects_Too_Many_Streams(t *testing.T) {
2230 const testPath = "/some/path"
2232 inHandler := make(chan uint32)
2233 leaveHandler := make(chan bool)
2234 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
2235 id := w.(*responseWriter).rws.stream.id
2237 if id == 1+(defaultMaxStreams+1)*2 && r.URL.Path != testPath {
2238 t.Errorf("decoded final path as %q; want %q", r.URL.Path, testPath)
2244 nextStreamID := uint32(1)
2245 streamID := func() uint32 {
2246 defer func() { nextStreamID += 2 }()
2249 sendReq := func(id uint32, headers ...string) {
2250 st.writeHeaders(HeadersFrameParam{
2252 BlockFragment: st.encodeHeader(headers...),
2257 for i := 0; i < defaultMaxStreams; i++ {
2262 for i := 0; i < defaultMaxStreams; i++ {
2263 leaveHandler <- true
2267 // And this one should cross the limit:
2268 // (It's also sent as a CONTINUATION, to verify we still track the decoder context,
2269 // even if we're rejecting it)
2270 rejectID := streamID()
2271 headerBlock := st.encodeHeader(":path", testPath)
2272 frag1, frag2 := headerBlock[:3], headerBlock[3:]
2273 st.writeHeaders(HeadersFrameParam{
2275 BlockFragment: frag1,
2277 EndHeaders: false, // CONTINUATION coming
2279 if err := st.fr.WriteContinuation(rejectID, true, frag2); err != nil {
2282 st.wantRSTStream(rejectID, ErrCodeProtocol)
2284 // But let a handler finish:
2285 leaveHandler <- true
2288 // And now another stream should be able to start:
2289 goodID := streamID()
2290 sendReq(goodID, ":path", testPath)
2292 case got := <-inHandler:
2294 t.Errorf("Got stream %d; want %d", got, goodID)
2296 case <-time.After(3 * time.Second):
2297 t.Error("timeout waiting for handler")
2301 // So many response headers that the server needs to use CONTINUATION frames:
2302 func TestServer_Response_ManyHeaders_With_Continuation(t *testing.T) {
2303 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2305 for i := 0; i < 5000; i++ {
2306 h.Set(fmt.Sprintf("x-header-%d", i), fmt.Sprintf("x-value-%d", i))
2309 }, func(st *serverTester) {
2311 hf := st.wantHeaders()
2312 if hf.HeadersEnded() {
2313 t.Fatal("got unwanted END_HEADERS flag")
2318 cf := st.wantContinuation()
2319 if cf.HeadersEnded() {
2324 t.Errorf("Only got %d CONTINUATION frames; expected 5+ (currently 6)", n)
2329 // This previously crashed (reported by Mathieu Lonjaret as observed
2330 // while using Camlistore) because we got a DATA frame from the client
2331 // after the handler exited and our logic at the time was wrong,
2332 // keeping a stream in the map in stateClosed, which tickled an
2333 // invariant check later when we tried to remove that stream (via
2334 // defer sc.closeAllStreamsOnConnClose) when the serverConn serve loop
2336 func TestServer_NoCrash_HandlerClose_Then_ClientClose(t *testing.T) {
2337 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2340 }, func(st *serverTester) {
2341 st.writeHeaders(HeadersFrameParam{
2343 BlockFragment: st.encodeHeader(),
2344 EndStream: false, // DATA is coming
2347 hf := st.wantHeaders()
2348 if !hf.HeadersEnded() || !hf.StreamEnded() {
2349 t.Fatalf("want END_HEADERS+END_STREAM, got %v", hf)
2352 // Sent when the a Handler closes while a client has
2353 // indicated it's still sending DATA:
2354 st.wantRSTStream(1, ErrCodeNo)
2356 // Now the handler has ended, so it's ended its
2357 // stream, but the client hasn't closed its side
2358 // (stateClosedLocal). So send more data and verify
2359 // it doesn't crash with an internal invariant panic, like
2361 st.writeData(1, true, []byte("foo"))
2363 // Get our flow control bytes back, since the handler didn't get them.
2364 st.wantWindowUpdate(0, uint32(len("foo")))
2366 // Sent after a peer sends data anyway (admittedly the
2367 // previous RST_STREAM might've still been in-flight),
2368 // but they'll get the more friendly 'cancel' code
2370 st.wantRSTStream(1, ErrCodeStreamClosed)
2372 // Set up a bunch of machinery to record the panic we saw
2376 panicVal interface{}
2379 testHookOnPanicMu.Lock()
2380 testHookOnPanic = func(sc *serverConn, pv interface{}) bool {
2386 testHookOnPanicMu.Unlock()
2388 // Now force the serve loop to end, via closing the connection.
2391 case <-st.sc.doneServing:
2397 t.Errorf("Got panic: %v", got)
2399 case <-time.After(5 * time.Second):
2405 func TestServer_Rejects_TLS10(t *testing.T) { testRejectTLS(t, tls.VersionTLS10) }
2406 func TestServer_Rejects_TLS11(t *testing.T) { testRejectTLS(t, tls.VersionTLS11) }
2408 func testRejectTLS(t *testing.T, max uint16) {
2409 st := newServerTester(t, nil, func(c *tls.Config) {
2413 gf := st.wantGoAway()
2414 if got, want := gf.ErrCode, ErrCodeInadequateSecurity; got != want {
2415 t.Errorf("Got error code %v; want %v", got, want)
2419 func TestServer_Rejects_TLSBadCipher(t *testing.T) {
2420 st := newServerTester(t, nil, func(c *tls.Config) {
2421 // Only list bad ones:
2422 c.CipherSuites = []uint16{
2423 tls.TLS_RSA_WITH_RC4_128_SHA,
2424 tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
2425 tls.TLS_RSA_WITH_AES_128_CBC_SHA,
2426 tls.TLS_RSA_WITH_AES_256_CBC_SHA,
2427 tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
2428 tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
2429 tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
2430 tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
2431 tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
2432 tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
2433 tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
2434 cipher_TLS_RSA_WITH_AES_128_CBC_SHA256,
2438 gf := st.wantGoAway()
2439 if got, want := gf.ErrCode, ErrCodeInadequateSecurity; got != want {
2440 t.Errorf("Got error code %v; want %v", got, want)
2444 func TestServer_Advertises_Common_Cipher(t *testing.T) {
2445 const requiredSuite = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
2446 st := newServerTester(t, nil, func(c *tls.Config) {
2447 // Have the client only support the one required by the spec.
2448 c.CipherSuites = []uint16{requiredSuite}
2449 }, func(ts *httptest.Server) {
2450 var srv *http.Server = ts.Config
2451 // Have the server configured with no specific cipher suites.
2452 // This tests that Go's defaults include the required one.
2459 func (st *serverTester) onHeaderField(f hpack.HeaderField) {
2460 if f.Name == "date" {
2463 st.decodedHeaders = append(st.decodedHeaders, [2]string{f.Name, f.Value})
2466 func (st *serverTester) decodeHeader(headerBlock []byte) (pairs [][2]string) {
2467 st.decodedHeaders = nil
2468 if _, err := st.hpackDec.Write(headerBlock); err != nil {
2469 st.t.Fatalf("hpack decoding error: %v", err)
2471 if err := st.hpackDec.Close(); err != nil {
2472 st.t.Fatalf("hpack decoding error: %v", err)
2474 return st.decodedHeaders
2477 // testServerResponse sets up an idle HTTP/2 connection. The client function should
2478 // write a single request that must be handled by the handler. This waits up to 5s
2479 // for client to return, then up to an additional 2s for the handler to return.
2480 func testServerResponse(t testing.TB,
2481 handler func(http.ResponseWriter, *http.Request) error,
2482 client func(*serverTester),
2484 errc := make(chan error, 1)
2485 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
2489 errc <- handler(w, r)
2493 donec := make(chan bool)
2502 case <-time.After(5 * time.Second):
2503 t.Fatal("timeout in client")
2509 t.Fatalf("Error in handler: %v", err)
2511 case <-time.After(2 * time.Second):
2512 t.Fatal("timeout in handler")
2516 // readBodyHandler returns an http Handler func that reads len(want)
2517 // bytes from r.Body and fails t if the contents read were not
2518 // the value of want.
2519 func readBodyHandler(t *testing.T, want string) func(w http.ResponseWriter, r *http.Request) {
2520 return func(w http.ResponseWriter, r *http.Request) {
2521 buf := make([]byte, len(want))
2522 _, err := io.ReadFull(r.Body, buf)
2527 if string(buf) != want {
2528 t.Errorf("read %q; want %q", buf, want)
2533 // TestServerWithCurl currently fails, hence the LenientCipherSuites test. See:
2534 // https://github.com/tatsuhiro-t/nghttp2/issues/140 &
2535 // http://sourceforge.net/p/curl/bugs/1472/
2536 func TestServerWithCurl(t *testing.T) { testServerWithCurl(t, false) }
2537 func TestServerWithCurl_LenientCipherSuites(t *testing.T) { testServerWithCurl(t, true) }
2539 func testServerWithCurl(t *testing.T, permitProhibitedCipherSuites bool) {
2540 if runtime.GOOS != "linux" {
2541 t.Skip("skipping Docker test when not on Linux; requires --net which won't work with boot2docker anyway")
2543 if testing.Short() {
2544 t.Skip("skipping curl test in short mode")
2548 testHookOnConn = func() { atomic.StoreInt32(&gotConn, 1) }
2550 const msg = "Hello from curl!\n"
2551 ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2552 w.Header().Set("Foo", "Bar")
2553 w.Header().Set("Client-Proto", r.Proto)
2554 io.WriteString(w, msg)
2556 ConfigureServer(ts.Config, &Server{
2557 PermitProhibitedCipherSuites: permitProhibitedCipherSuites,
2559 ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config
2563 t.Logf("Running test server for curl to hit at: %s", ts.URL)
2564 container := curl(t, "--silent", "--http2", "--insecure", "-v", ts.URL)
2565 defer kill(container)
2566 resc := make(chan interface{}, 1)
2568 res, err := dockerLogs(container)
2577 if err, ok := res.(error); ok {
2580 body := string(res.([]byte))
2581 // Search for both "key: value" and "key:value", since curl changed their format
2582 // Our Dockerfile contains the latest version (no space), but just in case people
2583 // didn't rebuild, check both.
2584 if !strings.Contains(body, "foo: Bar") && !strings.Contains(body, "foo:Bar") {
2585 t.Errorf("didn't see foo: Bar header")
2586 t.Logf("Got: %s", body)
2588 if !strings.Contains(body, "client-proto: HTTP/2") && !strings.Contains(body, "client-proto:HTTP/2") {
2589 t.Errorf("didn't see client-proto: HTTP/2 header")
2590 t.Logf("Got: %s", res)
2592 if !strings.Contains(string(res.([]byte)), msg) {
2593 t.Errorf("didn't see %q content", msg)
2594 t.Logf("Got: %s", res)
2596 case <-time.After(3 * time.Second):
2597 t.Errorf("timeout waiting for curl")
2600 if atomic.LoadInt32(&gotConn) == 0 {
2601 t.Error("never saw an http2 connection")
2605 var doh2load = flag.Bool("h2load", false, "Run h2load test")
2607 func TestServerWithH2Load(t *testing.T) {
2609 t.Skip("Skipping without --h2load flag.")
2611 if runtime.GOOS != "linux" {
2612 t.Skip("skipping Docker test when not on Linux; requires --net which won't work with boot2docker anyway")
2616 msg := strings.Repeat("Hello, h2load!\n", 5000)
2617 ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2618 io.WriteString(w, msg)
2619 w.(http.Flusher).Flush()
2620 io.WriteString(w, msg)
2625 cmd := exec.Command("docker", "run", "--net=host", "--entrypoint=/usr/local/bin/h2load", "gohttp2/curl",
2626 "-n100000", "-c100", "-m100", ts.URL)
2627 cmd.Stdout = os.Stdout
2628 cmd.Stderr = os.Stderr
2629 if err := cmd.Run(); err != nil {
2635 func TestServerDoS_MaxHeaderListSize(t *testing.T) {
2636 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {})
2640 frameSize := defaultMaxReadFrameSize
2641 var advHeaderListSize *uint32
2642 st.greetAndCheckSettings(func(s Setting) error {
2644 case SettingMaxFrameSize:
2645 if s.Val < minMaxFrameSize {
2646 frameSize = minMaxFrameSize
2647 } else if s.Val > maxFrameSize {
2648 frameSize = maxFrameSize
2650 frameSize = int(s.Val)
2652 case SettingMaxHeaderListSize:
2653 advHeaderListSize = &s.Val
2658 if advHeaderListSize == nil {
2659 t.Errorf("server didn't advertise a max header list size")
2660 } else if *advHeaderListSize == 0 {
2661 t.Errorf("server advertised a max header list size of 0")
2664 st.encodeHeaderField(":method", "GET")
2665 st.encodeHeaderField(":path", "/")
2666 st.encodeHeaderField(":scheme", "https")
2667 cookie := strings.Repeat("*", 4058)
2668 st.encodeHeaderField("cookie", cookie)
2669 st.writeHeaders(HeadersFrameParam{
2671 BlockFragment: st.headerBuf.Bytes(),
2676 // Capture the short encoding of a duplicate ~4K cookie, now
2677 // that we've already sent it once.
2678 st.headerBuf.Reset()
2679 st.encodeHeaderField("cookie", cookie)
2681 // Now send 1MB of it.
2682 const size = 1 << 20
2683 b := bytes.Repeat(st.headerBuf.Bytes(), size/st.headerBuf.Len())
2686 if len(chunk) > frameSize {
2687 chunk = chunk[:frameSize]
2690 st.fr.WriteContinuation(1, len(b) == 0, chunk)
2693 h := st.wantHeaders()
2694 if !h.HeadersEnded() {
2695 t.Fatalf("Got HEADERS without END_HEADERS set: %v", h)
2697 headers := st.decodeHeader(h.HeaderBlockFragment())
2698 want := [][2]string{
2700 {"content-type", "text/html; charset=utf-8"},
2701 {"content-length", "63"},
2703 if !reflect.DeepEqual(headers, want) {
2704 t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
2708 func TestCompressionErrorOnWrite(t *testing.T) {
2709 const maxStrLen = 8 << 10
2710 var serverConfig *http.Server
2711 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
2712 // No response body.
2713 }, func(ts *httptest.Server) {
2714 serverConfig = ts.Config
2715 serverConfig.MaxHeaderBytes = maxStrLen
2717 st.addLogFilter("connection error: COMPRESSION_ERROR")
2721 maxAllowed := st.sc.framer.maxHeaderStringLen()
2723 // Crank this up, now that we have a conn connected with the
2724 // hpack.Decoder's max string length set has been initialized
2725 // from the earlier low ~8K value. We want this higher so don't
2726 // hit the max header list size. We only want to test hitting
2727 // the max string size.
2728 serverConfig.MaxHeaderBytes = 1 << 20
2730 // First a request with a header that's exactly the max allowed size
2731 // for the hpack compression. It's still too long for the header list
2732 // size, so we'll get the 431 error, but that keeps the compression
2733 // context still valid.
2734 hbf := st.encodeHeader("foo", strings.Repeat("a", maxAllowed))
2736 st.writeHeaders(HeadersFrameParam{
2742 h := st.wantHeaders()
2743 if !h.HeadersEnded() {
2744 t.Fatalf("Got HEADERS without END_HEADERS set: %v", h)
2746 headers := st.decodeHeader(h.HeaderBlockFragment())
2747 want := [][2]string{
2749 {"content-type", "text/html; charset=utf-8"},
2750 {"content-length", "63"},
2752 if !reflect.DeepEqual(headers, want) {
2753 t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
2756 if !strings.Contains(string(df.Data()), "HTTP Error 431") {
2757 t.Errorf("Unexpected data body: %q", df.Data())
2759 if !df.StreamEnded() {
2760 t.Fatalf("expect data stream end")
2763 // And now send one that's just one byte too big.
2764 hbf = st.encodeHeader("bar", strings.Repeat("b", maxAllowed+1))
2765 st.writeHeaders(HeadersFrameParam{
2771 ga := st.wantGoAway()
2772 if ga.ErrCode != ErrCodeCompression {
2773 t.Errorf("GOAWAY err = %v; want ErrCodeCompression", ga.ErrCode)
2777 func TestCompressionErrorOnClose(t *testing.T) {
2778 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
2779 // No response body.
2781 st.addLogFilter("connection error: COMPRESSION_ERROR")
2785 hbf := st.encodeHeader("foo", "bar")
2786 hbf = hbf[:len(hbf)-1] // truncate one byte from the end, so hpack.Decoder.Close fails.
2787 st.writeHeaders(HeadersFrameParam{
2793 ga := st.wantGoAway()
2794 if ga.ErrCode != ErrCodeCompression {
2795 t.Errorf("GOAWAY err = %v; want ErrCodeCompression", ga.ErrCode)
2799 // test that a server handler can read trailers from a client
2800 func TestServerReadsTrailers(t *testing.T) {
2801 const testBody = "some test body"
2802 writeReq := func(st *serverTester) {
2803 st.writeHeaders(HeadersFrameParam{
2804 StreamID: 1, // clients send odd numbers
2805 BlockFragment: st.encodeHeader("trailer", "Foo, Bar", "trailer", "Baz"),
2809 st.writeData(1, false, []byte(testBody))
2810 st.writeHeaders(HeadersFrameParam{
2811 StreamID: 1, // clients send odd numbers
2812 BlockFragment: st.encodeHeaderRaw(
2816 "surprise", "wasn't declared; shouldn't show up",
2822 checkReq := func(r *http.Request) {
2823 wantTrailer := http.Header{
2828 if !reflect.DeepEqual(r.Trailer, wantTrailer) {
2829 t.Errorf("initial Trailer = %v; want %v", r.Trailer, wantTrailer)
2831 slurp, err := ioutil.ReadAll(r.Body)
2832 if string(slurp) != testBody {
2833 t.Errorf("read body %q; want %q", slurp, testBody)
2836 t.Fatalf("Body slurp: %v", err)
2838 wantTrailerAfter := http.Header{
2843 if !reflect.DeepEqual(r.Trailer, wantTrailerAfter) {
2844 t.Errorf("final Trailer = %v; want %v", r.Trailer, wantTrailerAfter)
2847 testServerRequest(t, writeReq, checkReq)
2850 // test that a server handler can send trailers
2851 func TestServerWritesTrailers_WithFlush(t *testing.T) { testServerWritesTrailers(t, true) }
2852 func TestServerWritesTrailers_WithoutFlush(t *testing.T) { testServerWritesTrailers(t, false) }
2854 func testServerWritesTrailers(t *testing.T, withFlush bool) {
2855 // See https://httpwg.github.io/specs/rfc7540.html#rfc.section.8.1.3
2856 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2857 w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B")
2858 w.Header().Add("Trailer", "Server-Trailer-C")
2859 w.Header().Add("Trailer", "Transfer-Encoding, Content-Length, Trailer") // filtered
2862 w.Header().Set("Foo", "Bar")
2863 w.Header().Set("Content-Length", "5") // len("Hello")
2865 io.WriteString(w, "Hello")
2867 w.(http.Flusher).Flush()
2869 w.Header().Set("Server-Trailer-A", "valuea")
2870 w.Header().Set("Server-Trailer-C", "valuec") // skipping B
2871 // After a flush, random keys like Server-Surprise shouldn't show up:
2872 w.Header().Set("Server-Surpise", "surprise! this isn't predeclared!")
2873 // But we do permit promoting keys to trailers after a
2874 // flush if they start with the magic
2875 // otherwise-invalid "Trailer:" prefix:
2876 w.Header().Set("Trailer:Post-Header-Trailer", "hi1")
2877 w.Header().Set("Trailer:post-header-trailer2", "hi2")
2878 w.Header().Set("Trailer:Range", "invalid")
2879 w.Header().Set("Trailer:Foo\x01Bogus", "invalid")
2880 w.Header().Set("Transfer-Encoding", "should not be included; Forbidden by RFC 2616 14.40")
2881 w.Header().Set("Content-Length", "should not be included; Forbidden by RFC 2616 14.40")
2882 w.Header().Set("Trailer", "should not be included; Forbidden by RFC 2616 14.40")
2884 }, func(st *serverTester) {
2886 hf := st.wantHeaders()
2887 if hf.StreamEnded() {
2888 t.Fatal("response HEADERS had END_STREAM")
2890 if !hf.HeadersEnded() {
2891 t.Fatal("response HEADERS didn't have END_HEADERS")
2893 goth := st.decodeHeader(hf.HeaderBlockFragment())
2894 wanth := [][2]string{
2897 {"trailer", "Server-Trailer-A, Server-Trailer-B"},
2898 {"trailer", "Server-Trailer-C"},
2899 {"trailer", "Transfer-Encoding, Content-Length, Trailer"},
2900 {"content-type", "text/plain; charset=utf-8"},
2901 {"content-length", "5"},
2903 if !reflect.DeepEqual(goth, wanth) {
2904 t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth)
2907 if string(df.Data()) != "Hello" {
2908 t.Fatalf("Client read %q; want Hello", df.Data())
2910 if df.StreamEnded() {
2911 t.Fatalf("data frame had STREAM_ENDED")
2913 tf := st.wantHeaders() // for the trailers
2914 if !tf.StreamEnded() {
2915 t.Fatalf("trailers HEADERS lacked END_STREAM")
2917 if !tf.HeadersEnded() {
2918 t.Fatalf("trailers HEADERS lacked END_HEADERS")
2920 wanth = [][2]string{
2921 {"post-header-trailer", "hi1"},
2922 {"post-header-trailer2", "hi2"},
2923 {"server-trailer-a", "valuea"},
2924 {"server-trailer-c", "valuec"},
2926 goth = st.decodeHeader(tf.HeaderBlockFragment())
2927 if !reflect.DeepEqual(goth, wanth) {
2928 t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth)
2933 // validate transmitted header field names & values
2934 // golang.org/issue/14048
2935 func TestServerDoesntWriteInvalidHeaders(t *testing.T) {
2936 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2937 w.Header().Add("OK1", "x")
2938 w.Header().Add("Bad:Colon", "x") // colon (non-token byte) in key
2939 w.Header().Add("Bad1\x00", "x") // null in key
2940 w.Header().Add("Bad2", "x\x00y") // null in value
2942 }, func(st *serverTester) {
2944 hf := st.wantHeaders()
2945 if !hf.StreamEnded() {
2946 t.Error("response HEADERS lacked END_STREAM")
2948 if !hf.HeadersEnded() {
2949 t.Fatal("response HEADERS didn't have END_HEADERS")
2951 goth := st.decodeHeader(hf.HeaderBlockFragment())
2952 wanth := [][2]string{
2955 {"content-type", "text/plain; charset=utf-8"},
2956 {"content-length", "0"},
2958 if !reflect.DeepEqual(goth, wanth) {
2959 t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth)
2964 func BenchmarkServerGets(b *testing.B) {
2965 defer disableGoroutineTracking()()
2968 const msg = "Hello, world"
2969 st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
2970 io.WriteString(w, msg)
2975 // Give the server quota to reply. (plus it has the the 64KB)
2976 if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
2980 for i := 0; i < b.N; i++ {
2981 id := 1 + uint32(i)*2
2982 st.writeHeaders(HeadersFrameParam{
2984 BlockFragment: st.encodeHeader(),
2990 if !df.StreamEnded() {
2991 b.Fatalf("DATA didn't have END_STREAM; got %v", df)
2996 func BenchmarkServerPosts(b *testing.B) {
2997 defer disableGoroutineTracking()()
3000 const msg = "Hello, world"
3001 st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
3002 // Consume the (empty) body from th peer before replying, otherwise
3003 // the server will sometimes (depending on scheduling) send the peer a
3004 // a RST_STREAM with the CANCEL error code.
3005 if n, err := io.Copy(ioutil.Discard, r.Body); n != 0 || err != nil {
3006 b.Errorf("Copy error; got %v, %v; want 0, nil", n, err)
3008 io.WriteString(w, msg)
3013 // Give the server quota to reply. (plus it has the the 64KB)
3014 if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
3018 for i := 0; i < b.N; i++ {
3019 id := 1 + uint32(i)*2
3020 st.writeHeaders(HeadersFrameParam{
3022 BlockFragment: st.encodeHeader(":method", "POST"),
3026 st.writeData(id, true, nil)
3029 if !df.StreamEnded() {
3030 b.Fatalf("DATA didn't have END_STREAM; got %v", df)
3035 // Send a stream of messages from server to client in separate data frames.
3036 // Brings up performance issues seen in long streams.
3037 // Created to show problem in go issue #18502
3038 func BenchmarkServerToClientStreamDefaultOptions(b *testing.B) {
3039 benchmarkServerToClientStream(b)
3042 // Justification for Change-Id: Iad93420ef6c3918f54249d867098f1dadfa324d8
3043 // Expect to see memory/alloc reduction by opting in to Frame reuse with the Framer.
3044 func BenchmarkServerToClientStreamReuseFrames(b *testing.B) {
3045 benchmarkServerToClientStream(b, optFramerReuseFrames)
3048 func benchmarkServerToClientStream(b *testing.B, newServerOpts ...interface{}) {
3049 defer disableGoroutineTracking()()
3052 // default window size
3053 const windowSize = 1<<16 - 1
3055 // next message to send from the server and for the client to expect
3056 nextMsg := func(i int) []byte {
3057 msg := make([]byte, msgLen)
3059 if len(msg) != msgLen {
3060 panic("invalid test setup msg length")
3065 st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
3066 // Consume the (empty) body from th peer before replying, otherwise
3067 // the server will sometimes (depending on scheduling) send the peer a
3068 // a RST_STREAM with the CANCEL error code.
3069 if n, err := io.Copy(ioutil.Discard, r.Body); n != 0 || err != nil {
3070 b.Errorf("Copy error; got %v, %v; want 0, nil", n, err)
3072 for i := 0; i < b.N; i += 1 {
3074 w.(http.Flusher).Flush()
3076 }, newServerOpts...)
3080 const id = uint32(1)
3082 st.writeHeaders(HeadersFrameParam{
3084 BlockFragment: st.encodeHeader(":method", "POST"),
3089 st.writeData(id, true, nil)
3092 var pendingWindowUpdate = uint32(0)
3094 for i := 0; i < b.N; i += 1 {
3095 expected := nextMsg(i)
3097 if bytes.Compare(expected, df.data) != 0 {
3098 b.Fatalf("Bad message received; want %v; got %v", expected, df.data)
3100 // try to send infrequent but large window updates so they don't overwhelm the test
3101 pendingWindowUpdate += uint32(len(df.data))
3102 if pendingWindowUpdate >= windowSize/2 {
3103 if err := st.fr.WriteWindowUpdate(0, pendingWindowUpdate); err != nil {
3106 if err := st.fr.WriteWindowUpdate(id, pendingWindowUpdate); err != nil {
3109 pendingWindowUpdate = 0
3113 if !df.StreamEnded() {
3114 b.Fatalf("DATA didn't have END_STREAM; got %v", df)
3118 // go-fuzz bug, originally reported at https://github.com/bradfitz/http2/issues/53
3119 // Verify we don't hang.
3120 func TestIssue53(t *testing.T) {
3121 const data = "PRI * HTTP/2.0\r\n\r\nSM" +
3122 "\r\n\r\n\x00\x00\x00\x01\ainfinfin\ad"
3124 ErrorLog: log.New(io.MultiWriter(stderrv(), twriter{t: t}), "", log.LstdFlags),
3125 Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
3126 w.Write([]byte("hello"))
3130 MaxReadFrameSize: 1 << 16,
3131 PermitProhibitedCipherSuites: true,
3133 c := &issue53Conn{[]byte(data), false, false}
3134 s2.ServeConn(c, &ServeConnOpts{BaseConfig: s})
3136 t.Fatal("connection is not closed")
3140 type issue53Conn struct {
3146 func (c *issue53Conn) Read(b []byte) (n int, err error) {
3147 if len(c.data) == 0 {
3155 func (c *issue53Conn) Write(b []byte) (n int, err error) {
3160 func (c *issue53Conn) Close() error {
3165 func (c *issue53Conn) LocalAddr() net.Addr {
3166 return &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 49706}
3168 func (c *issue53Conn) RemoteAddr() net.Addr {
3169 return &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 49706}
3171 func (c *issue53Conn) SetDeadline(t time.Time) error { return nil }
3172 func (c *issue53Conn) SetReadDeadline(t time.Time) error { return nil }
3173 func (c *issue53Conn) SetWriteDeadline(t time.Time) error { return nil }
3175 // golang.org/issue/12895
3176 func TestConfigureServer(t *testing.T) {
3179 tlsConfig *tls.Config
3183 name: "empty server",
3186 name: "just the required cipher suite",
3187 tlsConfig: &tls.Config{
3188 CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3192 name: "missing required cipher suite",
3193 tlsConfig: &tls.Config{
3194 CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
3196 wantErr: "is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
3199 name: "required after bad",
3200 tlsConfig: &tls.Config{
3201 CipherSuites: []uint16{tls.TLS_RSA_WITH_RC4_128_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3203 wantErr: "contains an HTTP/2-approved cipher suite (0xc02f), but it comes after",
3206 name: "bad after required",
3207 tlsConfig: &tls.Config{
3208 CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_RSA_WITH_RC4_128_SHA},
3212 for _, tt := range tests {
3213 srv := &http.Server{TLSConfig: tt.tlsConfig}
3214 err := ConfigureServer(srv, nil)
3215 if (err != nil) != (tt.wantErr != "") {
3216 if tt.wantErr != "" {
3217 t.Errorf("%s: success, but want error", tt.name)
3219 t.Errorf("%s: unexpected error: %v", tt.name, err)
3222 if err != nil && tt.wantErr != "" && !strings.Contains(err.Error(), tt.wantErr) {
3223 t.Errorf("%s: err = %v; want substring %q", tt.name, err, tt.wantErr)
3225 if err == nil && !srv.TLSConfig.PreferServerCipherSuites {
3226 t.Errorf("%s: PreferServerCipherSuite is false; want true", tt.name)
3231 func TestServerRejectHeadWithBody(t *testing.T) {
3232 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3233 // No response body.
3237 st.writeHeaders(HeadersFrameParam{
3238 StreamID: 1, // clients send odd numbers
3239 BlockFragment: st.encodeHeader(":method", "HEAD"),
3240 EndStream: false, // what we're testing, a bogus HEAD request with body
3243 st.wantRSTStream(1, ErrCodeProtocol)
3246 func TestServerNoAutoContentLengthOnHead(t *testing.T) {
3247 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3248 // No response body. (or smaller than one frame)
3252 st.writeHeaders(HeadersFrameParam{
3253 StreamID: 1, // clients send odd numbers
3254 BlockFragment: st.encodeHeader(":method", "HEAD"),
3258 h := st.wantHeaders()
3259 headers := st.decodeHeader(h.HeaderBlockFragment())
3260 want := [][2]string{
3262 {"content-type", "text/plain; charset=utf-8"},
3264 if !reflect.DeepEqual(headers, want) {
3265 t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
3269 // golang.org/issue/13495
3270 func TestServerNoDuplicateContentType(t *testing.T) {
3271 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3272 w.Header()["Content-Type"] = []string{""}
3273 fmt.Fprintf(w, "<html><head></head><body>hi</body></html>")
3277 st.writeHeaders(HeadersFrameParam{
3279 BlockFragment: st.encodeHeader(),
3283 h := st.wantHeaders()
3284 headers := st.decodeHeader(h.HeaderBlockFragment())
3285 want := [][2]string{
3287 {"content-type", ""},
3288 {"content-length", "41"},
3290 if !reflect.DeepEqual(headers, want) {
3291 t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
3295 func disableGoroutineTracking() (restore func()) {
3296 old := DebugGoroutines
3297 DebugGoroutines = false
3298 return func() { DebugGoroutines = old }
3301 func BenchmarkServer_GetRequest(b *testing.B) {
3302 defer disableGoroutineTracking()()
3304 const msg = "Hello, world."
3305 st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
3306 n, err := io.Copy(ioutil.Discard, r.Body)
3307 if err != nil || n > 0 {
3308 b.Errorf("Read %d bytes, error %v; want 0 bytes.", n, err)
3310 io.WriteString(w, msg)
3315 // Give the server quota to reply. (plus it has the the 64KB)
3316 if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
3319 hbf := st.encodeHeader(":method", "GET")
3320 for i := 0; i < b.N; i++ {
3321 streamID := uint32(1 + 2*i)
3322 st.writeHeaders(HeadersFrameParam{
3333 func BenchmarkServer_PostRequest(b *testing.B) {
3334 defer disableGoroutineTracking()()
3336 const msg = "Hello, world."
3337 st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
3338 n, err := io.Copy(ioutil.Discard, r.Body)
3339 if err != nil || n > 0 {
3340 b.Errorf("Read %d bytes, error %v; want 0 bytes.", n, err)
3342 io.WriteString(w, msg)
3346 // Give the server quota to reply. (plus it has the the 64KB)
3347 if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
3350 hbf := st.encodeHeader(":method", "POST")
3351 for i := 0; i < b.N; i++ {
3352 streamID := uint32(1 + 2*i)
3353 st.writeHeaders(HeadersFrameParam{
3359 st.writeData(streamID, true, nil)
3365 type connStateConn struct {
3367 cs tls.ConnectionState
3370 func (c connStateConn) ConnectionState() tls.ConnectionState { return c.cs }
3372 // golang.org/issue/12737 -- handle any net.Conn, not just
3374 func TestServerHandleCustomConn(t *testing.T) {
3376 c1, c2 := net.Pipe()
3377 clientDone := make(chan struct{})
3378 handlerDone := make(chan struct{})
3379 var req *http.Request
3381 defer close(clientDone)
3383 fr := NewFramer(c2, c2)
3384 io.WriteString(c2, ClientPreface)
3386 fr.WriteSettingsAck()
3387 f, err := fr.ReadFrame()
3392 if sf, ok := f.(*SettingsFrame); !ok || sf.IsAck() {
3393 t.Errorf("Got %v; want non-ACK SettingsFrame", summarizeFrame(f))
3396 f, err = fr.ReadFrame()
3401 if sf, ok := f.(*SettingsFrame); !ok || !sf.IsAck() {
3402 t.Errorf("Got %v; want ACK SettingsFrame", summarizeFrame(f))
3405 var henc hpackEncoder
3406 fr.WriteHeaders(HeadersFrameParam{
3408 BlockFragment: henc.encodeHeaderRaw(t, ":method", "GET", ":path", "/", ":scheme", "https", ":authority", "foo.com"),
3412 go io.Copy(ioutil.Discard, c2)
3415 const testString = "my custom ConnectionState"
3416 fakeConnState := tls.ConnectionState{
3417 ServerName: testString,
3418 Version: tls.VersionTLS12,
3419 CipherSuite: cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
3421 go s.ServeConn(connStateConn{c1, fakeConnState}, &ServeConnOpts{
3422 BaseConfig: &http.Server{
3423 Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
3424 defer close(handlerDone)
3430 case <-time.After(5 * time.Second):
3431 t.Fatal("timeout waiting for handler")
3434 t.Fatalf("Request.TLS is nil. Got: %#v", req)
3436 if req.TLS.ServerName != testString {
3437 t.Fatalf("Request.TLS = %+v; want ServerName of %q", req.TLS, testString)
3441 // golang.org/issue/14214
3442 func TestServer_Rejects_ConnHeaders(t *testing.T) {
3443 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3444 t.Error("should not get to Handler")
3448 st.bodylessReq1("connection", "foo")
3449 hf := st.wantHeaders()
3450 goth := st.decodeHeader(hf.HeaderBlockFragment())
3451 wanth := [][2]string{
3453 {"content-type", "text/plain; charset=utf-8"},
3454 {"x-content-type-options", "nosniff"},
3455 {"content-length", "51"},
3457 if !reflect.DeepEqual(goth, wanth) {
3458 t.Errorf("Got headers %v; want %v", goth, wanth)
3462 type hpackEncoder struct {
3467 func (he *hpackEncoder) encodeHeaderRaw(t *testing.T, headers ...string) []byte {
3468 if len(headers)%2 == 1 {
3469 panic("odd number of kv args")
3473 he.enc = hpack.NewEncoder(&he.buf)
3475 for len(headers) > 0 {
3476 k, v := headers[0], headers[1]
3477 err := he.enc.WriteField(hpack.HeaderField{Name: k, Value: v})
3479 t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err)
3481 headers = headers[2:]
3483 return he.buf.Bytes()
3486 func TestCheckValidHTTP2Request(t *testing.T) {
3492 h: http.Header{"Te": {"trailers"}},
3496 h: http.Header{"Te": {"trailers", "bogus"}},
3497 want: errors.New(`request header "TE" may only be "trailers" in HTTP/2`),
3500 h: http.Header{"Foo": {""}},
3504 h: http.Header{"Connection": {""}},
3505 want: errors.New(`request header "Connection" is not valid in HTTP/2`),
3508 h: http.Header{"Proxy-Connection": {""}},
3509 want: errors.New(`request header "Proxy-Connection" is not valid in HTTP/2`),
3512 h: http.Header{"Keep-Alive": {""}},
3513 want: errors.New(`request header "Keep-Alive" is not valid in HTTP/2`),
3516 h: http.Header{"Upgrade": {""}},
3517 want: errors.New(`request header "Upgrade" is not valid in HTTP/2`),
3520 for i, tt := range tests {
3521 got := checkValidHTTP2RequestHeaders(tt.h)
3522 if !reflect.DeepEqual(got, tt.want) {
3523 t.Errorf("%d. checkValidHTTP2Request = %v; want %v", i, got, tt.want)
3528 // golang.org/issue/14030
3529 func TestExpect100ContinueAfterHandlerWrites(t *testing.T) {
3531 const msg2 = "World"
3533 doRead := make(chan bool, 1)
3534 defer close(doRead) // fallback cleanup
3536 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3537 io.WriteString(w, msg)
3538 w.(http.Flusher).Flush()
3540 // Do a read, which might force a 100-continue status to be sent.
3542 r.Body.Read(make([]byte, 10))
3544 io.WriteString(w, msg2)
3549 tr := &Transport{TLSClientConfig: tlsConfigInsecure}
3550 defer tr.CloseIdleConnections()
3552 req, _ := http.NewRequest("POST", st.ts.URL, io.LimitReader(neverEnding('A'), 2<<20))
3553 req.Header.Set("Expect", "100-continue")
3555 res, err := tr.RoundTrip(req)
3559 defer res.Body.Close()
3561 buf := make([]byte, len(msg))
3562 if _, err := io.ReadFull(res.Body, buf); err != nil {
3565 if string(buf) != msg {
3566 t.Fatalf("msg = %q; want %q", buf, msg)
3571 if _, err := io.ReadFull(res.Body, buf); err != nil {
3574 if string(buf) != msg2 {
3575 t.Fatalf("second msg = %q; want %q", buf, msg2)
3579 type funcReader func([]byte) (n int, err error)
3581 func (f funcReader) Read(p []byte) (n int, err error) { return f(p) }
3583 // golang.org/issue/16481 -- return flow control when streams close with unread data.
3584 // (The Server version of the bug. See also TestUnreadFlowControlReturned_Transport)
3585 func TestUnreadFlowControlReturned_Server(t *testing.T) {
3586 unblock := make(chan bool, 1)
3587 defer close(unblock)
3589 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3590 // Don't read the 16KB request body. Wait until the client's
3591 // done sending it and then return. This should cause the Server
3592 // to then return those 16KB of flow control to the client.
3597 tr := &Transport{TLSClientConfig: tlsConfigInsecure}
3598 defer tr.CloseIdleConnections()
3600 // This previously hung on the 4th iteration.
3601 for i := 0; i < 6; i++ {
3602 body := io.MultiReader(
3603 io.LimitReader(neverEnding('A'), 16<<10),
3604 funcReader(func([]byte) (n int, err error) {
3609 req, _ := http.NewRequest("POST", st.ts.URL, body)
3610 res, err := tr.RoundTrip(req)
3619 func TestServerIdleTimeout(t *testing.T) {
3620 if testing.Short() {
3621 t.Skip("skipping in short mode")
3624 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3625 }, func(h2s *Server) {
3626 h2s.IdleTimeout = 500 * time.Millisecond
3631 ga := st.wantGoAway()
3632 if ga.ErrCode != ErrCodeNo {
3633 t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode)
3637 func TestServerIdleTimeout_AfterRequest(t *testing.T) {
3638 if testing.Short() {
3639 t.Skip("skipping in short mode")
3641 const timeout = 250 * time.Millisecond
3643 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3644 time.Sleep(timeout * 2)
3645 }, func(h2s *Server) {
3646 h2s.IdleTimeout = timeout
3652 // Send a request which takes twice the timeout. Verifies the
3653 // idle timeout doesn't fire while we're in a request:
3657 // But the idle timeout should be rearmed after the request
3659 ga := st.wantGoAway()
3660 if ga.ErrCode != ErrCodeNo {
3661 t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode)
3665 // grpc-go closes the Request.Body currently with a Read.
3666 // Verify that it doesn't race.
3667 // See https://github.com/grpc/grpc-go/pull/938
3668 func TestRequestBodyReadCloseRace(t *testing.T) {
3669 for i := 0; i < 100; i++ {
3670 body := &requestBody{
3672 b: new(bytes.Buffer),
3675 body.pipe.CloseWithError(io.EOF)
3677 done := make(chan bool, 1)
3678 buf := make([]byte, 10)
3680 time.Sleep(1 * time.Millisecond)
3689 func TestIssue20704Race(t *testing.T) {
3690 if testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" {
3691 t.Skip("skipping in short mode")
3698 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3699 for i := 0; i < itemCount; i++ {
3700 _, err := w.Write(make([]byte, itemSize))
3708 tr := &Transport{TLSClientConfig: tlsConfigInsecure}
3709 defer tr.CloseIdleConnections()
3710 cl := &http.Client{Transport: tr}
3712 for i := 0; i < 1000; i++ {
3713 resp, err := cl.Get(st.ts.URL)
3717 // Force a RST stream to the server by closing without
3718 // reading the body: