1
2
3
4
5 package http2_test
6
7 import (
8 "bytes"
9 "compress/gzip"
10 "compress/zlib"
11 "context"
12 "crypto/tls"
13 "crypto/x509"
14 "errors"
15 "flag"
16 "fmt"
17 "io"
18 "log"
19 "math"
20 "net"
21 "net/http"
22 "net/http/httptest"
23 "os"
24 "reflect"
25 "runtime"
26 "slices"
27 "strconv"
28 "strings"
29 "sync"
30 "testing"
31 "testing/synctest"
32 "time"
33 _ "unsafe"
34
35 "net/http/internal/http2"
36 . "net/http/internal/http2"
37 "net/http/internal/testcert"
38
39 "golang.org/x/net/http2/hpack"
40 )
41
42 var stderrVerbose = flag.Bool("stderr_verbose", false, "Mirror verbosity to stderr, unbuffered")
43
44 func stderrv() io.Writer {
45 if *stderrVerbose {
46 return os.Stderr
47 }
48
49 return io.Discard
50 }
51
52 type safeBuffer struct {
53 b bytes.Buffer
54 m sync.Mutex
55 }
56
57 func (sb *safeBuffer) Write(d []byte) (int, error) {
58 sb.m.Lock()
59 defer sb.m.Unlock()
60 return sb.b.Write(d)
61 }
62
63 func (sb *safeBuffer) Bytes() []byte {
64 sb.m.Lock()
65 defer sb.m.Unlock()
66 return sb.b.Bytes()
67 }
68
69 func (sb *safeBuffer) Len() int {
70 sb.m.Lock()
71 defer sb.m.Unlock()
72 return sb.b.Len()
73 }
74
75 type serverTester struct {
76 cc net.Conn
77 t *testing.T
78 h1server *http.Server
79 h2server *Server
80 serverLogBuf safeBuffer
81 logFilter []string
82 scMu sync.Mutex
83 sc *ServerConn
84 wrotePreface bool
85 testConnFramer
86
87 callsMu sync.Mutex
88 calls []*serverHandlerCall
89
90
91
92
93
94 frameReadLogMu sync.Mutex
95 frameReadLogBuf bytes.Buffer
96 frameWriteLogMu sync.Mutex
97 frameWriteLogBuf bytes.Buffer
98
99
100 headerBuf bytes.Buffer
101 hpackEnc *hpack.Encoder
102 }
103
104 type twriter struct {
105 t testing.TB
106 st *serverTester
107 }
108
109 func (w twriter) Write(p []byte) (n int, err error) {
110 if w.st != nil {
111 ps := string(p)
112 for _, phrase := range w.st.logFilter {
113 if strings.Contains(ps, phrase) {
114 return len(p), nil
115 }
116 }
117 }
118 w.t.Logf("%s", p)
119 return len(p), nil
120 }
121
122 func newTestServer(t testing.TB, handler http.HandlerFunc, opts ...any) *httptest.Server {
123 t.Helper()
124 if handler == nil {
125 handler = func(w http.ResponseWriter, req *http.Request) {}
126 }
127 ts := httptest.NewUnstartedServer(handler)
128 ts.EnableHTTP2 = true
129 ts.Config.ErrorLog = log.New(twriter{t: t}, "", log.LstdFlags)
130 ts.Config.Protocols = protocols("h2")
131 for _, opt := range opts {
132 switch v := opt.(type) {
133 case func(*httptest.Server):
134 v(ts)
135 case func(*http.Server):
136 v(ts.Config)
137 case func(*http.HTTP2Config):
138 if ts.Config.HTTP2 == nil {
139 ts.Config.HTTP2 = &http.HTTP2Config{}
140 }
141 v(ts.Config.HTTP2)
142 default:
143 t.Fatalf("unknown newTestServer option type %T", v)
144 }
145 }
146
147 if ts.Config.Protocols.HTTP2() {
148 ts.TLS = testServerTLSConfig
149 if ts.Config.TLSConfig != nil {
150 ts.TLS = ts.Config.TLSConfig
151 }
152 ts.StartTLS()
153 } else if ts.Config.Protocols.UnencryptedHTTP2() {
154 ts.EnableHTTP2 = false
155 ts.Start()
156 } else {
157 t.Fatalf("Protocols contains neither HTTP2 nor UnencryptedHTTP2")
158 }
159
160 t.Cleanup(func() {
161 ts.CloseClientConnections()
162 ts.Close()
163 })
164
165 return ts
166 }
167
168 type serverTesterOpt string
169
170 var optFramerReuseFrames = serverTesterOpt("frame_reuse_frames")
171
172 var optQuiet = func(server *http.Server) {
173 server.ErrorLog = log.New(io.Discard, "", 0)
174 }
175
176 func newServerTester(t *testing.T, handler http.HandlerFunc, opts ...any) *serverTester {
177 t.Helper()
178
179 h1server := &http.Server{}
180 var tlsState *tls.ConnectionState
181 for _, opt := range opts {
182 switch v := opt.(type) {
183 case func(*http.Server):
184 v(h1server)
185 case func(*http.HTTP2Config):
186 if h1server.HTTP2 == nil {
187 h1server.HTTP2 = &http.HTTP2Config{}
188 }
189 v(h1server.HTTP2)
190 case func(*tls.ConnectionState):
191 if tlsState == nil {
192 tlsState = &tls.ConnectionState{
193 Version: tls.VersionTLS13,
194 ServerName: "go.dev",
195 CipherSuite: tls.TLS_AES_128_GCM_SHA256,
196 }
197 }
198 v(tlsState)
199 default:
200 t.Fatalf("unknown newServerTester option type %T", v)
201 }
202 }
203
204 tlsConfig := h1server.TLSConfig
205 if tlsConfig == nil {
206 cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
207 if err != nil {
208 t.Fatal(err)
209 }
210 tlsConfig = &tls.Config{
211 Certificates: []tls.Certificate{cert},
212 InsecureSkipVerify: true,
213 NextProtos: []string{"h2"},
214 }
215 h1server.TLSConfig = tlsConfig
216 }
217
218 var cli, srv net.Conn
219
220 cliPipe, srvPipe := synctestNetPipe()
221
222 if h1server.Protocols != nil && h1server.Protocols.UnencryptedHTTP2() {
223 cli, srv = cliPipe, srvPipe
224 } else {
225 cli = tls.Client(cliPipe, &tls.Config{
226 InsecureSkipVerify: true,
227 NextProtos: []string{"h2"},
228 })
229 srv = tls.Server(srvPipe, tlsConfig)
230 }
231
232 st := &serverTester{
233 t: t,
234 cc: cli,
235 h1server: h1server,
236 }
237 st.hpackEnc = hpack.NewEncoder(&st.headerBuf)
238 if h1server.ErrorLog == nil {
239 h1server.ErrorLog = log.New(io.MultiWriter(stderrv(), twriter{t: t, st: st}, &st.serverLogBuf), "", log.LstdFlags)
240 }
241
242 if handler == nil {
243 handler = serverTesterHandler{st}.ServeHTTP
244 }
245 h1server.Handler = handler
246
247 t.Cleanup(func() {
248 st.Close()
249 time.Sleep(GoAwayTimeout)
250 })
251
252 connc := make(chan *ServerConn)
253 h1server.ConnContext = func(ctx context.Context, conn net.Conn) context.Context {
254 ctx = context.WithValue(ctx, NewConnContextKey, func(sc *ServerConn) {
255 connc <- sc
256 })
257 if tlsState != nil {
258 ctx = context.WithValue(ctx, ConnectionStateContextKey, func() tls.ConnectionState {
259 return *tlsState
260 })
261 }
262 return ctx
263 }
264 go func() {
265 li := newOneConnListener(srv)
266 t.Cleanup(func() {
267 li.Close()
268 })
269 h1server.Serve(li)
270 }()
271 if cliTLS, ok := cli.(*tls.Conn); ok {
272 if err := cliTLS.Handshake(); err != nil {
273 t.Fatalf("client TLS handshake: %v", err)
274 }
275 cliTLS.SetReadDeadline(time.Now())
276 } else {
277
278
279 st.writePreface()
280 st.wrotePreface = true
281 cliPipe.SetReadDeadline(time.Now())
282 }
283 st.sc = <-connc
284
285 st.fr = NewFramer(st.cc, st.cc)
286 st.testConnFramer = testConnFramer{
287 t: t,
288 fr: NewFramer(cli, cli),
289 dec: hpack.NewDecoder(InitialHeaderTableSize, nil),
290 }
291 synctest.Wait()
292 return st
293 }
294
295 type netConnWithConnectionState struct {
296 net.Conn
297 state tls.ConnectionState
298 }
299
300 func (c *netConnWithConnectionState) ConnectionState() tls.ConnectionState {
301 return c.state
302 }
303
304 func (c *netConnWithConnectionState) HandshakeContext() tls.ConnectionState {
305 return c.state
306 }
307
308 type serverTesterHandler struct {
309 st *serverTester
310 }
311
312 func (h serverTesterHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
313 call := &serverHandlerCall{
314 w: w,
315 req: req,
316 ch: make(chan func()),
317 }
318 h.st.t.Cleanup(call.exit)
319 h.st.callsMu.Lock()
320 h.st.calls = append(h.st.calls, call)
321 h.st.callsMu.Unlock()
322 for f := range call.ch {
323 f()
324 }
325 }
326
327
328 type serverHandlerCall struct {
329 w http.ResponseWriter
330 req *http.Request
331 closeOnce sync.Once
332 ch chan func()
333 }
334
335
336 func (call *serverHandlerCall) do(f func(http.ResponseWriter, *http.Request)) {
337 donec := make(chan struct{})
338 call.ch <- func() {
339 defer close(donec)
340 f(call.w, call.req)
341 }
342 <-donec
343 }
344
345
346 func (call *serverHandlerCall) exit() {
347 call.closeOnce.Do(func() {
348 close(call.ch)
349 })
350 }
351
352
353 func (st *serverTester) sync() {
354 synctest.Wait()
355 }
356
357
358 func (st *serverTester) advance(d time.Duration) {
359 time.Sleep(d)
360 synctest.Wait()
361 }
362
363 func (st *serverTester) authority() string {
364 return "dummy.tld"
365 }
366
367 func (st *serverTester) addLogFilter(phrase string) {
368 st.logFilter = append(st.logFilter, phrase)
369 }
370
371 func (st *serverTester) nextHandlerCall() *serverHandlerCall {
372 st.t.Helper()
373 synctest.Wait()
374 st.callsMu.Lock()
375 defer st.callsMu.Unlock()
376 if len(st.calls) == 0 {
377 st.t.Fatal("expected server handler call, got none")
378 }
379 call := st.calls[0]
380 st.calls = st.calls[1:]
381 return call
382 }
383
384 func (st *serverTester) streamExists(id uint32) bool {
385 return st.sc.TestStreamExists(id)
386 }
387
388 func (st *serverTester) streamState(id uint32) StreamState {
389 return st.sc.TestStreamState(id)
390 }
391
392 func (st *serverTester) Close() {
393 if st.t.Failed() {
394 st.frameReadLogMu.Lock()
395 if st.frameReadLogBuf.Len() > 0 {
396 st.t.Logf("Framer read log:\n%s", st.frameReadLogBuf.String())
397 }
398 st.frameReadLogMu.Unlock()
399
400 st.frameWriteLogMu.Lock()
401 if st.frameWriteLogBuf.Len() > 0 {
402 st.t.Logf("Framer write log:\n%s", st.frameWriteLogBuf.String())
403 }
404 st.frameWriteLogMu.Unlock()
405
406
407
408
409
410 if st.cc != nil {
411 st.cc.Close()
412 }
413 }
414 if st.cc != nil {
415 st.cc.Close()
416 }
417 log.SetOutput(os.Stderr)
418 }
419
420
421
422 func (st *serverTester) greet() {
423 st.t.Helper()
424 st.greetAndCheckSettings(func(Setting) error { return nil })
425 }
426
427 func (st *serverTester) greetAndCheckSettings(checkSetting func(s Setting) error) {
428 st.t.Helper()
429 st.writePreface()
430 st.writeSettings()
431 st.sync()
432 readFrame[*SettingsFrame](st.t, st).ForeachSetting(checkSetting)
433 st.writeSettingsAck()
434
435
436 var gotSettingsAck bool
437 var gotWindowUpdate bool
438
439 for range 2 {
440 f := st.readFrame()
441 if f == nil {
442 st.t.Fatal("wanted a settings ACK and window update, got none")
443 }
444 switch f := f.(type) {
445 case *SettingsFrame:
446 if !f.Header().Flags.Has(FlagSettingsAck) {
447 st.t.Fatal("Settings Frame didn't have ACK set")
448 }
449 gotSettingsAck = true
450
451 case *WindowUpdateFrame:
452 if f.FrameHeader.StreamID != 0 {
453 st.t.Fatalf("WindowUpdate StreamID = %d; want 0", f.FrameHeader.StreamID)
454 }
455 gotWindowUpdate = true
456
457 default:
458 st.t.Fatalf("Wanting a settings ACK or window update, received a %T", f)
459 }
460 }
461
462 if !gotSettingsAck {
463 st.t.Fatalf("Didn't get a settings ACK")
464 }
465 if !gotWindowUpdate {
466 st.t.Fatalf("Didn't get a window update")
467 }
468 }
469
470 func (st *serverTester) writePreface() {
471 if st.wrotePreface {
472 return
473 }
474 n, err := st.cc.Write([]byte(ClientPreface))
475 if err != nil {
476 st.t.Fatalf("Error writing client preface: %v", err)
477 }
478 if n != len(ClientPreface) {
479 st.t.Fatalf("Writing client preface, wrote %d bytes; want %d", n, len(ClientPreface))
480 }
481 }
482
483 func (st *serverTester) encodeHeaderField(k, v string) {
484 err := st.hpackEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
485 if err != nil {
486 st.t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err)
487 }
488 }
489
490
491
492 func (st *serverTester) encodeHeaderRaw(headers ...string) []byte {
493 if len(headers)%2 == 1 {
494 panic("odd number of kv args")
495 }
496 st.headerBuf.Reset()
497 for len(headers) > 0 {
498 k, v := headers[0], headers[1]
499 st.encodeHeaderField(k, v)
500 headers = headers[2:]
501 }
502 return st.headerBuf.Bytes()
503 }
504
505
506
507
508
509
510 func (st *serverTester) encodeHeader(headers ...string) []byte {
511 if len(headers)%2 == 1 {
512 panic("odd number of kv args")
513 }
514
515 st.headerBuf.Reset()
516 defaultAuthority := st.authority()
517
518 if len(headers) == 0 {
519
520
521 st.encodeHeaderField(":method", "GET")
522 st.encodeHeaderField(":scheme", "https")
523 st.encodeHeaderField(":authority", defaultAuthority)
524 st.encodeHeaderField(":path", "/")
525 return st.headerBuf.Bytes()
526 }
527
528 if len(headers) == 2 && headers[0] == ":method" {
529
530 st.encodeHeaderField(":method", headers[1])
531 st.encodeHeaderField(":scheme", "https")
532 st.encodeHeaderField(":authority", defaultAuthority)
533 st.encodeHeaderField(":path", "/")
534 return st.headerBuf.Bytes()
535 }
536
537 pseudoCount := map[string]int{}
538 keys := []string{":method", ":scheme", ":authority", ":path"}
539 vals := map[string][]string{
540 ":method": {"GET"},
541 ":scheme": {"https"},
542 ":authority": {defaultAuthority},
543 ":path": {"/"},
544 }
545 for len(headers) > 0 {
546 k, v := headers[0], headers[1]
547 headers = headers[2:]
548 if _, ok := vals[k]; !ok {
549 keys = append(keys, k)
550 }
551 if strings.HasPrefix(k, ":") {
552 pseudoCount[k]++
553 if pseudoCount[k] == 1 {
554 vals[k] = []string{v}
555 } else {
556
557 vals[k] = append(vals[k], v)
558 }
559 } else {
560 vals[k] = append(vals[k], v)
561 }
562 }
563 for _, k := range keys {
564 for _, v := range vals[k] {
565 st.encodeHeaderField(k, v)
566 }
567 }
568 return st.headerBuf.Bytes()
569 }
570
571
572 func (st *serverTester) bodylessReq1(headers ...string) {
573 st.writeHeaders(HeadersFrameParam{
574 StreamID: 1,
575 BlockFragment: st.encodeHeader(headers...),
576 EndStream: true,
577 EndHeaders: true,
578 })
579 }
580
581 func (st *serverTester) wantConnFlowControlConsumed(consumed int32) {
582 if got, want := st.sc.TestFlowControlConsumed(), consumed; got != want {
583 st.t.Errorf("connection flow control consumed: %v, want %v", got, want)
584 }
585 }
586
587 func TestServer(t *testing.T) { synctest.Test(t, testServer) }
588 func testServer(t *testing.T) {
589 gotReq := make(chan bool, 1)
590 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
591 w.Header().Set("Foo", "Bar")
592 gotReq <- true
593 })
594 defer st.Close()
595
596 st.greet()
597 st.writeHeaders(HeadersFrameParam{
598 StreamID: 1,
599 BlockFragment: st.encodeHeader(),
600 EndStream: true,
601 EndHeaders: true,
602 })
603
604 <-gotReq
605 }
606
607 func TestServer_Request_TLS(t *testing.T) {
608 for _, unencrypted := range []bool{false, true} {
609 for _, scheme := range []string{"https", "http", ""} {
610 name := scheme
611 if scheme == "" {
612 name = "CONNECT"
613 }
614 t.Run(fmt.Sprintf("unencrypted=%v/%s", unencrypted, name), func(t *testing.T) {
615 synctest.Test(t, func(t *testing.T) {
616 gotTLS := make(chan *tls.ConnectionState, 1)
617 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
618 gotTLS <- r.TLS
619 }, func(s *http.Server) {
620 s.Protocols = new(http.Protocols)
621 s.Protocols.SetHTTP2(!unencrypted)
622 s.Protocols.SetUnencryptedHTTP2(unencrypted)
623 })
624 st.greet()
625 headers := []string{":method", "CONNECT", ":authority", "example.com:443"}
626 if scheme != "" {
627 headers = []string{":method", "GET", ":authority", "example.com", ":scheme", scheme, ":path", "/"}
628 }
629 st.writeHeaders(HeadersFrameParam{
630 StreamID: 1,
631 BlockFragment: st.encodeHeaderRaw(headers...),
632 EndStream: true,
633 EndHeaders: true,
634 })
635 state := <-gotTLS
636 if unencrypted {
637 if state != nil {
638 t.Fatalf("Request.TLS = %v; want nil for an unencrypted connection", state)
639 }
640 } else {
641 if state == nil {
642 t.Fatal("Request.TLS = nil; want TLS connection state")
643 }
644 if !state.HandshakeComplete || state.NegotiatedProtocol != "h2" {
645 t.Errorf("Request.TLS = %+v; want completed HTTP/2 TLS handshake", state)
646 }
647 }
648 })
649 })
650 }
651 }
652 }
653
654 func TestServer_Request_Get(t *testing.T) { synctest.Test(t, testServer_Request_Get) }
655 func testServer_Request_Get(t *testing.T) {
656 testServerRequest(t, func(st *serverTester) {
657 st.writeHeaders(HeadersFrameParam{
658 StreamID: 1,
659 BlockFragment: st.encodeHeader("foo-bar", "some-value"),
660 EndStream: true,
661 EndHeaders: true,
662 })
663 }, func(r *http.Request) {
664 if r.Method != "GET" {
665 t.Errorf("Method = %q; want GET", r.Method)
666 }
667 if r.URL.Path != "/" {
668 t.Errorf("URL.Path = %q; want /", r.URL.Path)
669 }
670 if r.ContentLength != 0 {
671 t.Errorf("ContentLength = %v; want 0", r.ContentLength)
672 }
673 if r.Close {
674 t.Error("Close = true; want false")
675 }
676 if !strings.Contains(r.RemoteAddr, ":") {
677 t.Errorf("RemoteAddr = %q; want something with a colon", r.RemoteAddr)
678 }
679 if r.Proto != "HTTP/2.0" || r.ProtoMajor != 2 || r.ProtoMinor != 0 {
680 t.Errorf("Proto = %q Major=%v,Minor=%v; want HTTP/2.0", r.Proto, r.ProtoMajor, r.ProtoMinor)
681 }
682 wantHeader := http.Header{
683 "Foo-Bar": []string{"some-value"},
684 }
685 if !reflect.DeepEqual(r.Header, wantHeader) {
686 t.Errorf("Header = %#v; want %#v", r.Header, wantHeader)
687 }
688 if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 {
689 t.Errorf("Read = %d, %v; want 0, EOF", n, err)
690 }
691 })
692 }
693
694 func TestServer_Request_Get_PathSlashes(t *testing.T) {
695 synctest.Test(t, testServer_Request_Get_PathSlashes)
696 }
697 func testServer_Request_Get_PathSlashes(t *testing.T) {
698 testServerRequest(t, func(st *serverTester) {
699 st.writeHeaders(HeadersFrameParam{
700 StreamID: 1,
701 BlockFragment: st.encodeHeader(":path", "/%2f/"),
702 EndStream: true,
703 EndHeaders: true,
704 })
705 }, func(r *http.Request) {
706 if r.RequestURI != "/%2f/" {
707 t.Errorf("RequestURI = %q; want /%%2f/", r.RequestURI)
708 }
709 if r.URL.Path != "///" {
710 t.Errorf("URL.Path = %q; want ///", r.URL.Path)
711 }
712 })
713 }
714
715
716
717
718
719 func TestServer_Request_Post_NoContentLength_EndStream(t *testing.T) {
720 synctest.Test(t, testServer_Request_Post_NoContentLength_EndStream)
721 }
722 func testServer_Request_Post_NoContentLength_EndStream(t *testing.T) {
723 testServerRequest(t, func(st *serverTester) {
724 st.writeHeaders(HeadersFrameParam{
725 StreamID: 1,
726 BlockFragment: st.encodeHeader(":method", "POST"),
727 EndStream: true,
728 EndHeaders: true,
729 })
730 }, func(r *http.Request) {
731 if r.Method != "POST" {
732 t.Errorf("Method = %q; want POST", r.Method)
733 }
734 if r.ContentLength != 0 {
735 t.Errorf("ContentLength = %v; want 0", r.ContentLength)
736 }
737 if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 {
738 t.Errorf("Read = %d, %v; want 0, EOF", n, err)
739 }
740 })
741 }
742
743 func TestServer_Request_Post_Body_ImmediateEOF(t *testing.T) {
744 synctest.Test(t, testServer_Request_Post_Body_ImmediateEOF)
745 }
746 func testServer_Request_Post_Body_ImmediateEOF(t *testing.T) {
747 testBodyContents(t, -1, "", func(st *serverTester) {
748 st.writeHeaders(HeadersFrameParam{
749 StreamID: 1,
750 BlockFragment: st.encodeHeader(":method", "POST"),
751 EndStream: false,
752 EndHeaders: true,
753 })
754 st.writeData(1, true, nil)
755 })
756 }
757
758 func TestServer_Request_Post_Body_OneData(t *testing.T) {
759 synctest.Test(t, testServer_Request_Post_Body_OneData)
760 }
761 func testServer_Request_Post_Body_OneData(t *testing.T) {
762 const content = "Some content"
763 testBodyContents(t, -1, content, func(st *serverTester) {
764 st.writeHeaders(HeadersFrameParam{
765 StreamID: 1,
766 BlockFragment: st.encodeHeader(":method", "POST"),
767 EndStream: false,
768 EndHeaders: true,
769 })
770 st.writeData(1, true, []byte(content))
771 })
772 }
773
774 func TestServer_Request_Post_Body_TwoData(t *testing.T) {
775 synctest.Test(t, testServer_Request_Post_Body_TwoData)
776 }
777 func testServer_Request_Post_Body_TwoData(t *testing.T) {
778 const content = "Some content"
779 testBodyContents(t, -1, content, func(st *serverTester) {
780 st.writeHeaders(HeadersFrameParam{
781 StreamID: 1,
782 BlockFragment: st.encodeHeader(":method", "POST"),
783 EndStream: false,
784 EndHeaders: true,
785 })
786 st.writeData(1, false, []byte(content[:5]))
787 st.writeData(1, true, []byte(content[5:]))
788 })
789 }
790
791 func TestServer_Request_Post_Body_ContentLength_Correct(t *testing.T) {
792 synctest.Test(t, testServer_Request_Post_Body_ContentLength_Correct)
793 }
794 func testServer_Request_Post_Body_ContentLength_Correct(t *testing.T) {
795 const content = "Some content"
796 testBodyContents(t, int64(len(content)), content, func(st *serverTester) {
797 st.writeHeaders(HeadersFrameParam{
798 StreamID: 1,
799 BlockFragment: st.encodeHeader(
800 ":method", "POST",
801 "content-length", strconv.Itoa(len(content)),
802 ),
803 EndStream: false,
804 EndHeaders: true,
805 })
806 st.writeData(1, true, []byte(content))
807 })
808 }
809
810 func TestServer_Request_Post_Body_ContentLength_TooLarge(t *testing.T) {
811 synctest.Test(t, testServer_Request_Post_Body_ContentLength_TooLarge)
812 }
813 func testServer_Request_Post_Body_ContentLength_TooLarge(t *testing.T) {
814 testBodyContentsFail(t, 3, "request declared a Content-Length of 3 but only wrote 2 bytes",
815 func(st *serverTester) {
816 st.writeHeaders(HeadersFrameParam{
817 StreamID: 1,
818 BlockFragment: st.encodeHeader(
819 ":method", "POST",
820 "content-length", "3",
821 ),
822 EndStream: false,
823 EndHeaders: true,
824 })
825 st.writeData(1, true, []byte("12"))
826 })
827 }
828
829 func TestServer_Request_Post_Body_ContentLength_EndStream(t *testing.T) {
830 testRejectRequest(t, func(st *serverTester) {
831 st.writeHeaders(HeadersFrameParam{
832 StreamID: 1,
833 BlockFragment: st.encodeHeader(
834 ":method", "POST",
835 "content-length", "3",
836 ),
837 EndStream: true,
838 EndHeaders: true,
839 })
840 })
841 }
842
843 func TestServer_Request_Post_Body_ContentLength_TooSmall(t *testing.T) {
844 synctest.Test(t, testServer_Request_Post_Body_ContentLength_TooSmall)
845 }
846 func testServer_Request_Post_Body_ContentLength_TooSmall(t *testing.T) {
847 testBodyContentsFail(t, 4, "sender tried to send more than declared Content-Length of 4 bytes",
848 func(st *serverTester) {
849 st.writeHeaders(HeadersFrameParam{
850 StreamID: 1,
851 BlockFragment: st.encodeHeader(
852 ":method", "POST",
853 "content-length", "4",
854 ),
855 EndStream: false,
856 EndHeaders: true,
857 })
858 st.writeData(1, true, []byte("12345"))
859
860
861 st.wantRSTStream(1, ErrCodeProtocol)
862 st.wantConnFlowControlConsumed(0)
863 })
864 }
865
866 func testBodyContents(t *testing.T, wantContentLength int64, wantBody string, write func(st *serverTester)) {
867 testServerRequest(t, write, func(r *http.Request) {
868 if r.Method != "POST" {
869 t.Errorf("Method = %q; want POST", r.Method)
870 }
871 if r.ContentLength != wantContentLength {
872 t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength)
873 }
874 all, err := io.ReadAll(r.Body)
875 if err != nil {
876 t.Fatal(err)
877 }
878 if string(all) != wantBody {
879 t.Errorf("Read = %q; want %q", all, wantBody)
880 }
881 if err := r.Body.Close(); err != nil {
882 t.Fatalf("Close: %v", err)
883 }
884 })
885 }
886
887 func testBodyContentsFail(t *testing.T, wantContentLength int64, wantReadError string, write func(st *serverTester)) {
888 testServerRequest(t, write, func(r *http.Request) {
889 if r.Method != "POST" {
890 t.Errorf("Method = %q; want POST", r.Method)
891 }
892 if r.ContentLength != wantContentLength {
893 t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength)
894 }
895 all, err := io.ReadAll(r.Body)
896 if err == nil {
897 t.Fatalf("expected an error (%q) reading from the body. Successfully read %q instead.",
898 wantReadError, all)
899 }
900 if !strings.Contains(err.Error(), wantReadError) {
901 t.Fatalf("Body.Read = %v; want substring %q", err, wantReadError)
902 }
903 if err := r.Body.Close(); err != nil {
904 t.Fatalf("Close: %v", err)
905 }
906 })
907 }
908
909
910 func TestServer_Request_Get_Host(t *testing.T) { synctest.Test(t, testServer_Request_Get_Host) }
911 func testServer_Request_Get_Host(t *testing.T) {
912 const host = "example.com"
913 testServerRequest(t, func(st *serverTester) {
914 st.writeHeaders(HeadersFrameParam{
915 StreamID: 1,
916 BlockFragment: st.encodeHeader(":authority", "", "host", host),
917 EndStream: true,
918 EndHeaders: true,
919 })
920 }, func(r *http.Request) {
921 if r.Host != host {
922 t.Errorf("Host = %q; want %q", r.Host, host)
923 }
924 })
925 }
926
927
928 func TestServer_Request_Get_Authority(t *testing.T) {
929 synctest.Test(t, testServer_Request_Get_Authority)
930 }
931 func testServer_Request_Get_Authority(t *testing.T) {
932 const host = "example.com"
933 testServerRequest(t, func(st *serverTester) {
934 st.writeHeaders(HeadersFrameParam{
935 StreamID: 1,
936 BlockFragment: st.encodeHeader(":authority", host),
937 EndStream: true,
938 EndHeaders: true,
939 })
940 }, func(r *http.Request) {
941 if r.Host != host {
942 t.Errorf("Host = %q; want %q", r.Host, host)
943 }
944 })
945 }
946
947 func TestServer_Request_WithContinuation(t *testing.T) {
948 synctest.Test(t, testServer_Request_WithContinuation)
949 }
950 func testServer_Request_WithContinuation(t *testing.T) {
951 wantHeader := http.Header{
952 "Foo-One": []string{"value-one"},
953 "Foo-Two": []string{"value-two"},
954 "Foo-Three": []string{"value-three"},
955 }
956 testServerRequest(t, func(st *serverTester) {
957 fullHeaders := st.encodeHeader(
958 "foo-one", "value-one",
959 "foo-two", "value-two",
960 "foo-three", "value-three",
961 )
962 remain := fullHeaders
963 chunks := 0
964 for len(remain) > 0 {
965 const maxChunkSize = 5
966 chunk := remain
967 if len(chunk) > maxChunkSize {
968 chunk = chunk[:maxChunkSize]
969 }
970 remain = remain[len(chunk):]
971
972 if chunks == 0 {
973 st.writeHeaders(HeadersFrameParam{
974 StreamID: 1,
975 BlockFragment: chunk,
976 EndStream: true,
977 EndHeaders: false,
978 })
979 } else {
980 err := st.fr.WriteContinuation(1, len(remain) == 0, chunk)
981 if err != nil {
982 t.Fatal(err)
983 }
984 }
985 chunks++
986 }
987 if chunks < 2 {
988 t.Fatal("too few chunks")
989 }
990 }, func(r *http.Request) {
991 if !reflect.DeepEqual(r.Header, wantHeader) {
992 t.Errorf("Header = %#v; want %#v", r.Header, wantHeader)
993 }
994 })
995 }
996
997
998 func TestServer_Request_CookieConcat(t *testing.T) { synctest.Test(t, testServer_Request_CookieConcat) }
999 func testServer_Request_CookieConcat(t *testing.T) {
1000 const host = "example.com"
1001 testServerRequest(t, func(st *serverTester) {
1002 st.bodylessReq1(
1003 ":authority", host,
1004 "cookie", "a=b",
1005 "cookie", "c=d",
1006 "cookie", "e=f",
1007 )
1008 }, func(r *http.Request) {
1009 const want = "a=b; c=d; e=f"
1010 if got := r.Header.Get("Cookie"); got != want {
1011 t.Errorf("Cookie = %q; want %q", got, want)
1012 }
1013 })
1014 }
1015
1016 func TestServer_Request_Reject_CapitalHeader(t *testing.T) {
1017 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("UPPER", "v") })
1018 }
1019
1020 func TestServer_Request_Reject_HeaderFieldNameColon(t *testing.T) {
1021 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("has:colon", "v") })
1022 }
1023
1024 func TestServer_Request_Reject_HeaderFieldNameNULL(t *testing.T) {
1025 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("has\x00null", "v") })
1026 }
1027
1028 func TestServer_Request_Reject_HeaderFieldNameEmpty(t *testing.T) {
1029 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("", "v") })
1030 }
1031
1032 func TestServer_Request_Reject_HeaderFieldValueNewline(t *testing.T) {
1033 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\nnewline") })
1034 }
1035
1036 func TestServer_Request_Reject_HeaderFieldValueCR(t *testing.T) {
1037 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\rcarriage") })
1038 }
1039
1040 func TestServer_Request_Reject_HeaderFieldValueDEL(t *testing.T) {
1041 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\x7fdel") })
1042 }
1043
1044 func TestServer_Request_Reject_Pseudo_Missing_method(t *testing.T) {
1045 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":method", "") })
1046 }
1047
1048 func TestServer_Request_Reject_Pseudo_ExactlyOne(t *testing.T) {
1049
1050
1051 testRejectRequest(t, func(st *serverTester) {
1052 st.addLogFilter("duplicate pseudo-header")
1053 st.bodylessReq1(":method", "GET", ":method", "POST")
1054 })
1055 }
1056
1057 func TestServer_Request_Reject_Pseudo_AfterRegular(t *testing.T) {
1058
1059
1060
1061
1062
1063
1064 testRejectRequest(t, func(st *serverTester) {
1065 st.addLogFilter("pseudo-header after regular header")
1066 var buf bytes.Buffer
1067 enc := hpack.NewEncoder(&buf)
1068 enc.WriteField(hpack.HeaderField{Name: ":method", Value: "GET"})
1069 enc.WriteField(hpack.HeaderField{Name: "regular", Value: "foobar"})
1070 enc.WriteField(hpack.HeaderField{Name: ":path", Value: "/"})
1071 enc.WriteField(hpack.HeaderField{Name: ":scheme", Value: "https"})
1072 st.writeHeaders(HeadersFrameParam{
1073 StreamID: 1,
1074 BlockFragment: buf.Bytes(),
1075 EndStream: true,
1076 EndHeaders: true,
1077 })
1078 })
1079 }
1080
1081 func TestServer_Request_Reject_Pseudo_Missing_path(t *testing.T) {
1082 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":path", "") })
1083 }
1084
1085 func TestServer_Request_Reject_Pseudo_Missing_scheme(t *testing.T) {
1086 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "") })
1087 }
1088
1089 func TestServer_Request_Reject_Pseudo_scheme_invalid(t *testing.T) {
1090 testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "bogus") })
1091 }
1092
1093 func TestServer_Request_Reject_Pseudo_Unknown(t *testing.T) {
1094 testRejectRequest(t, func(st *serverTester) {
1095 st.addLogFilter(`invalid pseudo-header ":unknown_thing"`)
1096 st.bodylessReq1(":unknown_thing", "")
1097 })
1098 }
1099
1100 func TestServer_Request_Reject_Authority_Userinfo(t *testing.T) {
1101
1102
1103
1104 testRejectRequest(t, func(st *serverTester) {
1105 var buf bytes.Buffer
1106 enc := hpack.NewEncoder(&buf)
1107 enc.WriteField(hpack.HeaderField{Name: ":authority", Value: "userinfo@example.tld"})
1108 enc.WriteField(hpack.HeaderField{Name: ":method", Value: "GET"})
1109 enc.WriteField(hpack.HeaderField{Name: ":path", Value: "/"})
1110 enc.WriteField(hpack.HeaderField{Name: ":scheme", Value: "https"})
1111 st.writeHeaders(HeadersFrameParam{
1112 StreamID: 1,
1113 BlockFragment: buf.Bytes(),
1114 EndStream: true,
1115 EndHeaders: true,
1116 })
1117 })
1118 }
1119
1120 func testRejectRequest(t *testing.T, send func(*serverTester)) {
1121 synctest.Test(t, func(t *testing.T) {
1122 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1123 t.Error("server request made it to handler; should've been rejected")
1124 })
1125 defer st.Close()
1126
1127 st.greet()
1128 send(st)
1129 st.wantRSTStream(1, ErrCodeProtocol)
1130 })
1131 }
1132
1133 func newServerTesterForError(t *testing.T) *serverTester {
1134 t.Helper()
1135 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1136 t.Error("server request made it to handler; should've been rejected")
1137 }, optQuiet)
1138 st.greet()
1139 return st
1140 }
1141
1142
1143
1144
1145 func TestRejectFrameOnIdle_WindowUpdate(t *testing.T) {
1146 synctest.Test(t, testRejectFrameOnIdle_WindowUpdate)
1147 }
1148 func testRejectFrameOnIdle_WindowUpdate(t *testing.T) {
1149 st := newServerTesterForError(t)
1150 st.fr.WriteWindowUpdate(123, 456)
1151 st.wantGoAway(123, ErrCodeProtocol)
1152 }
1153 func TestRejectFrameOnIdle_Data(t *testing.T) { synctest.Test(t, testRejectFrameOnIdle_Data) }
1154 func testRejectFrameOnIdle_Data(t *testing.T) {
1155 st := newServerTesterForError(t)
1156 st.fr.WriteData(123, true, nil)
1157 st.wantGoAway(123, ErrCodeProtocol)
1158 }
1159 func TestRejectFrameOnIdle_RSTStream(t *testing.T) { synctest.Test(t, testRejectFrameOnIdle_RSTStream) }
1160 func testRejectFrameOnIdle_RSTStream(t *testing.T) {
1161 st := newServerTesterForError(t)
1162 st.fr.WriteRSTStream(123, ErrCodeCancel)
1163 st.wantGoAway(123, ErrCodeProtocol)
1164 }
1165
1166 func TestServer_Request_Connect(t *testing.T) { synctest.Test(t, testServer_Request_Connect) }
1167 func testServer_Request_Connect(t *testing.T) {
1168 testServerRequest(t, func(st *serverTester) {
1169 st.writeHeaders(HeadersFrameParam{
1170 StreamID: 1,
1171 BlockFragment: st.encodeHeaderRaw(
1172 ":method", "CONNECT",
1173 ":authority", "example.com:123",
1174 ),
1175 EndStream: true,
1176 EndHeaders: true,
1177 })
1178 }, func(r *http.Request) {
1179 if g, w := r.Method, "CONNECT"; g != w {
1180 t.Errorf("Method = %q; want %q", g, w)
1181 }
1182 if g, w := r.RequestURI, "example.com:123"; g != w {
1183 t.Errorf("RequestURI = %q; want %q", g, w)
1184 }
1185 if g, w := r.URL.Host, "example.com:123"; g != w {
1186 t.Errorf("URL.Host = %q; want %q", g, w)
1187 }
1188 })
1189 }
1190
1191 func TestServer_Request_Connect_InvalidPath(t *testing.T) {
1192 synctest.Test(t, testServer_Request_Connect_InvalidPath)
1193 }
1194 func testServer_Request_Connect_InvalidPath(t *testing.T) {
1195 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
1196 st.writeHeaders(HeadersFrameParam{
1197 StreamID: 1,
1198 BlockFragment: st.encodeHeaderRaw(
1199 ":method", "CONNECT",
1200 ":authority", "example.com:123",
1201 ":path", "/bogus",
1202 ),
1203 EndStream: true,
1204 EndHeaders: true,
1205 })
1206 })
1207 }
1208
1209 func TestServer_Request_Connect_InvalidScheme(t *testing.T) {
1210 synctest.Test(t, testServer_Request_Connect_InvalidScheme)
1211 }
1212 func testServer_Request_Connect_InvalidScheme(t *testing.T) {
1213 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
1214 st.writeHeaders(HeadersFrameParam{
1215 StreamID: 1,
1216 BlockFragment: st.encodeHeaderRaw(
1217 ":method", "CONNECT",
1218 ":authority", "example.com:123",
1219 ":scheme", "https",
1220 ),
1221 EndStream: true,
1222 EndHeaders: true,
1223 })
1224 })
1225 }
1226
1227 func TestServer_Ping(t *testing.T) { synctest.Test(t, testServer_Ping) }
1228 func testServer_Ping(t *testing.T) {
1229 st := newServerTester(t, nil)
1230 defer st.Close()
1231 st.greet()
1232
1233
1234 ackPingData := [8]byte{1, 2, 4, 8, 16, 32, 64, 128}
1235 if err := st.fr.WritePing(true, ackPingData); err != nil {
1236 t.Fatal(err)
1237 }
1238
1239
1240 pingData := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
1241 if err := st.fr.WritePing(false, pingData); err != nil {
1242 t.Fatal(err)
1243 }
1244
1245 pf := readFrame[*PingFrame](t, st)
1246 if !pf.Flags.Has(FlagPingAck) {
1247 t.Error("response ping doesn't have ACK set")
1248 }
1249 if pf.Data != pingData {
1250 t.Errorf("response ping has data %q; want %q", pf.Data, pingData)
1251 }
1252 }
1253
1254 type filterListener struct {
1255 net.Listener
1256 accept func(conn net.Conn) (net.Conn, error)
1257 }
1258
1259 func (l *filterListener) Accept() (net.Conn, error) {
1260 c, err := l.Listener.Accept()
1261 if err != nil {
1262 return nil, err
1263 }
1264 return l.accept(c)
1265 }
1266
1267 func TestServer_MaxQueuedControlFrames(t *testing.T) {
1268 synctest.Test(t, testServer_MaxQueuedControlFrames)
1269 }
1270 func testServer_MaxQueuedControlFrames(t *testing.T) {
1271
1272 DisableGoroutineTracking(t)
1273
1274 st := newServerTester(t, nil)
1275 st.greet()
1276
1277 st.cc.(*tls.Conn).NetConn().(*synctestNetConn).SetReadBufferSize(0)
1278
1279
1280
1281 const extraPings = 2
1282 for range MaxQueuedControlFrames + extraPings {
1283 pingData := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
1284 st.fr.WritePing(false, pingData)
1285 }
1286 synctest.Wait()
1287
1288
1289
1290 st.cc.(*tls.Conn).NetConn().(*synctestNetConn).SetReadBufferSize(math.MaxInt)
1291
1292 st.advance(GoAwayTimeout)
1293
1294 for range 10 {
1295 if st.readFrame() == nil {
1296 break
1297 }
1298 }
1299 st.wantClosed()
1300 }
1301
1302 func TestServer_RejectsLargeFrames(t *testing.T) { synctest.Test(t, testServer_RejectsLargeFrames) }
1303 func testServer_RejectsLargeFrames(t *testing.T) {
1304 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" || runtime.GOOS == "zos" {
1305 t.Skip("see golang.org/issue/13434, golang.org/issue/37321")
1306 }
1307 st := newServerTester(t, nil)
1308 defer st.Close()
1309 st.greet()
1310
1311
1312
1313
1314 st.fr.WriteRawFrame(0xff, 0, 0, make([]byte, DefaultMaxReadFrameSize+1))
1315
1316 st.wantGoAway(0, ErrCodeFrameSize)
1317 st.advance(GoAwayTimeout)
1318 st.wantClosed()
1319 }
1320
1321 func TestServer_Handler_Sends_WindowUpdate(t *testing.T) {
1322 synctest.Test(t, testServer_Handler_Sends_WindowUpdate)
1323 }
1324 func testServer_Handler_Sends_WindowUpdate(t *testing.T) {
1325
1326
1327
1328
1329 const windowSize = 65535 * 2
1330 st := newServerTester(t, nil, func(h2 *http.HTTP2Config) {
1331 h2.MaxReceiveBufferPerConnection = windowSize
1332 h2.MaxReceiveBufferPerStream = windowSize
1333 })
1334 defer st.Close()
1335
1336 st.greet()
1337 st.writeHeaders(HeadersFrameParam{
1338 StreamID: 1,
1339 BlockFragment: st.encodeHeader(":method", "POST"),
1340 EndStream: false,
1341 EndHeaders: true,
1342 })
1343 call := st.nextHandlerCall()
1344
1345
1346
1347
1348 data := make([]byte, windowSize)
1349 st.writeData(1, false, data[:1024])
1350 call.do(readBodyHandler(t, string(data[:1024])))
1351
1352
1353
1354 st.writeData(1, false, data[1024:])
1355 st.wantWindowUpdate(0, 1024)
1356 st.wantWindowUpdate(1, 1024)
1357
1358
1359 call.do(readBodyHandler(t, string(data[1024:])))
1360 st.wantWindowUpdate(0, windowSize-1024)
1361 st.wantWindowUpdate(1, windowSize-1024)
1362 }
1363
1364
1365
1366 func TestServer_Handler_Sends_WindowUpdate_Padding(t *testing.T) {
1367 synctest.Test(t, testServer_Handler_Sends_WindowUpdate_Padding)
1368 }
1369 func testServer_Handler_Sends_WindowUpdate_Padding(t *testing.T) {
1370 const windowSize = 65535 * 2
1371 st := newServerTester(t, nil, func(h2 *http.HTTP2Config) {
1372 h2.MaxReceiveBufferPerConnection = windowSize
1373 h2.MaxReceiveBufferPerStream = windowSize
1374 })
1375 defer st.Close()
1376
1377 st.greet()
1378 st.writeHeaders(HeadersFrameParam{
1379 StreamID: 1,
1380 BlockFragment: st.encodeHeader(":method", "POST"),
1381 EndStream: false,
1382 EndHeaders: true,
1383 })
1384 call := st.nextHandlerCall()
1385
1386
1387
1388
1389 data := make([]byte, windowSize/2)
1390 pad := make([]byte, 4)
1391 st.writeDataPadded(1, false, data, pad)
1392
1393
1394
1395
1396 call.do(readBodyHandler(t, string(data)))
1397 st.wantWindowUpdate(0, uint32(len(data)+1+len(pad)))
1398 st.wantWindowUpdate(1, uint32(len(data)+1+len(pad)))
1399 }
1400
1401 func TestServer_Send_GoAway_After_Bogus_WindowUpdate(t *testing.T) {
1402 synctest.Test(t, testServer_Send_GoAway_After_Bogus_WindowUpdate)
1403 }
1404 func testServer_Send_GoAway_After_Bogus_WindowUpdate(t *testing.T) {
1405 st := newServerTester(t, nil)
1406 defer st.Close()
1407 st.greet()
1408 if err := st.fr.WriteWindowUpdate(0, 1<<31-1); err != nil {
1409 t.Fatal(err)
1410 }
1411 st.wantGoAway(0, ErrCodeFlowControl)
1412 }
1413
1414 func TestServer_Send_RstStream_After_Bogus_WindowUpdate(t *testing.T) {
1415 synctest.Test(t, testServer_Send_RstStream_After_Bogus_WindowUpdate)
1416 }
1417 func testServer_Send_RstStream_After_Bogus_WindowUpdate(t *testing.T) {
1418 inHandler := make(chan bool)
1419 blockHandler := make(chan bool)
1420 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1421 inHandler <- true
1422 <-blockHandler
1423 })
1424 defer st.Close()
1425 defer close(blockHandler)
1426 st.greet()
1427 st.writeHeaders(HeadersFrameParam{
1428 StreamID: 1,
1429 BlockFragment: st.encodeHeader(":method", "POST"),
1430 EndStream: false,
1431 EndHeaders: true,
1432 })
1433 <-inHandler
1434
1435 if err := st.fr.WriteWindowUpdate(1, 1<<31-1); err != nil {
1436 t.Fatal(err)
1437 }
1438 st.wantRSTStream(1, ErrCodeFlowControl)
1439
1440 st.writePing(false, [8]byte{})
1441 st.wantFrameType(FramePing)
1442 }
1443
1444
1445
1446
1447 func testServerPostUnblock(t *testing.T,
1448 handler func(http.ResponseWriter, *http.Request) error,
1449 fn func(*serverTester),
1450 checkErr func(error),
1451 otherHeaders ...string) {
1452 inHandler := make(chan bool)
1453 errc := make(chan error, 1)
1454 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1455 inHandler <- true
1456 errc <- handler(w, r)
1457 })
1458 defer st.Close()
1459 st.greet()
1460 st.writeHeaders(HeadersFrameParam{
1461 StreamID: 1,
1462 BlockFragment: st.encodeHeader(append([]string{":method", "POST"}, otherHeaders...)...),
1463 EndStream: false,
1464 EndHeaders: true,
1465 })
1466 <-inHandler
1467 fn(st)
1468 err := <-errc
1469 if checkErr != nil {
1470 checkErr(err)
1471 }
1472 }
1473
1474 func TestServer_RSTStream_Unblocks_Read(t *testing.T) {
1475 synctest.Test(t, testServer_RSTStream_Unblocks_Read)
1476 }
1477 func testServer_RSTStream_Unblocks_Read(t *testing.T) {
1478 testServerPostUnblock(t,
1479 func(w http.ResponseWriter, r *http.Request) (err error) {
1480 _, err = r.Body.Read(make([]byte, 1))
1481 return
1482 },
1483 func(st *serverTester) {
1484 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
1485 t.Fatal(err)
1486 }
1487 },
1488 func(err error) {
1489 want := StreamError{StreamID: 0x1, Code: 0x8}
1490 if !reflect.DeepEqual(err, want) {
1491 t.Errorf("Read error = %v; want %v", err, want)
1492 }
1493 },
1494 )
1495 }
1496
1497 func TestServer_RSTStream_Unblocks_Header_Write(t *testing.T) {
1498
1499
1500 n := 50
1501 if testing.Short() {
1502 n = 5
1503 }
1504 for i := 0; i < n; i++ {
1505 synctest.Test(t, testServer_RSTStream_Unblocks_Header_Write)
1506 }
1507 }
1508
1509 func testServer_RSTStream_Unblocks_Header_Write(t *testing.T) {
1510 inHandler := make(chan bool, 1)
1511 unblockHandler := make(chan bool, 1)
1512 headerWritten := make(chan bool, 1)
1513 wroteRST := make(chan bool, 1)
1514
1515 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1516 inHandler <- true
1517 <-wroteRST
1518 w.Header().Set("foo", "bar")
1519 w.WriteHeader(200)
1520 w.(http.Flusher).Flush()
1521 headerWritten <- true
1522 <-unblockHandler
1523 })
1524 defer st.Close()
1525
1526 st.greet()
1527 st.writeHeaders(HeadersFrameParam{
1528 StreamID: 1,
1529 BlockFragment: st.encodeHeader(":method", "POST"),
1530 EndStream: false,
1531 EndHeaders: true,
1532 })
1533 <-inHandler
1534 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
1535 t.Fatal(err)
1536 }
1537 wroteRST <- true
1538 synctest.Wait()
1539 <-headerWritten
1540 unblockHandler <- true
1541 }
1542
1543 func TestServer_DeadConn_Unblocks_Read(t *testing.T) {
1544 synctest.Test(t, testServer_DeadConn_Unblocks_Read)
1545 }
1546 func testServer_DeadConn_Unblocks_Read(t *testing.T) {
1547 testServerPostUnblock(t,
1548 func(w http.ResponseWriter, r *http.Request) (err error) {
1549 _, err = r.Body.Read(make([]byte, 1))
1550 return
1551 },
1552 func(st *serverTester) { st.cc.Close() },
1553 func(err error) {
1554 if err == nil {
1555 t.Error("unexpected nil error from Request.Body.Read")
1556 }
1557 },
1558 )
1559 }
1560
1561 var blockUntilClosed = func(w http.ResponseWriter, r *http.Request) error {
1562 <-w.(http.CloseNotifier).CloseNotify()
1563 return nil
1564 }
1565
1566 func TestServer_CloseNotify_After_RSTStream(t *testing.T) {
1567 synctest.Test(t, testServer_CloseNotify_After_RSTStream)
1568 }
1569 func testServer_CloseNotify_After_RSTStream(t *testing.T) {
1570 testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) {
1571 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
1572 t.Fatal(err)
1573 }
1574 }, nil)
1575 }
1576
1577 func TestServer_CloseNotify_After_ConnClose(t *testing.T) {
1578 synctest.Test(t, testServer_CloseNotify_After_ConnClose)
1579 }
1580 func testServer_CloseNotify_After_ConnClose(t *testing.T) {
1581 testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) { st.cc.Close() }, nil)
1582 }
1583
1584
1585
1586
1587 func TestServer_CloseNotify_After_StreamError(t *testing.T) {
1588 synctest.Test(t, testServer_CloseNotify_After_StreamError)
1589 }
1590 func testServer_CloseNotify_After_StreamError(t *testing.T) {
1591 testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) {
1592
1593 st.writeData(1, true, []byte("1234"))
1594 }, nil, "content-length", "3")
1595 }
1596
1597 func TestServer_StateTransitions(t *testing.T) { synctest.Test(t, testServer_StateTransitions) }
1598 func testServer_StateTransitions(t *testing.T) {
1599 var st *serverTester
1600 inHandler := make(chan bool)
1601 writeData := make(chan bool)
1602 leaveHandler := make(chan bool)
1603 st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1604 inHandler <- true
1605 if !st.streamExists(1) {
1606 t.Errorf("stream 1 does not exist in handler")
1607 }
1608 if got, want := st.streamState(1), StateOpen; got != want {
1609 t.Errorf("in handler, state is %v; want %v", got, want)
1610 }
1611 writeData <- true
1612 if n, err := r.Body.Read(make([]byte, 1)); n != 0 || err != io.EOF {
1613 t.Errorf("body read = %d, %v; want 0, EOF", n, err)
1614 }
1615 if got, want := st.streamState(1), StateHalfClosedRemote; got != want {
1616 t.Errorf("in handler, state is %v; want %v", got, want)
1617 }
1618
1619 <-leaveHandler
1620 })
1621 st.greet()
1622 if st.streamExists(1) {
1623 t.Fatal("stream 1 should be empty")
1624 }
1625 if got := st.streamState(1); got != StateIdle {
1626 t.Fatalf("stream 1 should be idle; got %v", got)
1627 }
1628
1629 st.writeHeaders(HeadersFrameParam{
1630 StreamID: 1,
1631 BlockFragment: st.encodeHeader(":method", "POST"),
1632 EndStream: false,
1633 EndHeaders: true,
1634 })
1635 <-inHandler
1636 <-writeData
1637 st.writeData(1, true, nil)
1638
1639 leaveHandler <- true
1640 st.wantHeaders(wantHeader{
1641 streamID: 1,
1642 endStream: true,
1643 })
1644
1645 if got, want := st.streamState(1), StateClosed; got != want {
1646 t.Errorf("at end, state is %v; want %v", got, want)
1647 }
1648 if st.streamExists(1) {
1649 t.Fatal("at end, stream 1 should be gone")
1650 }
1651 }
1652
1653
1654 func TestServer_Rejects_HeadersNoEnd_Then_Headers(t *testing.T) {
1655 synctest.Test(t, testServer_Rejects_HeadersNoEnd_Then_Headers)
1656 }
1657 func testServer_Rejects_HeadersNoEnd_Then_Headers(t *testing.T) {
1658 st := newServerTesterForError(t)
1659 st.writeHeaders(HeadersFrameParam{
1660 StreamID: 1,
1661 BlockFragment: st.encodeHeader(),
1662 EndStream: true,
1663 EndHeaders: false,
1664 })
1665 st.writeHeaders(HeadersFrameParam{
1666 StreamID: 3,
1667 BlockFragment: st.encodeHeader(),
1668 EndStream: true,
1669 EndHeaders: true,
1670 })
1671 st.wantGoAway(0, ErrCodeProtocol)
1672 }
1673
1674
1675 func TestServer_Rejects_HeadersNoEnd_Then_Ping(t *testing.T) {
1676 synctest.Test(t, testServer_Rejects_HeadersNoEnd_Then_Ping)
1677 }
1678 func testServer_Rejects_HeadersNoEnd_Then_Ping(t *testing.T) {
1679 st := newServerTesterForError(t)
1680 st.writeHeaders(HeadersFrameParam{
1681 StreamID: 1,
1682 BlockFragment: st.encodeHeader(),
1683 EndStream: true,
1684 EndHeaders: false,
1685 })
1686 if err := st.fr.WritePing(false, [8]byte{}); err != nil {
1687 t.Fatal(err)
1688 }
1689 st.wantGoAway(0, ErrCodeProtocol)
1690 }
1691
1692
1693 func TestServer_Rejects_HeadersEnd_Then_Continuation(t *testing.T) {
1694 synctest.Test(t, testServer_Rejects_HeadersEnd_Then_Continuation)
1695 }
1696 func testServer_Rejects_HeadersEnd_Then_Continuation(t *testing.T) {
1697 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}, optQuiet)
1698 st.greet()
1699 st.writeHeaders(HeadersFrameParam{
1700 StreamID: 1,
1701 BlockFragment: st.encodeHeader(),
1702 EndStream: true,
1703 EndHeaders: true,
1704 })
1705 st.wantHeaders(wantHeader{
1706 streamID: 1,
1707 endStream: true,
1708 })
1709 if err := st.fr.WriteContinuation(1, true, EncodeHeaderRaw(t, "foo", "bar")); err != nil {
1710 t.Fatal(err)
1711 }
1712 st.wantGoAway(1, ErrCodeProtocol)
1713 }
1714
1715
1716 func TestServer_Rejects_HeadersNoEnd_Then_ContinuationWrongStream(t *testing.T) {
1717 synctest.Test(t, testServer_Rejects_HeadersNoEnd_Then_ContinuationWrongStream)
1718 }
1719 func testServer_Rejects_HeadersNoEnd_Then_ContinuationWrongStream(t *testing.T) {
1720 st := newServerTesterForError(t)
1721 st.writeHeaders(HeadersFrameParam{
1722 StreamID: 1,
1723 BlockFragment: st.encodeHeader(),
1724 EndStream: true,
1725 EndHeaders: false,
1726 })
1727 if err := st.fr.WriteContinuation(3, true, EncodeHeaderRaw(t, "foo", "bar")); err != nil {
1728 t.Fatal(err)
1729 }
1730 st.wantGoAway(0, ErrCodeProtocol)
1731 }
1732
1733
1734 func TestServer_Rejects_Headers0(t *testing.T) { synctest.Test(t, testServer_Rejects_Headers0) }
1735 func testServer_Rejects_Headers0(t *testing.T) {
1736 st := newServerTesterForError(t)
1737 st.fr.AllowIllegalWrites = true
1738 st.writeHeaders(HeadersFrameParam{
1739 StreamID: 0,
1740 BlockFragment: st.encodeHeader(),
1741 EndStream: true,
1742 EndHeaders: true,
1743 })
1744 st.wantGoAway(0, ErrCodeProtocol)
1745 }
1746
1747
1748 func TestServer_Rejects_Continuation0(t *testing.T) {
1749 synctest.Test(t, testServer_Rejects_Continuation0)
1750 }
1751 func testServer_Rejects_Continuation0(t *testing.T) {
1752 st := newServerTesterForError(t)
1753 st.fr.AllowIllegalWrites = true
1754 if err := st.fr.WriteContinuation(0, true, st.encodeHeader()); err != nil {
1755 t.Fatal(err)
1756 }
1757 st.wantGoAway(0, ErrCodeProtocol)
1758 }
1759
1760
1761 func TestServer_Rejects_Priority0(t *testing.T) { synctest.Test(t, testServer_Rejects_Priority0) }
1762 func testServer_Rejects_Priority0(t *testing.T) {
1763 st := newServerTesterForError(t)
1764 st.fr.AllowIllegalWrites = true
1765 st.writePriority(0, PriorityParam{StreamDep: 1})
1766 st.wantGoAway(0, ErrCodeProtocol)
1767 }
1768
1769
1770
1771 func TestServer_Rejects_PriorityUpdate0(t *testing.T) {
1772 synctest.Test(t, testServer_Rejects_PriorityUpdate0)
1773 }
1774 func testServer_Rejects_PriorityUpdate0(t *testing.T) {
1775 st := newServerTesterForError(t)
1776 st.fr.AllowIllegalWrites = true
1777 st.writePriorityUpdate(0, "")
1778 st.wantGoAway(0, ErrCodeProtocol)
1779 }
1780
1781
1782 func TestServer_Rejects_PriorityUpdateUnparsable(t *testing.T) {
1783 synctest.Test(t, testServer_Rejects_PriorityUnparsable)
1784 }
1785 func testServer_Rejects_PriorityUnparsable(t *testing.T) {
1786 st := newServerTester(t, nil)
1787 defer st.Close()
1788 st.greet()
1789 st.writePriorityUpdate(1, "Invalid dictionary: ((((")
1790 st.wantRSTStream(1, ErrCodeProtocol)
1791 }
1792
1793
1794 func TestServer_Rejects_HeadersSelfDependence(t *testing.T) {
1795 synctest.Test(t, testServer_Rejects_HeadersSelfDependence)
1796 }
1797 func testServer_Rejects_HeadersSelfDependence(t *testing.T) {
1798 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
1799 st.fr.AllowIllegalWrites = true
1800 st.writeHeaders(HeadersFrameParam{
1801 StreamID: 1,
1802 BlockFragment: st.encodeHeader(),
1803 EndStream: true,
1804 EndHeaders: true,
1805 Priority: PriorityParam{StreamDep: 1},
1806 })
1807 })
1808 }
1809
1810
1811 func TestServer_Rejects_PrioritySelfDependence(t *testing.T) {
1812 synctest.Test(t, testServer_Rejects_PrioritySelfDependence)
1813 }
1814 func testServer_Rejects_PrioritySelfDependence(t *testing.T) {
1815 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
1816 st.fr.AllowIllegalWrites = true
1817 st.writePriority(1, PriorityParam{StreamDep: 1})
1818 })
1819 }
1820
1821 func TestServer_Rejects_PushPromise(t *testing.T) { synctest.Test(t, testServer_Rejects_PushPromise) }
1822 func testServer_Rejects_PushPromise(t *testing.T) {
1823 st := newServerTesterForError(t)
1824 pp := PushPromiseParam{
1825 StreamID: 1,
1826 PromiseID: 3,
1827 }
1828 if err := st.fr.WritePushPromise(pp); err != nil {
1829 t.Fatal(err)
1830 }
1831 st.wantGoAway(1, ErrCodeProtocol)
1832 }
1833
1834
1835
1836 func testServerRejectsStream(t *testing.T, code ErrCode, writeReq func(*serverTester)) {
1837 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {})
1838 defer st.Close()
1839 st.greet()
1840 writeReq(st)
1841 st.wantRSTStream(1, code)
1842 }
1843
1844
1845
1846
1847 func testServerRequest(t *testing.T, writeReq func(*serverTester), checkReq func(*http.Request)) {
1848 gotReq := make(chan bool, 1)
1849 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
1850 if r.Body == nil {
1851 t.Fatal("nil Body")
1852 }
1853 checkReq(r)
1854 gotReq <- true
1855 })
1856 defer st.Close()
1857
1858 st.greet()
1859 writeReq(st)
1860 <-gotReq
1861 }
1862
1863 func getSlash(st *serverTester) { st.bodylessReq1() }
1864
1865 func TestServer_Response_NoData(t *testing.T) { synctest.Test(t, testServer_Response_NoData) }
1866 func testServer_Response_NoData(t *testing.T) {
1867 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1868
1869 return nil
1870 }, func(st *serverTester) {
1871 getSlash(st)
1872 st.wantHeaders(wantHeader{
1873 streamID: 1,
1874 endStream: true,
1875 })
1876 })
1877 }
1878
1879 func TestServer_Response_NoData_Header_FooBar(t *testing.T) {
1880 synctest.Test(t, testServer_Response_NoData_Header_FooBar)
1881 }
1882 func testServer_Response_NoData_Header_FooBar(t *testing.T) {
1883 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1884 w.Header().Set("Foo-Bar", "some-value")
1885 return nil
1886 }, func(st *serverTester) {
1887 getSlash(st)
1888 st.wantHeaders(wantHeader{
1889 streamID: 1,
1890 endStream: true,
1891 header: http.Header{
1892 ":status": []string{"200"},
1893 "foo-bar": []string{"some-value"},
1894 "content-length": []string{"0"},
1895 },
1896 })
1897 })
1898 }
1899
1900
1901
1902 func TestServerIgnoresContentLengthSignWhenWritingChunks(t *testing.T) {
1903 synctest.Test(t, testServerIgnoresContentLengthSignWhenWritingChunks)
1904 }
1905 func testServerIgnoresContentLengthSignWhenWritingChunks(t *testing.T) {
1906 tests := []struct {
1907 name string
1908 cl string
1909 wantCL string
1910 }{
1911 {
1912 name: "proper content-length",
1913 cl: "3",
1914 wantCL: "3",
1915 },
1916 {
1917 name: "ignore cl with plus sign",
1918 cl: "+3",
1919 wantCL: "0",
1920 },
1921 {
1922 name: "ignore cl with minus sign",
1923 cl: "-3",
1924 wantCL: "0",
1925 },
1926 {
1927 name: "max int64, for safe uint64->int64 conversion",
1928 cl: "9223372036854775807",
1929 wantCL: "9223372036854775807",
1930 },
1931 {
1932 name: "overflows int64, so ignored",
1933 cl: "9223372036854775808",
1934 wantCL: "0",
1935 },
1936 }
1937
1938 for _, tt := range tests {
1939 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
1940 w.Header().Set("content-length", tt.cl)
1941 return nil
1942 }, func(st *serverTester) {
1943 getSlash(st)
1944 st.wantHeaders(wantHeader{
1945 streamID: 1,
1946 endStream: true,
1947 header: http.Header{
1948 ":status": []string{"200"},
1949 "content-length": []string{tt.wantCL},
1950 },
1951 })
1952 })
1953 }
1954 }
1955
1956
1957
1958 func TestServerRejectsContentLengthWithSignNewRequests(t *testing.T) {
1959 tests := []struct {
1960 name string
1961 cl string
1962 wantCL int64
1963 }{
1964 {
1965 name: "proper content-length",
1966 cl: "3",
1967 wantCL: 3,
1968 },
1969 {
1970 name: "ignore cl with plus sign",
1971 cl: "+3",
1972 wantCL: 0,
1973 },
1974 {
1975 name: "ignore cl with minus sign",
1976 cl: "-3",
1977 wantCL: 0,
1978 },
1979 {
1980 name: "max int64, for safe uint64->int64 conversion",
1981 cl: "9223372036854775807",
1982 wantCL: 9223372036854775807,
1983 },
1984 {
1985 name: "overflows int64, so ignored",
1986 cl: "9223372036854775808",
1987 wantCL: 0,
1988 },
1989 }
1990
1991 for _, tt := range tests {
1992 synctestSubtest(t, tt.name, func(t *testing.T) {
1993 writeReq := func(st *serverTester) {
1994 st.writeHeaders(HeadersFrameParam{
1995 StreamID: 1,
1996 BlockFragment: st.encodeHeader("content-length", tt.cl),
1997 EndStream: false,
1998 EndHeaders: true,
1999 })
2000 st.writeData(1, false, []byte(""))
2001 }
2002 checkReq := func(r *http.Request) {
2003 if r.ContentLength != tt.wantCL {
2004 t.Fatalf("Got: %d\nWant: %d", r.ContentLength, tt.wantCL)
2005 }
2006 }
2007 testServerRequest(t, writeReq, checkReq)
2008 })
2009 }
2010 }
2011
2012 func TestServerContentLengthDuplicates(t *testing.T) {
2013 tests := []struct {
2014 name string
2015 clValues []string
2016 wantOk bool
2017 }{
2018 {
2019 name: "single value",
2020 clValues: []string{"123"},
2021 wantOk: true,
2022 },
2023 {
2024 name: "identical duplicate values",
2025 clValues: []string{"123", "123", "123"},
2026 wantOk: true,
2027 },
2028 {
2029 name: "identical duplicate values with extra whitespace",
2030 clValues: []string{"123", " 123", "123"},
2031 wantOk: false,
2032 },
2033 {
2034 name: "different duplicate values",
2035 clValues: []string{"123", "321", "123"},
2036 wantOk: false,
2037 },
2038 }
2039 for _, tt := range tests {
2040 synctestSubtest(t, tt.name, func(t *testing.T) {
2041 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
2042 w.WriteHeader(200)
2043 })
2044 defer st.Close()
2045 st.greet()
2046
2047 headers := []string{":method", "GET"}
2048 for _, val := range tt.clValues {
2049 headers = append(headers, "content-length", val)
2050 }
2051 st.writeHeaders(HeadersFrameParam{
2052 StreamID: 1,
2053 BlockFragment: st.encodeHeader(headers...),
2054 EndStream: false,
2055 EndHeaders: true,
2056 })
2057 if tt.wantOk {
2058 st.wantHeaders(wantHeader{
2059 streamID: 1,
2060 endStream: true,
2061 header: http.Header{":status": []string{"200"}},
2062 })
2063 } else {
2064 st.wantRSTStream(1, ErrCodeProtocol)
2065 }
2066 })
2067 }
2068 }
2069
2070 func TestServer_Response_Data_Sniff_DoesntOverride(t *testing.T) {
2071 synctest.Test(t, testServer_Response_Data_Sniff_DoesntOverride)
2072 }
2073 func testServer_Response_Data_Sniff_DoesntOverride(t *testing.T) {
2074 const msg = "<html>this is HTML."
2075 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2076 w.Header().Set("Content-Type", "foo/bar")
2077 io.WriteString(w, msg)
2078 return nil
2079 }, func(st *serverTester) {
2080 getSlash(st)
2081 st.wantHeaders(wantHeader{
2082 streamID: 1,
2083 endStream: false,
2084 header: http.Header{
2085 ":status": []string{"200"},
2086 "content-type": []string{"foo/bar"},
2087 "content-length": []string{strconv.Itoa(len(msg))},
2088 },
2089 })
2090 st.wantData(wantData{
2091 streamID: 1,
2092 endStream: true,
2093 data: []byte(msg),
2094 })
2095 })
2096 }
2097
2098 func TestServer_Response_TransferEncoding_chunked(t *testing.T) {
2099 synctest.Test(t, testServer_Response_TransferEncoding_chunked)
2100 }
2101 func testServer_Response_TransferEncoding_chunked(t *testing.T) {
2102 const msg = "hi"
2103 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2104 w.Header().Set("Transfer-Encoding", "chunked")
2105 io.WriteString(w, msg)
2106 return nil
2107 }, func(st *serverTester) {
2108 getSlash(st)
2109 st.wantHeaders(wantHeader{
2110 streamID: 1,
2111 endStream: false,
2112 header: http.Header{
2113 ":status": []string{"200"},
2114 "content-type": []string{"text/plain; charset=utf-8"},
2115 "content-length": []string{strconv.Itoa(len(msg))},
2116 },
2117 })
2118 })
2119 }
2120
2121
2122 func TestServer_Response_Data_IgnoreHeaderAfterWrite_After(t *testing.T) {
2123 synctest.Test(t, testServer_Response_Data_IgnoreHeaderAfterWrite_After)
2124 }
2125 func testServer_Response_Data_IgnoreHeaderAfterWrite_After(t *testing.T) {
2126 const msg = "<html>this is HTML."
2127 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2128 io.WriteString(w, msg)
2129 w.Header().Set("foo", "should be ignored")
2130 return nil
2131 }, func(st *serverTester) {
2132 getSlash(st)
2133 st.wantHeaders(wantHeader{
2134 streamID: 1,
2135 endStream: false,
2136 header: http.Header{
2137 ":status": []string{"200"},
2138 "content-type": []string{"text/html; charset=utf-8"},
2139 "content-length": []string{strconv.Itoa(len(msg))},
2140 },
2141 })
2142 })
2143 }
2144
2145
2146 func TestServer_Response_Data_IgnoreHeaderAfterWrite_Overwrite(t *testing.T) {
2147 synctest.Test(t, testServer_Response_Data_IgnoreHeaderAfterWrite_Overwrite)
2148 }
2149 func testServer_Response_Data_IgnoreHeaderAfterWrite_Overwrite(t *testing.T) {
2150 const msg = "<html>this is HTML."
2151 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2152 w.Header().Set("foo", "proper value")
2153 io.WriteString(w, msg)
2154 w.Header().Set("foo", "should be ignored")
2155 return nil
2156 }, func(st *serverTester) {
2157 getSlash(st)
2158 st.wantHeaders(wantHeader{
2159 streamID: 1,
2160 endStream: false,
2161 header: http.Header{
2162 ":status": []string{"200"},
2163 "foo": []string{"proper value"},
2164 "content-type": []string{"text/html; charset=utf-8"},
2165 "content-length": []string{strconv.Itoa(len(msg))},
2166 },
2167 })
2168 })
2169 }
2170
2171 func TestServer_Response_Data_SniffLenType(t *testing.T) {
2172 synctest.Test(t, testServer_Response_Data_SniffLenType)
2173 }
2174 func testServer_Response_Data_SniffLenType(t *testing.T) {
2175 const msg = "<html>this is HTML."
2176 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2177 io.WriteString(w, msg)
2178 return nil
2179 }, func(st *serverTester) {
2180 getSlash(st)
2181 st.wantHeaders(wantHeader{
2182 streamID: 1,
2183 endStream: false,
2184 header: http.Header{
2185 ":status": []string{"200"},
2186 "content-type": []string{"text/html; charset=utf-8"},
2187 "content-length": []string{strconv.Itoa(len(msg))},
2188 },
2189 })
2190 st.wantData(wantData{
2191 streamID: 1,
2192 endStream: true,
2193 data: []byte(msg),
2194 })
2195 })
2196 }
2197
2198 func TestServer_Response_Header_Flush_MidWrite(t *testing.T) {
2199 synctest.Test(t, testServer_Response_Header_Flush_MidWrite)
2200 }
2201 func testServer_Response_Header_Flush_MidWrite(t *testing.T) {
2202 const msg = "<html>this is HTML"
2203 const msg2 = ", and this is the next chunk"
2204 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2205 io.WriteString(w, msg)
2206 w.(http.Flusher).Flush()
2207 io.WriteString(w, msg2)
2208 return nil
2209 }, func(st *serverTester) {
2210 getSlash(st)
2211 st.wantHeaders(wantHeader{
2212 streamID: 1,
2213 endStream: false,
2214 header: http.Header{
2215 ":status": []string{"200"},
2216 "content-type": []string{"text/html; charset=utf-8"},
2217
2218 },
2219 })
2220 st.wantData(wantData{
2221 streamID: 1,
2222 endStream: false,
2223 data: []byte(msg),
2224 })
2225 st.wantData(wantData{
2226 streamID: 1,
2227 endStream: true,
2228 data: []byte(msg2),
2229 })
2230 })
2231 }
2232
2233 func TestServer_Response_LargeWrite(t *testing.T) { synctest.Test(t, testServer_Response_LargeWrite) }
2234 func testServer_Response_LargeWrite(t *testing.T) {
2235 const size = 1 << 20
2236 const maxFrameSize = 16 << 10
2237 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2238 n, err := w.Write(bytes.Repeat([]byte("a"), size))
2239 if err != nil {
2240 return fmt.Errorf("Write error: %v", err)
2241 }
2242 if n != size {
2243 return fmt.Errorf("wrong size %d from Write", n)
2244 }
2245 return nil
2246 }, func(st *serverTester) {
2247 if err := st.fr.WriteSettings(
2248 Setting{SettingInitialWindowSize, 0},
2249 Setting{SettingMaxFrameSize, maxFrameSize},
2250 ); err != nil {
2251 t.Fatal(err)
2252 }
2253 st.wantSettingsAck()
2254
2255 getSlash(st)
2256
2257
2258 if err := st.fr.WriteWindowUpdate(1, size); err != nil {
2259 t.Fatal(err)
2260 }
2261
2262
2263 if err := st.fr.WriteWindowUpdate(0, size); err != nil {
2264 t.Fatal(err)
2265 }
2266 st.wantHeaders(wantHeader{
2267 streamID: 1,
2268 endStream: false,
2269 header: http.Header{
2270 ":status": []string{"200"},
2271 "content-type": []string{"text/plain; charset=utf-8"},
2272
2273 },
2274 })
2275 var bytes, frames int
2276 for {
2277 df := readFrame[*DataFrame](t, st)
2278 bytes += len(df.Data())
2279 frames++
2280 for _, b := range df.Data() {
2281 if b != 'a' {
2282 t.Fatal("non-'a' byte seen in DATA")
2283 }
2284 }
2285 if df.StreamEnded() {
2286 break
2287 }
2288 }
2289 if bytes != size {
2290 t.Errorf("Got %d bytes; want %d", bytes, size)
2291 }
2292 if want := int(size / maxFrameSize); frames < want || frames > want*2 {
2293 t.Errorf("Got %d frames; want %d", frames, size)
2294 }
2295 })
2296 }
2297
2298
2299 func TestServer_Response_LargeWrite_FlowControlled(t *testing.T) {
2300 synctest.Test(t, testServer_Response_LargeWrite_FlowControlled)
2301 }
2302 func testServer_Response_LargeWrite_FlowControlled(t *testing.T) {
2303
2304
2305 reads := []int{123, 1, 13, 127}
2306 size := 0
2307 for _, n := range reads {
2308 size += n
2309 }
2310
2311 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2312 w.(http.Flusher).Flush()
2313 n, err := w.Write(bytes.Repeat([]byte("a"), size))
2314 if err != nil {
2315 return fmt.Errorf("Write error: %v", err)
2316 }
2317 if n != size {
2318 return fmt.Errorf("wrong size %d from Write", n)
2319 }
2320 return nil
2321 }, func(st *serverTester) {
2322
2323
2324 if err := st.fr.WriteSettings(Setting{SettingInitialWindowSize, uint32(reads[0])}); err != nil {
2325 t.Fatal(err)
2326 }
2327 st.wantSettingsAck()
2328
2329 getSlash(st)
2330
2331 st.wantHeaders(wantHeader{
2332 streamID: 1,
2333 endStream: false,
2334 })
2335
2336 st.wantData(wantData{
2337 streamID: 1,
2338 endStream: false,
2339 size: reads[0],
2340 })
2341
2342 for i, quota := range reads[1:] {
2343 if err := st.fr.WriteWindowUpdate(1, uint32(quota)); err != nil {
2344 t.Fatal(err)
2345 }
2346 st.wantData(wantData{
2347 streamID: 1,
2348 endStream: i == len(reads[1:])-1,
2349 size: quota,
2350 })
2351 }
2352 })
2353 }
2354
2355
2356 func TestServer_Response_RST_Unblocks_LargeWrite(t *testing.T) {
2357 synctest.Test(t, testServer_Response_RST_Unblocks_LargeWrite)
2358 }
2359 func testServer_Response_RST_Unblocks_LargeWrite(t *testing.T) {
2360 const size = 1 << 20
2361 const maxFrameSize = 16 << 10
2362 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2363 w.(http.Flusher).Flush()
2364 _, err := w.Write(bytes.Repeat([]byte("a"), size))
2365 if err == nil {
2366 return errors.New("unexpected nil error from Write in handler")
2367 }
2368 return nil
2369 }, func(st *serverTester) {
2370 if err := st.fr.WriteSettings(
2371 Setting{SettingInitialWindowSize, 0},
2372 Setting{SettingMaxFrameSize, maxFrameSize},
2373 ); err != nil {
2374 t.Fatal(err)
2375 }
2376 st.wantSettingsAck()
2377
2378 getSlash(st)
2379
2380 st.wantHeaders(wantHeader{
2381 streamID: 1,
2382 endStream: false,
2383 })
2384
2385 if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
2386 t.Fatal(err)
2387 }
2388 })
2389 }
2390
2391 func TestServer_Response_Empty_Data_Not_FlowControlled(t *testing.T) {
2392 synctest.Test(t, testServer_Response_Empty_Data_Not_FlowControlled)
2393 }
2394 func testServer_Response_Empty_Data_Not_FlowControlled(t *testing.T) {
2395 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2396 w.(http.Flusher).Flush()
2397
2398 return nil
2399 }, func(st *serverTester) {
2400
2401 if err := st.fr.WriteSettings(Setting{SettingInitialWindowSize, 0}); err != nil {
2402 t.Fatal(err)
2403 }
2404 st.wantSettingsAck()
2405
2406 getSlash(st)
2407
2408 st.wantHeaders(wantHeader{
2409 streamID: 1,
2410 endStream: false,
2411 })
2412
2413 st.wantData(wantData{
2414 streamID: 1,
2415 endStream: true,
2416 size: 0,
2417 })
2418 })
2419 }
2420
2421 func TestServer_Response_Automatic100Continue(t *testing.T) {
2422 synctest.Test(t, testServer_Response_Automatic100Continue)
2423 }
2424 func testServer_Response_Automatic100Continue(t *testing.T) {
2425 const msg = "foo"
2426 const reply = "bar"
2427 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2428 if v := r.Header.Get("Expect"); v != "" {
2429 t.Errorf("Expect header = %q; want empty", v)
2430 }
2431 buf := make([]byte, len(msg))
2432
2433 if n, err := io.ReadFull(r.Body, buf); err != nil || n != len(msg) || string(buf) != msg {
2434 return fmt.Errorf("ReadFull = %q, %v; want %q, nil", buf[:n], err, msg)
2435 }
2436 _, err := io.WriteString(w, reply)
2437 return err
2438 }, func(st *serverTester) {
2439 st.writeHeaders(HeadersFrameParam{
2440 StreamID: 1,
2441 BlockFragment: st.encodeHeader(":method", "POST", "expect", "100-Continue"),
2442 EndStream: false,
2443 EndHeaders: true,
2444 })
2445 st.wantHeaders(wantHeader{
2446 streamID: 1,
2447 endStream: false,
2448 header: http.Header{
2449 ":status": []string{"100"},
2450 },
2451 })
2452
2453
2454
2455 st.writeData(1, true, []byte(msg))
2456
2457 st.wantHeaders(wantHeader{
2458 streamID: 1,
2459 endStream: false,
2460 header: http.Header{
2461 ":status": []string{"200"},
2462 "content-type": []string{"text/plain; charset=utf-8"},
2463 "content-length": []string{strconv.Itoa(len(reply))},
2464 },
2465 })
2466
2467 st.wantData(wantData{
2468 streamID: 1,
2469 endStream: true,
2470 data: []byte(reply),
2471 })
2472 })
2473 }
2474
2475 func TestServer_HandlerWriteErrorOnDisconnect(t *testing.T) {
2476 synctest.Test(t, testServer_HandlerWriteErrorOnDisconnect)
2477 }
2478 func testServer_HandlerWriteErrorOnDisconnect(t *testing.T) {
2479 errc := make(chan error, 1)
2480 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2481 p := []byte("some data.\n")
2482 for {
2483 _, err := w.Write(p)
2484 if err != nil {
2485 errc <- err
2486 return nil
2487 }
2488 }
2489 }, func(st *serverTester) {
2490 st.writeHeaders(HeadersFrameParam{
2491 StreamID: 1,
2492 BlockFragment: st.encodeHeader(),
2493 EndStream: false,
2494 EndHeaders: true,
2495 })
2496 st.wantHeaders(wantHeader{
2497 streamID: 1,
2498 endStream: false,
2499 })
2500
2501 st.cc.Close()
2502 _ = <-errc
2503 })
2504 }
2505
2506 func TestServer_Rejects_Too_Many_Streams(t *testing.T) {
2507 synctest.Test(t, testServer_Rejects_Too_Many_Streams)
2508 }
2509 func testServer_Rejects_Too_Many_Streams(t *testing.T) {
2510 st := newServerTester(t, nil)
2511 st.greet()
2512 nextStreamID := uint32(1)
2513 streamID := func() uint32 {
2514 defer func() { nextStreamID += 2 }()
2515 return nextStreamID
2516 }
2517 sendReq := func(id uint32) {
2518 st.writeHeaders(HeadersFrameParam{
2519 StreamID: id,
2520 BlockFragment: st.encodeHeader(
2521 ":path", fmt.Sprintf("/%v", id),
2522 ),
2523 EndStream: true,
2524 EndHeaders: true,
2525 })
2526 }
2527 var calls []*serverHandlerCall
2528 for range DefaultMaxStreams {
2529 sendReq(streamID())
2530 calls = append(calls, st.nextHandlerCall())
2531 }
2532
2533
2534
2535
2536 rejectID := streamID()
2537 headerBlock := st.encodeHeader(":path", fmt.Sprintf("/%v", rejectID))
2538 frag1, frag2 := headerBlock[:3], headerBlock[3:]
2539 st.writeHeaders(HeadersFrameParam{
2540 StreamID: rejectID,
2541 BlockFragment: frag1,
2542 EndStream: true,
2543 EndHeaders: false,
2544 })
2545 if err := st.fr.WriteContinuation(rejectID, true, frag2); err != nil {
2546 t.Fatal(err)
2547 }
2548 st.sync()
2549 st.wantRSTStream(rejectID, ErrCodeProtocol)
2550
2551
2552 calls[0].exit()
2553 st.sync()
2554 st.wantHeaders(wantHeader{
2555 streamID: 1,
2556 endStream: true,
2557 })
2558
2559
2560 goodID := streamID()
2561 sendReq(goodID)
2562 call := st.nextHandlerCall()
2563 if got, want := call.req.URL.Path, fmt.Sprintf("/%d", goodID); got != want {
2564 t.Errorf("Got request for %q, want %q", got, want)
2565 }
2566 }
2567
2568
2569 func TestServer_Response_ManyHeaders_With_Continuation(t *testing.T) {
2570 synctest.Test(t, testServer_Response_ManyHeaders_With_Continuation)
2571 }
2572 func testServer_Response_ManyHeaders_With_Continuation(t *testing.T) {
2573 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2574 h := w.Header()
2575 for i := range 5000 {
2576 h.Set(fmt.Sprintf("x-header-%d", i), fmt.Sprintf("x-value-%d", i))
2577 }
2578 return nil
2579 }, func(st *serverTester) {
2580 getSlash(st)
2581 hf := readFrame[*HeadersFrame](t, st)
2582 if hf.HeadersEnded() {
2583 t.Fatal("got unwanted END_HEADERS flag")
2584 }
2585 n := 0
2586 for {
2587 n++
2588 cf := readFrame[*ContinuationFrame](t, st)
2589 if cf.HeadersEnded() {
2590 break
2591 }
2592 }
2593 if n < 5 {
2594 t.Errorf("Only got %d CONTINUATION frames; expected 5+ (currently 6)", n)
2595 }
2596 })
2597 }
2598
2599
2600
2601
2602
2603
2604
2605
2606 func TestServer_NoCrash_HandlerClose_Then_ClientClose(t *testing.T) {
2607 synctest.Test(t, testServer_NoCrash_HandlerClose_Then_ClientClose)
2608 }
2609 func testServer_NoCrash_HandlerClose_Then_ClientClose(t *testing.T) {
2610 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2611
2612 return nil
2613 }, func(st *serverTester) {
2614 st.writeHeaders(HeadersFrameParam{
2615 StreamID: 1,
2616 BlockFragment: st.encodeHeader(),
2617 EndStream: false,
2618 EndHeaders: true,
2619 })
2620 st.wantHeaders(wantHeader{
2621 streamID: 1,
2622 endStream: true,
2623 })
2624
2625
2626
2627 st.wantRSTStream(1, ErrCodeNo)
2628
2629
2630
2631
2632
2633
2634 st.writeData(1, true, []byte("foo"))
2635
2636
2637
2638
2639
2640 st.wantRSTStream(1, ErrCodeStreamClosed)
2641
2642
2643
2644 st.wantConnFlowControlConsumed(0)
2645
2646
2647
2648 var (
2649 panMu sync.Mutex
2650 panicVal any
2651 )
2652
2653 SetTestHookOnPanic(t, func(sc *ServerConn, pv any) bool {
2654 panMu.Lock()
2655 panicVal = pv
2656 panMu.Unlock()
2657 return true
2658 })
2659
2660
2661 st.cc.Close()
2662 synctest.Wait()
2663
2664 panMu.Lock()
2665 got := panicVal
2666 panMu.Unlock()
2667 if got != nil {
2668 t.Errorf("Got panic: %v", got)
2669 }
2670 })
2671 }
2672
2673 func TestServer_Rejects_TLS10(t *testing.T) { testRejectTLS(t, tls.VersionTLS10) }
2674 func TestServer_Rejects_TLS11(t *testing.T) { testRejectTLS(t, tls.VersionTLS11) }
2675
2676 func testRejectTLS(t *testing.T, version uint16) {
2677 synctest.Test(t, func(t *testing.T) {
2678 st := newServerTester(t, nil, func(state *tls.ConnectionState) {
2679
2680
2681
2682 state.Version = version
2683 })
2684 defer st.Close()
2685 st.wantGoAway(0, ErrCodeInadequateSecurity)
2686 })
2687 }
2688
2689 func TestServer_Rejects_TLSBadCipher(t *testing.T) { synctest.Test(t, testServer_Rejects_TLSBadCipher) }
2690 func testServer_Rejects_TLSBadCipher(t *testing.T) {
2691 st := newServerTester(t, nil, func(state *tls.ConnectionState) {
2692 state.Version = tls.VersionTLS12
2693 state.CipherSuite = tls.TLS_RSA_WITH_RC4_128_SHA
2694 })
2695 defer st.Close()
2696 st.wantGoAway(0, ErrCodeInadequateSecurity)
2697 }
2698
2699 func TestServer_Advertises_Common_Cipher(t *testing.T) {
2700 synctest.Test(t, testServer_Advertises_Common_Cipher)
2701 }
2702 func testServer_Advertises_Common_Cipher(t *testing.T) {
2703 ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
2704 }, func(srv *http.Server) {
2705
2706
2707 srv.TLSConfig = nil
2708 })
2709
2710
2711 const requiredSuite = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
2712 tlsConfig := tlsConfigInsecure.Clone()
2713 tlsConfig.MaxVersion = tls.VersionTLS12
2714 tlsConfig.CipherSuites = []uint16{requiredSuite}
2715 tr := &http.Transport{
2716 TLSClientConfig: tlsConfig,
2717 Protocols: protocols("h2"),
2718 }
2719 defer tr.CloseIdleConnections()
2720
2721 req, err := http.NewRequest("GET", ts.URL, nil)
2722 if err != nil {
2723 t.Fatal(err)
2724 }
2725 res, err := tr.RoundTrip(req)
2726 if err != nil {
2727 t.Fatal(err)
2728 }
2729 res.Body.Close()
2730 }
2731
2732
2733
2734 func testServerResponse(t *testing.T,
2735 handler func(http.ResponseWriter, *http.Request) error,
2736 client func(*serverTester),
2737 ) {
2738 errc := make(chan error, 1)
2739 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
2740 if r.Body == nil {
2741 t.Fatal("nil Body")
2742 }
2743 err := handler(w, r)
2744 select {
2745 case errc <- err:
2746 default:
2747 t.Errorf("unexpected duplicate request")
2748 }
2749 })
2750 defer st.Close()
2751
2752 st.greet()
2753 client(st)
2754
2755 if err := <-errc; err != nil {
2756 t.Fatalf("Error in handler: %v", err)
2757 }
2758 }
2759
2760
2761
2762
2763 func readBodyHandler(t *testing.T, want string) func(w http.ResponseWriter, r *http.Request) {
2764 return func(w http.ResponseWriter, r *http.Request) {
2765 buf := make([]byte, len(want))
2766 _, err := io.ReadFull(r.Body, buf)
2767 if err != nil {
2768 t.Error(err)
2769 return
2770 }
2771 if string(buf) != want {
2772 t.Errorf("read %q; want %q", buf, want)
2773 }
2774 }
2775 }
2776
2777 func TestServer_MaxDecoderHeaderTableSize(t *testing.T) {
2778 synctest.Test(t, testServer_MaxDecoderHeaderTableSize)
2779 }
2780 func testServer_MaxDecoderHeaderTableSize(t *testing.T) {
2781 wantHeaderTableSize := uint32(InitialHeaderTableSize * 2)
2782 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}, func(h2 *http.HTTP2Config) {
2783 h2.MaxDecoderHeaderTableSize = int(wantHeaderTableSize)
2784 })
2785 defer st.Close()
2786
2787 var advHeaderTableSize *uint32
2788 st.greetAndCheckSettings(func(s Setting) error {
2789 switch s.ID {
2790 case SettingHeaderTableSize:
2791 advHeaderTableSize = &s.Val
2792 }
2793 return nil
2794 })
2795
2796 if advHeaderTableSize == nil {
2797 t.Errorf("server didn't advertise a header table size")
2798 } else if got, want := *advHeaderTableSize, wantHeaderTableSize; got != want {
2799 t.Errorf("server advertised a header table size of %d, want %d", got, want)
2800 }
2801 }
2802
2803 func TestServer_MaxEncoderHeaderTableSize(t *testing.T) {
2804 synctest.Test(t, testServer_MaxEncoderHeaderTableSize)
2805 }
2806 func testServer_MaxEncoderHeaderTableSize(t *testing.T) {
2807 wantHeaderTableSize := uint32(InitialHeaderTableSize / 2)
2808 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}, func(h2 *http.HTTP2Config) {
2809 h2.MaxEncoderHeaderTableSize = int(wantHeaderTableSize)
2810 })
2811 defer st.Close()
2812
2813 st.greet()
2814
2815 if got, want := st.sc.TestHPACKEncoder().MaxDynamicTableSize(), wantHeaderTableSize; got != want {
2816 t.Errorf("server encoder is using a header table size of %d, want %d", got, want)
2817 }
2818 }
2819
2820
2821
2822
2823
2824 func TestServer_HeaderTableSizeDuringWrite(t *testing.T) {
2825 synctest.Test(t, testServer_HeaderTableSizeDuringWrite)
2826 }
2827 func testServer_HeaderTableSizeDuringWrite(t *testing.T) {
2828 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {})
2829 defer st.Close()
2830 st.greet()
2831 enc := st.sc.TestHPACKEncoder()
2832
2833
2834
2835 st.cc.(*tls.Conn).NetConn().(*synctestNetConn).SetReadBufferSize(0)
2836 st.bodylessReq1()
2837 synctest.Wait()
2838 st.writeSettings(Setting{SettingHeaderTableSize, 0})
2839 st.writeSettings(Setting{SettingHeaderTableSize, 2048})
2840 synctest.Wait()
2841
2842
2843
2844 if got, want := enc.MaxDynamicTableSize(), uint32(InitialHeaderTableSize); got != want {
2845 t.Errorf("during frame write: encoder header table size = %d, want %d", got, want)
2846 }
2847 st.cc.(*tls.Conn).NetConn().(*synctestNetConn).SetReadBufferSize(math.MaxInt)
2848 st.wantHeaders(wantHeader{streamID: 1, endStream: true})
2849 st.wantSettingsAck()
2850
2851 st.writeHeaders(HeadersFrameParam{
2852 StreamID: 3,
2853 BlockFragment: st.encodeHeader(),
2854 EndStream: true,
2855 EndHeaders: true,
2856 })
2857 synctest.Wait()
2858 hf := readFrame[*HeadersFrame](t, st)
2859 if hf.StreamID != 3 {
2860 t.Fatalf("got HEADERS for stream %d, want stream 3", hf.StreamID)
2861 }
2862
2863
2864
2865 var want bytes.Buffer
2866 wantEnc := hpack.NewEncoder(&want)
2867 wantEnc.SetMaxDynamicTableSize(0)
2868 wantEnc.SetMaxDynamicTableSize(2048)
2869 wantEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
2870 if got := hf.HeaderBlockFragment(); !bytes.HasPrefix(got, want.Bytes()) {
2871 t.Errorf("stream 3 header block = %x, want prefix %x", got, want.Bytes())
2872 }
2873 if got, want := enc.MaxDynamicTableSize(), uint32(2048); got != want {
2874 t.Errorf("after frame write: encoder header table size = %d, want %d", got, want)
2875 }
2876 }
2877
2878
2879 func TestServerDoS_MaxHeaderListSize(t *testing.T) { synctest.Test(t, testServerDoS_MaxHeaderListSize) }
2880 func testServerDoS_MaxHeaderListSize(t *testing.T) {
2881 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {})
2882 defer st.Close()
2883
2884
2885 frameSize := DefaultMaxReadFrameSize
2886 var advHeaderListSize *uint32
2887 st.greetAndCheckSettings(func(s Setting) error {
2888 switch s.ID {
2889 case SettingMaxFrameSize:
2890 if s.Val < MinMaxFrameSize {
2891 frameSize = MinMaxFrameSize
2892 } else if s.Val > MaxFrameSize {
2893 frameSize = MaxFrameSize
2894 } else {
2895 frameSize = int(s.Val)
2896 }
2897 case SettingMaxHeaderListSize:
2898 advHeaderListSize = &s.Val
2899 }
2900 return nil
2901 })
2902
2903 if advHeaderListSize == nil {
2904 t.Errorf("server didn't advertise a max header list size")
2905 } else if *advHeaderListSize == 0 {
2906 t.Errorf("server advertised a max header list size of 0")
2907 }
2908
2909 st.encodeHeaderField(":method", "GET")
2910 st.encodeHeaderField(":path", "/")
2911 st.encodeHeaderField(":scheme", "https")
2912 cookie := strings.Repeat("*", 4058)
2913 st.encodeHeaderField("cookie", cookie)
2914 st.writeHeaders(HeadersFrameParam{
2915 StreamID: 1,
2916 BlockFragment: st.headerBuf.Bytes(),
2917 EndStream: true,
2918 EndHeaders: false,
2919 })
2920
2921
2922
2923 st.headerBuf.Reset()
2924 st.encodeHeaderField("cookie", cookie)
2925
2926
2927 const size = 1 << 20
2928 b := bytes.Repeat(st.headerBuf.Bytes(), size/st.headerBuf.Len())
2929 for len(b) > 0 {
2930 chunk := b
2931 if len(chunk) > frameSize {
2932 chunk = chunk[:frameSize]
2933 }
2934 b = b[len(chunk):]
2935 st.fr.WriteContinuation(1, len(b) == 0, chunk)
2936 }
2937
2938 st.wantHeaders(wantHeader{
2939 streamID: 1,
2940 endStream: false,
2941 header: http.Header{
2942 ":status": []string{"431"},
2943 "content-type": []string{"text/html; charset=utf-8"},
2944 "content-length": []string{"63"},
2945 },
2946 })
2947 }
2948
2949 func TestServer_Response_Stream_With_Missing_Trailer(t *testing.T) {
2950 synctest.Test(t, testServer_Response_Stream_With_Missing_Trailer)
2951 }
2952 func testServer_Response_Stream_With_Missing_Trailer(t *testing.T) {
2953 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
2954 w.Header().Set("Trailer", "test-trailer")
2955 return nil
2956 }, func(st *serverTester) {
2957 getSlash(st)
2958 st.wantHeaders(wantHeader{
2959 streamID: 1,
2960 endStream: false,
2961 })
2962 st.wantData(wantData{
2963 streamID: 1,
2964 endStream: true,
2965 size: 0,
2966 })
2967 })
2968 }
2969
2970 func TestCompressionErrorOnWrite(t *testing.T) { synctest.Test(t, testCompressionErrorOnWrite) }
2971 func testCompressionErrorOnWrite(t *testing.T) {
2972 const maxStrLen = 8 << 10
2973 var serverConfig *http.Server
2974 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
2975
2976 }, func(s *http.Server) {
2977 serverConfig = s
2978 serverConfig.MaxHeaderBytes = maxStrLen
2979 })
2980 st.addLogFilter("connection error: COMPRESSION_ERROR")
2981 defer st.Close()
2982 st.greet()
2983
2984 maxAllowed := st.sc.TestFramerMaxHeaderStringLen()
2985
2986
2987
2988
2989
2990
2991 serverConfig.MaxHeaderBytes = 1 << 20
2992
2993
2994
2995
2996
2997 hbf := st.encodeHeader("foo", strings.Repeat("a", maxAllowed))
2998
2999 st.writeHeaders(HeadersFrameParam{
3000 StreamID: 1,
3001 BlockFragment: hbf,
3002 EndStream: true,
3003 EndHeaders: true,
3004 })
3005 st.wantHeaders(wantHeader{
3006 streamID: 1,
3007 endStream: false,
3008 header: http.Header{
3009 ":status": []string{"431"},
3010 "content-type": []string{"text/html; charset=utf-8"},
3011 "content-length": []string{"63"},
3012 },
3013 })
3014 df := readFrame[*DataFrame](t, st)
3015 if !strings.Contains(string(df.Data()), "HTTP Error 431") {
3016 t.Errorf("Unexpected data body: %q", df.Data())
3017 }
3018 if !df.StreamEnded() {
3019 t.Fatalf("expect data stream end")
3020 }
3021
3022
3023 hbf = st.encodeHeader("bar", strings.Repeat("b", maxAllowed+1))
3024 st.writeHeaders(HeadersFrameParam{
3025 StreamID: 3,
3026 BlockFragment: hbf,
3027 EndStream: true,
3028 EndHeaders: true,
3029 })
3030 st.wantGoAway(3, ErrCodeCompression)
3031 }
3032
3033 func TestCompressionErrorOnClose(t *testing.T) { synctest.Test(t, testCompressionErrorOnClose) }
3034 func testCompressionErrorOnClose(t *testing.T) {
3035 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3036
3037 })
3038 st.addLogFilter("connection error: COMPRESSION_ERROR")
3039 defer st.Close()
3040 st.greet()
3041
3042 hbf := st.encodeHeader("foo", "bar")
3043 hbf = hbf[:len(hbf)-1]
3044 st.writeHeaders(HeadersFrameParam{
3045 StreamID: 1,
3046 BlockFragment: hbf,
3047 EndStream: true,
3048 EndHeaders: true,
3049 })
3050 st.wantGoAway(1, ErrCodeCompression)
3051 }
3052
3053
3054 func TestServerReadsTrailers(t *testing.T) { synctest.Test(t, testServerReadsTrailers) }
3055 func testServerReadsTrailers(t *testing.T) {
3056 const testBody = "some test body"
3057 writeReq := func(st *serverTester) {
3058 st.writeHeaders(HeadersFrameParam{
3059 StreamID: 1,
3060 BlockFragment: st.encodeHeader("trailer", "Foo, Bar", "trailer", "Baz"),
3061 EndStream: false,
3062 EndHeaders: true,
3063 })
3064 st.writeData(1, false, []byte(testBody))
3065 st.writeHeaders(HeadersFrameParam{
3066 StreamID: 1,
3067 BlockFragment: st.encodeHeaderRaw(
3068 "foo", "foov",
3069 "bar", "barv",
3070 "baz", "bazv",
3071 "surprise", "wasn't declared; shouldn't show up",
3072 ),
3073 EndStream: true,
3074 EndHeaders: true,
3075 })
3076 }
3077 checkReq := func(r *http.Request) {
3078 wantTrailer := http.Header{
3079 "Foo": nil,
3080 "Bar": nil,
3081 "Baz": nil,
3082 }
3083 if !reflect.DeepEqual(r.Trailer, wantTrailer) {
3084 t.Errorf("initial Trailer = %v; want %v", r.Trailer, wantTrailer)
3085 }
3086 slurp, err := io.ReadAll(r.Body)
3087 if string(slurp) != testBody {
3088 t.Errorf("read body %q; want %q", slurp, testBody)
3089 }
3090 if err != nil {
3091 t.Fatalf("Body slurp: %v", err)
3092 }
3093 wantTrailerAfter := http.Header{
3094 "Foo": {"foov"},
3095 "Bar": {"barv"},
3096 "Baz": {"bazv"},
3097 }
3098 if !reflect.DeepEqual(r.Trailer, wantTrailerAfter) {
3099 t.Errorf("final Trailer = %v; want %v", r.Trailer, wantTrailerAfter)
3100 }
3101 }
3102 testServerRequest(t, writeReq, checkReq)
3103 }
3104
3105
3106 func TestServerWritesTrailers_WithFlush(t *testing.T) {
3107 synctest.Test(t, func(t *testing.T) {
3108 testServerWritesTrailers(t, true)
3109 })
3110 }
3111 func TestServerWritesTrailers_WithoutFlush(t *testing.T) {
3112 synctest.Test(t, func(t *testing.T) {
3113 testServerWritesTrailers(t, false)
3114 })
3115 }
3116
3117 func testServerWritesTrailers(t *testing.T, withFlush bool) {
3118
3119 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
3120 w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B")
3121 w.Header().Add("Trailer", "Server-Trailer-C")
3122 w.Header().Add("Trailer", "Transfer-Encoding, Content-Length, Trailer")
3123
3124
3125 w.Header().Set("Foo", "Bar")
3126 w.Header().Set("Content-Length", "5")
3127
3128 io.WriteString(w, "Hello")
3129 if withFlush {
3130 w.(http.Flusher).Flush()
3131 }
3132 w.Header().Set("Server-Trailer-A", "valuea")
3133 w.Header().Set("Server-Trailer-C", "valuec")
3134
3135 w.Header().Set("Server-Surpise", "surprise! this isn't predeclared!")
3136
3137
3138
3139 w.Header().Set("Trailer:Post-Header-Trailer", "hi1")
3140 w.Header().Set("Trailer:post-header-trailer2", "hi2")
3141 w.Header().Set("Trailer:Range", "invalid")
3142 w.Header().Set("Trailer:Foo\x01Bogus", "invalid")
3143 w.Header().Set("Transfer-Encoding", "should not be included; Forbidden by RFC 7230 4.1.2")
3144 w.Header().Set("Content-Length", "should not be included; Forbidden by RFC 7230 4.1.2")
3145 w.Header().Set("Trailer", "should not be included; Forbidden by RFC 7230 4.1.2")
3146 return nil
3147 }, func(st *serverTester) {
3148
3149 st.h1server.ErrorLog = log.New(io.Discard, "", 0)
3150 getSlash(st)
3151 st.wantHeaders(wantHeader{
3152 streamID: 1,
3153 endStream: false,
3154 header: http.Header{
3155 ":status": []string{"200"},
3156 "foo": []string{"Bar"},
3157 "trailer": []string{
3158 "Server-Trailer-A, Server-Trailer-B",
3159 "Server-Trailer-C",
3160 "Transfer-Encoding, Content-Length, Trailer",
3161 },
3162 "content-type": []string{"text/plain; charset=utf-8"},
3163 "content-length": []string{"5"},
3164 },
3165 })
3166 st.wantData(wantData{
3167 streamID: 1,
3168 endStream: false,
3169 data: []byte("Hello"),
3170 })
3171 st.wantHeaders(wantHeader{
3172 streamID: 1,
3173 endStream: true,
3174 header: http.Header{
3175 "post-header-trailer": []string{"hi1"},
3176 "post-header-trailer2": []string{"hi2"},
3177 "server-trailer-a": []string{"valuea"},
3178 "server-trailer-c": []string{"valuec"},
3179 },
3180 })
3181 })
3182 }
3183
3184 func TestServerWritesUndeclaredTrailers(t *testing.T) {
3185 synctest.Test(t, testServerWritesUndeclaredTrailers)
3186 }
3187 func testServerWritesUndeclaredTrailers(t *testing.T) {
3188 const trailer = "Trailer-Header"
3189 const value = "hi1"
3190 ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
3191 w.Header().Set(http.TrailerPrefix+trailer, value)
3192 })
3193
3194 tr := &http.Transport{
3195 TLSClientConfig: tlsConfigInsecure,
3196 Protocols: protocols("h2"),
3197 }
3198 defer tr.CloseIdleConnections()
3199
3200 cl := &http.Client{Transport: tr}
3201 resp, err := cl.Get(ts.URL)
3202 if err != nil {
3203 t.Fatal(err)
3204 }
3205 io.Copy(io.Discard, resp.Body)
3206 resp.Body.Close()
3207
3208 if got, want := resp.Trailer.Get(trailer), value; got != want {
3209 t.Errorf("trailer %v = %q, want %q", trailer, got, want)
3210 }
3211 }
3212
3213
3214
3215 func TestServerDoesntWriteInvalidHeaders(t *testing.T) {
3216 synctest.Test(t, testServerDoesntWriteInvalidHeaders)
3217 }
3218 func testServerDoesntWriteInvalidHeaders(t *testing.T) {
3219 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
3220 w.Header().Add("OK1", "x")
3221 w.Header().Add("Bad:Colon", "x")
3222 w.Header().Add("Bad1\x00", "x")
3223 w.Header().Add("Bad2", "x\x00y")
3224 return nil
3225 }, func(st *serverTester) {
3226 getSlash(st)
3227 st.wantHeaders(wantHeader{
3228 streamID: 1,
3229 endStream: true,
3230 header: http.Header{
3231 ":status": []string{"200"},
3232 "ok1": []string{"x"},
3233 "content-length": []string{"0"},
3234 },
3235 })
3236 })
3237 }
3238
3239 func TestIssue53(t *testing.T) { synctest.Test(t, testIssue53) }
3240 func testIssue53(t *testing.T) {
3241 const data = "PRI * HTTP/2.0\r\n\r\nSM" +
3242 "\r\n\r\n\x00\x00\x00\x01\ainfinfin\ad"
3243 st := newServerTester(t, func(w http.ResponseWriter, req *http.Request) {
3244 w.Write([]byte("hello"))
3245 })
3246
3247 st.cc.Write([]byte(data))
3248 st.wantFrameType(FrameSettings)
3249 st.wantFrameType(FrameWindowUpdate)
3250 st.wantFrameType(FrameGoAway)
3251 time.Sleep(GoAwayTimeout)
3252 st.wantClosed()
3253 }
3254
3255 func TestServerServeNoBannedCiphers(t *testing.T) {
3256 tests := []struct {
3257 name string
3258 tlsConfig *tls.Config
3259 wantErr string
3260 }{
3261 {
3262 name: "empty CipherSuites",
3263 tlsConfig: &tls.Config{},
3264 },
3265 {
3266 name: "bad CipherSuites but MinVersion TLS 1.3",
3267 tlsConfig: &tls.Config{
3268 MinVersion: tls.VersionTLS13,
3269 CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
3270 },
3271 },
3272 {
3273 name: "just the required cipher suite",
3274 tlsConfig: &tls.Config{
3275 CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3276 },
3277 },
3278 {
3279 name: "just the alternative required cipher suite",
3280 tlsConfig: &tls.Config{
3281 CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
3282 },
3283 },
3284 {
3285 name: "missing required cipher suite",
3286 tlsConfig: &tls.Config{
3287 CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
3288 },
3289 wantErr: "is missing an HTTP/2-required",
3290 },
3291 {
3292 name: "required after bad",
3293 tlsConfig: &tls.Config{
3294 CipherSuites: []uint16{tls.TLS_RSA_WITH_RC4_128_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3295 },
3296 },
3297 {
3298 name: "bad after required",
3299 tlsConfig: &tls.Config{
3300 CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_RSA_WITH_RC4_128_SHA},
3301 },
3302 },
3303 }
3304 for _, tt := range tests {
3305 tt.tlsConfig.Certificates = testServerTLSConfig.Certificates
3306
3307 srv := &http.Server{
3308 TLSConfig: tt.tlsConfig,
3309 Protocols: protocols("h2"),
3310 }
3311
3312 err := srv.ServeTLS(errListener{}, "", "")
3313 if (err != net.ErrClosed) != (tt.wantErr != "") {
3314 if tt.wantErr != "" {
3315 t.Errorf("%s: success, but want error", tt.name)
3316 } else {
3317 t.Errorf("%s: unexpected error: %v", tt.name, err)
3318 }
3319 }
3320 if err != nil && tt.wantErr != "" && !strings.Contains(err.Error(), tt.wantErr) {
3321 t.Errorf("%s: err = %v; want substring %q", tt.name, err, tt.wantErr)
3322 }
3323 if err == nil && !srv.TLSConfig.PreferServerCipherSuites {
3324 t.Errorf("%s: PreferServerCipherSuite is false; want true", tt.name)
3325 }
3326 }
3327 }
3328
3329 type errListener struct{}
3330
3331 func (li errListener) Accept() (net.Conn, error) { return nil, net.ErrClosed }
3332 func (li errListener) Close() error { return nil }
3333 func (li errListener) Addr() net.Addr { return nil }
3334
3335 func TestServerNoAutoContentLengthOnHead(t *testing.T) {
3336 synctest.Test(t, testServerNoAutoContentLengthOnHead)
3337 }
3338 func testServerNoAutoContentLengthOnHead(t *testing.T) {
3339 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3340
3341 })
3342 defer st.Close()
3343 st.greet()
3344 st.writeHeaders(HeadersFrameParam{
3345 StreamID: 1,
3346 BlockFragment: st.encodeHeader(":method", "HEAD"),
3347 EndStream: true,
3348 EndHeaders: true,
3349 })
3350 st.wantHeaders(wantHeader{
3351 streamID: 1,
3352 endStream: true,
3353 header: http.Header{
3354 ":status": []string{"200"},
3355 },
3356 })
3357 }
3358
3359
3360 func TestServerNoDuplicateContentType(t *testing.T) {
3361 synctest.Test(t, testServerNoDuplicateContentType)
3362 }
3363 func testServerNoDuplicateContentType(t *testing.T) {
3364 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3365 w.Header()["Content-Type"] = []string{""}
3366 fmt.Fprintf(w, "<html><head></head><body>hi</body></html>")
3367 })
3368 defer st.Close()
3369 st.greet()
3370 st.writeHeaders(HeadersFrameParam{
3371 StreamID: 1,
3372 BlockFragment: st.encodeHeader(),
3373 EndStream: true,
3374 EndHeaders: true,
3375 })
3376 st.wantHeaders(wantHeader{
3377 streamID: 1,
3378 endStream: false,
3379 header: http.Header{
3380 ":status": []string{"200"},
3381 "content-type": []string{""},
3382 "content-length": []string{"41"},
3383 },
3384 })
3385 }
3386
3387 func TestServerContentLengthCanBeDisabled(t *testing.T) {
3388 synctest.Test(t, testServerContentLengthCanBeDisabled)
3389 }
3390 func testServerContentLengthCanBeDisabled(t *testing.T) {
3391 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3392 w.Header()["Content-Length"] = nil
3393 fmt.Fprintf(w, "OK")
3394 })
3395 defer st.Close()
3396 st.greet()
3397 st.writeHeaders(HeadersFrameParam{
3398 StreamID: 1,
3399 BlockFragment: st.encodeHeader(),
3400 EndStream: true,
3401 EndHeaders: true,
3402 })
3403 st.wantHeaders(wantHeader{
3404 streamID: 1,
3405 endStream: false,
3406 header: http.Header{
3407 ":status": []string{"200"},
3408 "content-type": []string{"text/plain; charset=utf-8"},
3409 },
3410 })
3411 }
3412
3413
3414 func TestServer_Rejects_ConnHeaders(t *testing.T) { synctest.Test(t, testServer_Rejects_ConnHeaders) }
3415 func testServer_Rejects_ConnHeaders(t *testing.T) {
3416 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3417 t.Error("should not get to Handler")
3418 })
3419 defer st.Close()
3420 st.greet()
3421 st.bodylessReq1("connection", "foo")
3422 st.wantHeaders(wantHeader{
3423 streamID: 1,
3424 endStream: false,
3425 header: http.Header{
3426 ":status": []string{"400"},
3427 "content-type": []string{"text/plain; charset=utf-8"},
3428 "x-content-type-options": []string{"nosniff"},
3429 "content-length": []string{"51"},
3430 },
3431 })
3432 }
3433
3434 type hpackEncoder struct {
3435 enc *hpack.Encoder
3436 buf bytes.Buffer
3437 }
3438
3439 func (he *hpackEncoder) encodeHeaderRaw(t *testing.T, headers ...string) []byte {
3440 if len(headers)%2 == 1 {
3441 panic("odd number of kv args")
3442 }
3443 he.buf.Reset()
3444 if he.enc == nil {
3445 he.enc = hpack.NewEncoder(&he.buf)
3446 }
3447 for len(headers) > 0 {
3448 k, v := headers[0], headers[1]
3449 err := he.enc.WriteField(hpack.HeaderField{Name: k, Value: v})
3450 if err != nil {
3451 t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err)
3452 }
3453 headers = headers[2:]
3454 }
3455 return he.buf.Bytes()
3456 }
3457
3458
3459 func TestExpect100ContinueAfterHandlerWrites(t *testing.T) {
3460 synctest.Test(t, testExpect100ContinueAfterHandlerWrites)
3461 }
3462 func testExpect100ContinueAfterHandlerWrites(t *testing.T) {
3463 const msg = "Hello"
3464 const msg2 = "World"
3465
3466 doRead := make(chan bool, 1)
3467 defer close(doRead)
3468
3469 ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
3470 io.WriteString(w, msg)
3471 w.(http.Flusher).Flush()
3472
3473
3474 <-doRead
3475 r.Body.Read(make([]byte, 10))
3476
3477 io.WriteString(w, msg2)
3478 })
3479
3480 tr := &http.Transport{
3481 TLSClientConfig: tlsConfigInsecure,
3482 Protocols: protocols("h2"),
3483 }
3484 defer tr.CloseIdleConnections()
3485
3486 req, _ := http.NewRequest("POST", ts.URL, io.LimitReader(neverEnding('A'), 2<<20))
3487 req.Header.Set("Expect", "100-continue")
3488
3489 res, err := tr.RoundTrip(req)
3490 if err != nil {
3491 t.Fatal(err)
3492 }
3493 defer res.Body.Close()
3494
3495 buf := make([]byte, len(msg))
3496 if _, err := io.ReadFull(res.Body, buf); err != nil {
3497 t.Fatal(err)
3498 }
3499 if string(buf) != msg {
3500 t.Fatalf("msg = %q; want %q", buf, msg)
3501 }
3502
3503 doRead <- true
3504
3505 if _, err := io.ReadFull(res.Body, buf); err != nil {
3506 t.Fatal(err)
3507 }
3508 if string(buf) != msg2 {
3509 t.Fatalf("second msg = %q; want %q", buf, msg2)
3510 }
3511 }
3512
3513 type funcReader func([]byte) (n int, err error)
3514
3515 func (f funcReader) Read(p []byte) (n int, err error) { return f(p) }
3516
3517
3518
3519 func TestUnreadFlowControlReturned_Server(t *testing.T) {
3520 for _, tt := range []struct {
3521 name string
3522 reqFn func(r *http.Request)
3523 }{
3524 {
3525 "body-open",
3526 func(r *http.Request) {},
3527 },
3528 {
3529 "body-closed",
3530 func(r *http.Request) {
3531 r.Body.Close()
3532 },
3533 },
3534 {
3535 "read-1-byte-and-close",
3536 func(r *http.Request) {
3537 b := make([]byte, 1)
3538 r.Body.Read(b)
3539 r.Body.Close()
3540 },
3541 },
3542 } {
3543 synctestSubtest(t, tt.name, func(t *testing.T) {
3544 unblock := make(chan bool, 1)
3545 defer close(unblock)
3546
3547 ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
3548
3549
3550
3551 tt.reqFn(r)
3552 <-unblock
3553 })
3554
3555 tr := &http.Transport{
3556 TLSClientConfig: tlsConfigInsecure,
3557 Protocols: protocols("h2"),
3558 }
3559 defer tr.CloseIdleConnections()
3560
3561
3562 iters := 100
3563 if testing.Short() {
3564 iters = 20
3565 }
3566 for i := 0; i < iters; i++ {
3567 body := io.MultiReader(
3568 io.LimitReader(neverEnding('A'), 16<<10),
3569 funcReader(func([]byte) (n int, err error) {
3570 unblock <- true
3571 return 0, io.EOF
3572 }),
3573 )
3574 req, _ := http.NewRequest("POST", ts.URL, body)
3575 res, err := tr.RoundTrip(req)
3576 if err != nil {
3577 t.Fatal(tt.name, err)
3578 }
3579 res.Body.Close()
3580 }
3581 })
3582 }
3583 }
3584
3585 func TestServerReturnsStreamAndConnFlowControlOnBodyClose(t *testing.T) {
3586 synctest.Test(t, testServerReturnsStreamAndConnFlowControlOnBodyClose)
3587 }
3588 func testServerReturnsStreamAndConnFlowControlOnBodyClose(t *testing.T) {
3589 unblockHandler := make(chan struct{})
3590 defer close(unblockHandler)
3591
3592 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3593 r.Body.Close()
3594 w.WriteHeader(200)
3595 w.(http.Flusher).Flush()
3596 <-unblockHandler
3597 })
3598 defer st.Close()
3599
3600 st.greet()
3601 st.writeHeaders(HeadersFrameParam{
3602 StreamID: 1,
3603 BlockFragment: st.encodeHeader(),
3604 EndHeaders: true,
3605 })
3606 st.wantHeaders(wantHeader{
3607 streamID: 1,
3608 endStream: false,
3609 })
3610 const size = InflowMinRefresh
3611 st.writeData(1, false, make([]byte, size))
3612 st.wantWindowUpdate(0, size)
3613 unblockHandler <- struct{}{}
3614 st.wantData(wantData{
3615 streamID: 1,
3616 endStream: true,
3617 })
3618 }
3619
3620 func TestServerResetStreamUnreadBody(t *testing.T) {
3621 synctestSubtest(t, "read_after_reset", func(t *testing.T) {
3622 st := newServerTester(t, nil)
3623 defer st.Close()
3624
3625 st.greet()
3626 st.writeHeaders(HeadersFrameParam{
3627 StreamID: 1,
3628 BlockFragment: st.encodeHeader(":method", "POST"),
3629 EndHeaders: true,
3630 })
3631 call := st.nextHandlerCall()
3632
3633 const size = InflowMinRefresh
3634 st.writeData(1, false, make([]byte, size))
3635 st.writeRSTStream(1, ErrCodeCancel)
3636 st.sync()
3637
3638
3639 call.do(func(w http.ResponseWriter, req *http.Request) {
3640 io.ReadAll(req.Body)
3641 })
3642 st.wantWindowUpdate(0, size)
3643
3644
3645 call.exit()
3646 st.wantIdle()
3647 })
3648
3649 synctestSubtest(t, "exit_without_reading", func(t *testing.T) {
3650 st := newServerTester(t, nil)
3651 defer st.Close()
3652
3653 st.greet()
3654 st.writeHeaders(HeadersFrameParam{
3655 StreamID: 1,
3656 BlockFragment: st.encodeHeader(":method", "POST"),
3657 EndHeaders: true,
3658 })
3659 call := st.nextHandlerCall()
3660
3661 const size = InflowMinRefresh
3662 st.writeData(1, false, make([]byte, size))
3663 st.writeRSTStream(1, ErrCodeCancel)
3664 st.sync()
3665
3666
3667 call.exit()
3668 st.wantWindowUpdate(0, size)
3669 st.wantIdle()
3670 })
3671
3672 synctestSubtest(t, "read_after_handler_exit", func(t *testing.T) {
3673 st := newServerTester(t, nil)
3674 defer st.Close()
3675
3676 st.greet()
3677 st.writeHeaders(HeadersFrameParam{
3678 StreamID: 1,
3679 BlockFragment: st.encodeHeader(":method", "POST"),
3680 EndHeaders: true,
3681 })
3682 call := st.nextHandlerCall()
3683
3684 const size = InflowMinRefresh
3685 st.writeData(1, false, make([]byte, size))
3686 synctest.Wait()
3687
3688
3689 call.exit()
3690
3691
3692 st.wantUnorderedFrames(
3693 func(f *WindowUpdateFrame) bool {
3694 return f.StreamID == 0 && f.Increment == size
3695 },
3696 func(f *HeadersFrame) bool {
3697 return f.StreamID == 1 && f.StreamEnded()
3698 },
3699 func(f *RSTStreamFrame) bool {
3700 return f.StreamID == 1 && f.ErrCode == ErrCodeNo
3701 },
3702 )
3703
3704
3705 io.ReadAll(call.req.Body)
3706 st.wantIdle()
3707 })
3708
3709 synctestSubtest(t, "unstarted_handler", func(t *testing.T) {
3710 st := newServerTester(t, nil, func(h2 *http.HTTP2Config) {
3711 h2.MaxConcurrentStreams = 1
3712 })
3713 defer st.Close()
3714
3715 st.greet()
3716
3717
3718 st.writeHeaders(HeadersFrameParam{
3719 StreamID: 1,
3720 BlockFragment: st.encodeHeader(),
3721 EndStream: true,
3722 EndHeaders: true,
3723 })
3724 call := st.nextHandlerCall()
3725
3726
3727
3728 st.writeRSTStream(1, ErrCodeCancel)
3729
3730
3731
3732 st.writeHeaders(HeadersFrameParam{
3733 StreamID: 3,
3734 BlockFragment: st.encodeHeader(":method", "POST"),
3735 EndHeaders: true,
3736 })
3737
3738 const size = InflowMinRefresh
3739 st.writeData(3, false, make([]byte, size))
3740 st.writeRSTStream(3, ErrCodeCancel)
3741 st.wantIdle()
3742
3743
3744
3745 call.exit()
3746 st.wantWindowUpdate(0, size)
3747 st.wantIdle()
3748 })
3749
3750
3751
3752 synctestSubtest(t, "middleware_replaces_body", func(t *testing.T) {
3753 st := newServerTester(t, nil)
3754 defer st.Close()
3755
3756 st.greet()
3757 st.writeHeaders(HeadersFrameParam{
3758 StreamID: 1,
3759 BlockFragment: st.encodeHeader(":method", "POST"),
3760 EndHeaders: true,
3761 })
3762 call := st.nextHandlerCall()
3763
3764 call.do(func(w http.ResponseWriter, r *http.Request) {
3765
3766 r.Body = http.MaxBytesReader(w, r.Body, 1000)
3767 })
3768
3769 const size = InflowMinRefresh
3770 st.writeData(1, false, make([]byte, size))
3771 st.writeRSTStream(1, ErrCodeCancel)
3772 st.sync()
3773
3774 call.exit()
3775 st.wantWindowUpdate(0, size)
3776 st.wantIdle()
3777 })
3778 }
3779
3780 func TestServerIdleTimeout(t *testing.T) { synctest.Test(t, testServerIdleTimeout) }
3781 func testServerIdleTimeout(t *testing.T) {
3782 if testing.Short() {
3783 t.Skip("skipping in short mode")
3784 }
3785
3786 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3787 }, func(s *http.Server) {
3788 s.IdleTimeout = 500 * time.Millisecond
3789 })
3790 defer st.Close()
3791
3792 st.greet()
3793 st.advance(500 * time.Millisecond)
3794 st.wantGoAway(0, ErrCodeNo)
3795 }
3796
3797 func TestServerIdleTimeout_AfterRequest(t *testing.T) {
3798 synctest.Test(t, testServerIdleTimeout_AfterRequest)
3799 }
3800 func testServerIdleTimeout_AfterRequest(t *testing.T) {
3801 if testing.Short() {
3802 t.Skip("skipping in short mode")
3803 }
3804 const (
3805 requestTimeout = 2 * time.Second
3806 idleTimeout = 1 * time.Second
3807 )
3808
3809 var st *serverTester
3810 st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3811 time.Sleep(requestTimeout)
3812 }, func(s *http.Server) {
3813 s.IdleTimeout = idleTimeout
3814 })
3815 defer st.Close()
3816
3817 st.greet()
3818
3819
3820
3821 st.bodylessReq1()
3822 st.advance(requestTimeout)
3823 st.wantHeaders(wantHeader{
3824 streamID: 1,
3825 endStream: true,
3826 })
3827
3828
3829
3830 st.advance(idleTimeout)
3831 st.wantGoAway(1, ErrCodeNo)
3832 }
3833
3834
3835
3836
3837 func TestRequestBodyReadCloseRace(t *testing.T) { synctest.Test(t, testRequestBodyReadCloseRace) }
3838 func testRequestBodyReadCloseRace(t *testing.T) {
3839 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3840 go r.Body.Close()
3841 io.Copy(io.Discard, r.Body)
3842 })
3843 st.greet()
3844
3845 data := make([]byte, 1024)
3846 for i := range 100 {
3847 streamID := uint32(1 + (i * 2))
3848 st.writeHeaders(HeadersFrameParam{
3849 StreamID: streamID,
3850 BlockFragment: st.encodeHeader(),
3851 EndHeaders: true,
3852 })
3853 st.writeData(1, false, data)
3854
3855 for {
3856
3857
3858 fr := st.readFrame()
3859 if fr == nil {
3860 t.Fatalf("got no RSTStreamFrame, want one")
3861 }
3862 rst, ok := fr.(*RSTStreamFrame)
3863 if !ok {
3864 continue
3865 }
3866
3867 if rst.ErrCode != ErrCodeNo && rst.ErrCode != ErrCodeStreamClosed {
3868 t.Fatalf("got RSTStreamFrame with error code %v, want ErrCodeNo or ErrCodeStreamClosed", rst.ErrCode)
3869 }
3870 break
3871 }
3872 }
3873 }
3874
3875 func TestIssue20704Race(t *testing.T) { synctest.Test(t, testIssue20704Race) }
3876 func testIssue20704Race(t *testing.T) {
3877 if testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" {
3878 t.Skip("skipping in short mode")
3879 }
3880 const (
3881 itemSize = 1 << 10
3882 itemCount = 100
3883 )
3884
3885 ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
3886 for range itemCount {
3887 _, err := w.Write(make([]byte, itemSize))
3888 if err != nil {
3889 return
3890 }
3891 }
3892 })
3893
3894 tr := &http.Transport{
3895 TLSClientConfig: tlsConfigInsecure,
3896 Protocols: protocols("h2"),
3897 }
3898 defer tr.CloseIdleConnections()
3899 cl := &http.Client{Transport: tr}
3900
3901 for range 1000 {
3902 resp, err := cl.Get(ts.URL)
3903 if err != nil {
3904 t.Fatal(err)
3905 }
3906
3907
3908 resp.Body.Close()
3909 }
3910 }
3911
3912 func TestServer_Rejects_TooSmall(t *testing.T) { synctest.Test(t, testServer_Rejects_TooSmall) }
3913 func testServer_Rejects_TooSmall(t *testing.T) {
3914 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
3915 io.ReadAll(r.Body)
3916 return nil
3917 }, func(st *serverTester) {
3918 st.writeHeaders(HeadersFrameParam{
3919 StreamID: 1,
3920 BlockFragment: st.encodeHeader(
3921 ":method", "POST",
3922 "content-length", "4",
3923 ),
3924 EndStream: false,
3925 EndHeaders: true,
3926 })
3927 st.writeData(1, true, []byte("12345"))
3928 st.wantRSTStream(1, ErrCodeProtocol)
3929 st.wantConnFlowControlConsumed(0)
3930 })
3931 }
3932
3933
3934
3935 func TestServerHandlerConnectionClose(t *testing.T) {
3936 synctest.Test(t, testServerHandlerConnectionClose)
3937 }
3938 func testServerHandlerConnectionClose(t *testing.T) {
3939 unblockHandler := make(chan bool, 1)
3940 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
3941 w.Header().Set("Connection", "close")
3942 w.Header().Set("Foo", "bar")
3943 w.(http.Flusher).Flush()
3944 <-unblockHandler
3945 return nil
3946 }, func(st *serverTester) {
3947 defer close(unblockHandler)
3948 st.writeHeaders(HeadersFrameParam{
3949 StreamID: 1,
3950 BlockFragment: st.encodeHeader(),
3951 EndStream: true,
3952 EndHeaders: true,
3953 })
3954 var sawGoAway bool
3955 var sawRes bool
3956 var sawWindowUpdate bool
3957 for {
3958 f := st.readFrame()
3959 if f == nil {
3960 break
3961 }
3962 switch f := f.(type) {
3963 case *GoAwayFrame:
3964 sawGoAway = true
3965 if f.LastStreamID != 1 || f.ErrCode != ErrCodeNo {
3966 t.Errorf("unexpected GOAWAY frame: %v", SummarizeFrame(f))
3967 }
3968
3969
3970 st.writeHeaders(HeadersFrameParam{
3971 StreamID: 3,
3972 BlockFragment: st.encodeHeader(),
3973 EndStream: false,
3974 EndHeaders: true,
3975 })
3976 st.fr.WriteRSTStream(3, ErrCodeCancel)
3977
3978
3979
3980 st.writeHeaders(HeadersFrameParam{
3981 StreamID: 5,
3982 BlockFragment: st.encodeHeader(),
3983 EndStream: false,
3984 EndHeaders: true,
3985 })
3986
3987 st.writeData(5, true, make([]byte, 1<<19))
3988 case *HeadersFrame:
3989 goth := st.decodeHeader(f.HeaderBlockFragment())
3990 wanth := [][2]string{
3991 {":status", "200"},
3992 {"foo", "bar"},
3993 }
3994 if !reflect.DeepEqual(goth, wanth) {
3995 t.Errorf("got headers %v; want %v", goth, wanth)
3996 }
3997 sawRes = true
3998 case *DataFrame:
3999 if f.StreamID != 1 || !f.StreamEnded() || len(f.Data()) != 0 {
4000 t.Errorf("unexpected DATA frame: %v", SummarizeFrame(f))
4001 }
4002 case *WindowUpdateFrame:
4003 if !sawGoAway {
4004 t.Errorf("unexpected WINDOW_UPDATE frame: %v", SummarizeFrame(f))
4005 return
4006 }
4007 if f.StreamID != 0 {
4008 st.t.Fatalf("WindowUpdate StreamID = %d; want 5", f.FrameHeader.StreamID)
4009 return
4010 }
4011 sawWindowUpdate = true
4012 unblockHandler <- true
4013 st.sync()
4014 st.advance(GoAwayTimeout)
4015 default:
4016 t.Logf("unexpected frame: %v", SummarizeFrame(f))
4017 }
4018 }
4019 if !sawGoAway {
4020 t.Errorf("didn't see GOAWAY")
4021 }
4022 if !sawRes {
4023 t.Errorf("didn't see response")
4024 }
4025 if !sawWindowUpdate {
4026 t.Errorf("didn't see WINDOW_UPDATE")
4027 }
4028 })
4029 }
4030
4031 func TestServer_Headers_HalfCloseRemote(t *testing.T) {
4032 synctest.Test(t, testServer_Headers_HalfCloseRemote)
4033 }
4034 func testServer_Headers_HalfCloseRemote(t *testing.T) {
4035 var st *serverTester
4036 writeData := make(chan bool)
4037 writeHeaders := make(chan bool)
4038 leaveHandler := make(chan bool)
4039 st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4040 if !st.streamExists(1) {
4041 t.Errorf("stream 1 does not exist in handler")
4042 }
4043 if got, want := st.streamState(1), StateOpen; got != want {
4044 t.Errorf("in handler, state is %v; want %v", got, want)
4045 }
4046 writeData <- true
4047 if n, err := r.Body.Read(make([]byte, 1)); n != 0 || err != io.EOF {
4048 t.Errorf("body read = %d, %v; want 0, EOF", n, err)
4049 }
4050 if got, want := st.streamState(1), StateHalfClosedRemote; got != want {
4051 t.Errorf("in handler, state is %v; want %v", got, want)
4052 }
4053 writeHeaders <- true
4054
4055 <-leaveHandler
4056 })
4057 st.greet()
4058
4059 st.writeHeaders(HeadersFrameParam{
4060 StreamID: 1,
4061 BlockFragment: st.encodeHeader(),
4062 EndStream: false,
4063 EndHeaders: true,
4064 })
4065 <-writeData
4066 st.writeData(1, true, nil)
4067
4068 <-writeHeaders
4069
4070 st.writeHeaders(HeadersFrameParam{
4071 StreamID: 1,
4072 BlockFragment: st.encodeHeader(),
4073 EndStream: false,
4074 EndHeaders: true,
4075 })
4076
4077 defer close(leaveHandler)
4078
4079 st.wantRSTStream(1, ErrCodeStreamClosed)
4080 }
4081
4082 func TestServerGracefulShutdown(t *testing.T) { synctest.Test(t, testServerGracefulShutdown) }
4083 func testServerGracefulShutdown(t *testing.T) {
4084 handlerDone := make(chan struct{})
4085 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4086 <-handlerDone
4087 w.Header().Set("x-foo", "bar")
4088 })
4089 defer st.Close()
4090
4091 st.greet()
4092 st.bodylessReq1()
4093
4094 st.sync()
4095
4096 shutdownc := make(chan struct{})
4097 go func() {
4098 defer close(shutdownc)
4099 st.h1server.Shutdown(context.Background())
4100 }()
4101
4102 st.wantGoAway(1, ErrCodeNo)
4103
4104 close(handlerDone)
4105 st.sync()
4106
4107 st.wantHeaders(wantHeader{
4108 streamID: 1,
4109 endStream: true,
4110 header: http.Header{
4111 ":status": []string{"200"},
4112 "x-foo": []string{"bar"},
4113 "content-length": []string{"0"},
4114 },
4115 })
4116
4117 n, err := st.cc.Read([]byte{0})
4118 if n != 0 || err == nil {
4119 t.Errorf("Read = %v, %v; want 0, non-nil", n, err)
4120 }
4121
4122
4123 <-shutdownc
4124 }
4125
4126
4127 func TestContentEncodingNoSniffing(t *testing.T) {
4128 type resp struct {
4129 name string
4130 body []byte
4131
4132
4133
4134 contentEncoding any
4135 wantContentType string
4136 }
4137
4138 resps := []*resp{
4139 {
4140 name: "gzip content-encoding, gzipped",
4141 contentEncoding: "application/gzip",
4142 wantContentType: "",
4143 body: func() []byte {
4144 buf := new(bytes.Buffer)
4145 gzw := gzip.NewWriter(buf)
4146 gzw.Write([]byte("doctype html><p>Hello</p>"))
4147 gzw.Close()
4148 return buf.Bytes()
4149 }(),
4150 },
4151 {
4152 name: "zlib content-encoding, zlibbed",
4153 contentEncoding: "application/zlib",
4154 wantContentType: "",
4155 body: func() []byte {
4156 buf := new(bytes.Buffer)
4157 zw := zlib.NewWriter(buf)
4158 zw.Write([]byte("doctype html><p>Hello</p>"))
4159 zw.Close()
4160 return buf.Bytes()
4161 }(),
4162 },
4163 {
4164 name: "no content-encoding",
4165 wantContentType: "application/x-gzip",
4166 body: func() []byte {
4167 buf := new(bytes.Buffer)
4168 gzw := gzip.NewWriter(buf)
4169 gzw.Write([]byte("doctype html><p>Hello</p>"))
4170 gzw.Close()
4171 return buf.Bytes()
4172 }(),
4173 },
4174 {
4175 name: "phony content-encoding",
4176 contentEncoding: "foo/bar",
4177 body: []byte("doctype html><p>Hello</p>"),
4178 },
4179 {
4180 name: "empty but set content-encoding",
4181 contentEncoding: "",
4182 wantContentType: "audio/mpeg",
4183 body: []byte("ID3"),
4184 },
4185 }
4186
4187 for _, tt := range resps {
4188 synctestSubtest(t, tt.name, func(t *testing.T) {
4189 ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
4190 if tt.contentEncoding != nil {
4191 w.Header().Set("Content-Encoding", tt.contentEncoding.(string))
4192 }
4193 w.Write(tt.body)
4194 })
4195
4196 tr := &http.Transport{
4197 TLSClientConfig: tlsConfigInsecure,
4198 Protocols: protocols("h2"),
4199 }
4200 defer tr.CloseIdleConnections()
4201
4202 req, _ := http.NewRequest("GET", ts.URL, nil)
4203 res, err := tr.RoundTrip(req)
4204 if err != nil {
4205 t.Fatalf("GET %s: %v", ts.URL, err)
4206 }
4207 defer res.Body.Close()
4208
4209 g := res.Header.Get("Content-Encoding")
4210 t.Logf("%s: Content-Encoding: %s", ts.URL, g)
4211
4212 if w := tt.contentEncoding; g != w {
4213 if w != nil {
4214 t.Errorf("Content-Encoding mismatch\n\tgot: %q\n\twant: %q", g, w)
4215 } else if g != "" {
4216 t.Errorf("Unexpected Content-Encoding %q", g)
4217 }
4218 }
4219
4220 g = res.Header.Get("Content-Type")
4221 if w := tt.wantContentType; g != w {
4222 t.Errorf("Content-Type mismatch\n\tgot: %q\n\twant: %q", g, w)
4223 }
4224 t.Logf("%s: Content-Type: %s", ts.URL, g)
4225 })
4226 }
4227 }
4228
4229 func TestServerWindowUpdateOnBodyClose(t *testing.T) {
4230 synctest.Test(t, testServerWindowUpdateOnBodyClose)
4231 }
4232 func testServerWindowUpdateOnBodyClose(t *testing.T) {
4233 const windowSize = 65535 * 2
4234 content := make([]byte, windowSize)
4235 errc := make(chan error)
4236 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4237 buf := make([]byte, 4)
4238 n, err := io.ReadFull(r.Body, buf)
4239 if err != nil {
4240 errc <- err
4241 return
4242 }
4243 if n != len(buf) {
4244 errc <- fmt.Errorf("too few bytes read: %d", n)
4245 return
4246 }
4247 r.Body.Close()
4248 errc <- nil
4249 }, func(h2 *http.HTTP2Config) {
4250 h2.MaxReceiveBufferPerConnection = windowSize
4251 h2.MaxReceiveBufferPerStream = windowSize
4252 })
4253 defer st.Close()
4254
4255 st.greet()
4256 st.writeHeaders(HeadersFrameParam{
4257 StreamID: 1,
4258 BlockFragment: st.encodeHeader(
4259 ":method", "POST",
4260 "content-length", strconv.Itoa(len(content)),
4261 ),
4262 EndStream: false,
4263 EndHeaders: true,
4264 })
4265 st.writeData(1, false, content[:windowSize/2])
4266 if err := <-errc; err != nil {
4267 t.Fatal(err)
4268 }
4269
4270
4271 increments := windowSize / 2
4272 for {
4273 f := st.readFrame()
4274 if f == nil {
4275 break
4276 }
4277 if wu, ok := f.(*WindowUpdateFrame); ok && wu.StreamID == 0 {
4278 increments -= int(wu.Increment)
4279 if increments == 0 {
4280 break
4281 }
4282 }
4283 }
4284
4285 st.wantHeaders(wantHeader{
4286 streamID: 1,
4287 endStream: true,
4288 })
4289
4290
4291 st.writeData(1, false, content[windowSize/2:])
4292 st.wantUnorderedFrames(
4293 func(f *WindowUpdateFrame) bool {
4294 return f.StreamID == 0 && f.Increment == windowSize/2
4295 },
4296 func(f *RSTStreamFrame) bool {
4297 return f.StreamID == 1 && f.ErrCode == ErrCodeStreamClosed
4298 },
4299 )
4300 }
4301
4302 func TestNoErrorLoggedOnPostAfterGOAWAY(t *testing.T) {
4303 synctest.Test(t, testNoErrorLoggedOnPostAfterGOAWAY)
4304 }
4305 func testNoErrorLoggedOnPostAfterGOAWAY(t *testing.T) {
4306 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {})
4307 defer st.Close()
4308
4309 st.greet()
4310
4311 content := "some content"
4312 st.writeHeaders(HeadersFrameParam{
4313 StreamID: 1,
4314 BlockFragment: st.encodeHeader(
4315 ":method", "POST",
4316 "content-length", strconv.Itoa(len(content)),
4317 ),
4318 EndStream: false,
4319 EndHeaders: true,
4320 })
4321 st.wantHeaders(wantHeader{
4322 streamID: 1,
4323 endStream: true,
4324 })
4325
4326 st.sc.StartGracefulShutdown()
4327 st.wantRSTStream(1, ErrCodeNo)
4328 st.wantGoAway(1, ErrCodeNo)
4329
4330 st.writeData(1, true, []byte(content))
4331 st.Close()
4332
4333 if bytes.Contains(st.serverLogBuf.Bytes(), []byte("PROTOCOL_ERROR")) {
4334 t.Error("got protocol error")
4335 }
4336 }
4337
4338 func TestServerSendsProcessing(t *testing.T) { synctest.Test(t, testServerSendsProcessing) }
4339 func testServerSendsProcessing(t *testing.T) {
4340 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
4341 w.WriteHeader(http.StatusProcessing)
4342 w.Write([]byte("stuff"))
4343
4344 return nil
4345 }, func(st *serverTester) {
4346 getSlash(st)
4347 st.wantHeaders(wantHeader{
4348 streamID: 1,
4349 endStream: false,
4350 header: http.Header{
4351 ":status": []string{"102"},
4352 },
4353 })
4354 st.wantHeaders(wantHeader{
4355 streamID: 1,
4356 endStream: false,
4357 header: http.Header{
4358 ":status": []string{"200"},
4359 "content-type": []string{"text/plain; charset=utf-8"},
4360 "content-length": []string{"5"},
4361 },
4362 })
4363 })
4364 }
4365
4366 func TestServerSendsEarlyHints(t *testing.T) { synctest.Test(t, testServerSendsEarlyHints) }
4367 func testServerSendsEarlyHints(t *testing.T) {
4368 testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
4369 h := w.Header()
4370 h.Add("Content-Length", "123")
4371 h.Add("Link", "</style.css>; rel=preload; as=style")
4372 h.Add("Link", "</script.js>; rel=preload; as=script")
4373 w.WriteHeader(http.StatusEarlyHints)
4374
4375 h.Add("Link", "</foo.js>; rel=preload; as=script")
4376 w.WriteHeader(http.StatusEarlyHints)
4377
4378 w.Write([]byte("stuff"))
4379
4380 return nil
4381 }, func(st *serverTester) {
4382 getSlash(st)
4383 st.wantHeaders(wantHeader{
4384 streamID: 1,
4385 endStream: false,
4386 header: http.Header{
4387 ":status": []string{"103"},
4388 "link": []string{
4389 "</style.css>; rel=preload; as=style",
4390 "</script.js>; rel=preload; as=script",
4391 },
4392 },
4393 })
4394 st.wantHeaders(wantHeader{
4395 streamID: 1,
4396 endStream: false,
4397 header: http.Header{
4398 ":status": []string{"103"},
4399 "link": []string{
4400 "</style.css>; rel=preload; as=style",
4401 "</script.js>; rel=preload; as=script",
4402 "</foo.js>; rel=preload; as=script",
4403 },
4404 },
4405 })
4406 st.wantHeaders(wantHeader{
4407 streamID: 1,
4408 endStream: false,
4409 header: http.Header{
4410 ":status": []string{"200"},
4411 "link": []string{
4412 "</style.css>; rel=preload; as=style",
4413 "</script.js>; rel=preload; as=script",
4414 "</foo.js>; rel=preload; as=script",
4415 },
4416 "content-type": []string{"text/plain; charset=utf-8"},
4417 "content-length": []string{"123"},
4418 },
4419 })
4420 })
4421 }
4422
4423 func TestProtocolErrorAfterGoAway(t *testing.T) { synctest.Test(t, testProtocolErrorAfterGoAway) }
4424 func testProtocolErrorAfterGoAway(t *testing.T) {
4425 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4426 io.Copy(io.Discard, r.Body)
4427 })
4428 defer st.Close()
4429
4430 st.greet()
4431 content := "some content"
4432 st.writeHeaders(HeadersFrameParam{
4433 StreamID: 1,
4434 BlockFragment: st.encodeHeader(
4435 ":method", "POST",
4436 "content-length", strconv.Itoa(len(content)),
4437 ),
4438 EndStream: false,
4439 EndHeaders: true,
4440 })
4441 st.writeData(1, false, []byte(content[:5]))
4442
4443
4444
4445 if err := st.fr.WriteGoAway(1, ErrCodeNo, nil); err != nil {
4446 t.Fatal(err)
4447 }
4448 if err := st.fr.WriteWindowUpdate(0, 1<<31-1); err != nil {
4449 t.Fatal(err)
4450 }
4451
4452 st.advance(GoAwayTimeout)
4453 st.wantGoAway(1, ErrCodeNo)
4454 st.wantClosed()
4455 }
4456
4457 func TestServerInitialFlowControlWindow(t *testing.T) {
4458 for _, want := range []int32{
4459 65535,
4460 1 << 19,
4461 1 << 21,
4462
4463
4464
4465
4466
4467 65535 * 2,
4468 } {
4469 synctestSubtest(t, fmt.Sprint(want), func(t *testing.T) {
4470
4471 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4472 }, func(h2 *http.HTTP2Config) {
4473 h2.MaxReceiveBufferPerConnection = int(want)
4474 })
4475 st.writePreface()
4476 st.writeSettings()
4477 _ = readFrame[*SettingsFrame](t, st)
4478 st.writeSettingsAck()
4479 st.writeHeaders(HeadersFrameParam{
4480 StreamID: 1,
4481 BlockFragment: st.encodeHeader(),
4482 EndStream: true,
4483 EndHeaders: true,
4484 })
4485 window := 65535
4486 Frames:
4487 for {
4488 f := st.readFrame()
4489 switch f := f.(type) {
4490 case *WindowUpdateFrame:
4491 if f.FrameHeader.StreamID != 0 {
4492 t.Errorf("WindowUpdate StreamID = %d; want 0", f.FrameHeader.StreamID)
4493 return
4494 }
4495 window += int(f.Increment)
4496 case *HeadersFrame:
4497 break Frames
4498 case nil:
4499 break Frames
4500 default:
4501 }
4502 }
4503 if window != int(want) {
4504 t.Errorf("got initial flow control window = %v, want %v", window, want)
4505 }
4506 })
4507 }
4508 }
4509
4510
4511
4512
4513
4514
4515 func TestServerWriteDoesNotRetainBufferAfterReturn(t *testing.T) {
4516 synctest.Test(t, testServerWriteDoesNotRetainBufferAfterReturn)
4517 }
4518 func testServerWriteDoesNotRetainBufferAfterReturn(t *testing.T) {
4519 donec := make(chan struct{})
4520 ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
4521 defer close(donec)
4522 buf := make([]byte, 1<<20)
4523 var i byte
4524 for {
4525 i++
4526 _, err := w.Write(buf)
4527 for j := range buf {
4528 buf[j] = byte(i)
4529 }
4530 if err != nil {
4531 return
4532 }
4533 }
4534 })
4535
4536 tr := &http.Transport{
4537 TLSClientConfig: tlsConfigInsecure,
4538 Protocols: protocols("h2"),
4539 }
4540 defer tr.CloseIdleConnections()
4541
4542 req, _ := http.NewRequest("GET", ts.URL, nil)
4543 res, err := tr.RoundTrip(req)
4544 if err != nil {
4545 t.Fatal(err)
4546 }
4547 res.Body.Close()
4548 <-donec
4549 }
4550
4551
4552
4553
4554
4555
4556 func TestServerWriteDoesNotRetainBufferAfterServerClose(t *testing.T) {
4557 synctest.Test(t, testServerWriteDoesNotRetainBufferAfterServerClose)
4558 }
4559 func testServerWriteDoesNotRetainBufferAfterServerClose(t *testing.T) {
4560 donec := make(chan struct{}, 1)
4561 ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
4562 donec <- struct{}{}
4563 defer close(donec)
4564 buf := make([]byte, 1<<20)
4565 var i byte
4566 for {
4567 i++
4568 _, err := w.Write(buf)
4569 for j := range buf {
4570 buf[j] = byte(i)
4571 }
4572 if err != nil {
4573 return
4574 }
4575 }
4576 })
4577
4578 tr := &http.Transport{
4579 TLSClientConfig: tlsConfigInsecure,
4580 Protocols: protocols("h2"),
4581 }
4582 defer tr.CloseIdleConnections()
4583
4584 req, _ := http.NewRequest("GET", ts.URL, nil)
4585 res, err := tr.RoundTrip(req)
4586 if err != nil {
4587 t.Fatal(err)
4588 }
4589 defer res.Body.Close()
4590 <-donec
4591 ts.Config.Close()
4592 <-donec
4593 }
4594
4595 func TestServerMaxHandlerGoroutines(t *testing.T) { synctest.Test(t, testServerMaxHandlerGoroutines) }
4596 func testServerMaxHandlerGoroutines(t *testing.T) {
4597 const maxHandlers = 10
4598 handlerc := make(chan chan bool)
4599 donec := make(chan struct{})
4600 defer close(donec)
4601 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4602 stopc := make(chan bool, 1)
4603 select {
4604 case handlerc <- stopc:
4605 case <-donec:
4606 }
4607 select {
4608 case shouldPanic := <-stopc:
4609 if shouldPanic {
4610 panic(http.ErrAbortHandler)
4611 }
4612 case <-donec:
4613 }
4614 }, func(h2 *http.HTTP2Config) {
4615 h2.MaxConcurrentStreams = maxHandlers
4616 })
4617 defer st.Close()
4618
4619 st.greet()
4620
4621
4622
4623 var stops []chan bool
4624 streamID := uint32(1)
4625 for range maxHandlers {
4626 st.writeHeaders(HeadersFrameParam{
4627 StreamID: streamID,
4628 BlockFragment: st.encodeHeader(),
4629 EndStream: true,
4630 EndHeaders: true,
4631 })
4632 stops = append(stops, <-handlerc)
4633 st.fr.WriteRSTStream(streamID, ErrCodeCancel)
4634 streamID += 2
4635 }
4636
4637
4638 st.writeHeaders(HeadersFrameParam{
4639 StreamID: streamID,
4640 BlockFragment: st.encodeHeader(),
4641 EndStream: true,
4642 EndHeaders: true,
4643 })
4644 st.fr.WriteRSTStream(streamID, ErrCodeCancel)
4645 streamID += 2
4646
4647
4648 for range 2 {
4649 st.writeHeaders(HeadersFrameParam{
4650 StreamID: streamID,
4651 BlockFragment: st.encodeHeader(),
4652 EndStream: true,
4653 EndHeaders: true,
4654 })
4655 streamID += 2
4656 }
4657
4658
4659
4660 select {
4661 case <-handlerc:
4662 t.Errorf("handler unexpectedly started while maxHandlers are already running")
4663 case <-time.After(1 * time.Millisecond):
4664 }
4665
4666
4667
4668 stops[0] <- false
4669 stops[1] <- true
4670 stops = stops[2:]
4671 stops = append(stops, <-handlerc)
4672 stops = append(stops, <-handlerc)
4673
4674
4675
4676 for range 5 * maxHandlers {
4677 st.writeHeaders(HeadersFrameParam{
4678 StreamID: streamID,
4679 BlockFragment: st.encodeHeader(),
4680 EndStream: true,
4681 EndHeaders: true,
4682 })
4683 st.fr.WriteRSTStream(streamID, ErrCodeCancel)
4684 streamID += 2
4685 }
4686 fr := readFrame[*GoAwayFrame](t, st)
4687 if fr.ErrCode != ErrCodeEnhanceYourCalm {
4688 t.Errorf("err code = %v; want %v", fr.ErrCode, ErrCodeEnhanceYourCalm)
4689 }
4690
4691 for _, s := range stops {
4692 close(s)
4693 }
4694 }
4695
4696 func TestServerContinuationFlood(t *testing.T) { synctest.Test(t, testServerContinuationFlood) }
4697 func testServerContinuationFlood(t *testing.T) {
4698 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4699 fmt.Println(r.Header)
4700 }, func(s *http.Server) {
4701 s.MaxHeaderBytes = 4096
4702 })
4703 defer st.Close()
4704
4705 st.greet()
4706
4707 st.writeHeaders(HeadersFrameParam{
4708 StreamID: 1,
4709 BlockFragment: st.encodeHeader(),
4710 EndStream: true,
4711 })
4712 for i := range 1000 {
4713 st.fr.WriteContinuation(1, false, st.encodeHeaderRaw(
4714 fmt.Sprintf("x-%v", i), "1234567890",
4715 ))
4716 }
4717 st.fr.WriteContinuation(1, true, st.encodeHeaderRaw(
4718 "x-last-header", "1",
4719 ))
4720
4721 for {
4722 f := st.readFrame()
4723 if f == nil {
4724 break
4725 }
4726 switch f := f.(type) {
4727 case *HeadersFrame:
4728 t.Fatalf("received HEADERS frame; want GOAWAY and a closed connection")
4729 case *GoAwayFrame:
4730
4731
4732
4733 if got, want := f.LastStreamID, uint32(1); got != want {
4734 t.Errorf("received GOAWAY with LastStreamId %v, want %v", got, want)
4735 }
4736
4737 }
4738 }
4739
4740
4741
4742
4743
4744
4745
4746
4747 }
4748
4749 func TestServerContinuationAfterInvalidHeader(t *testing.T) {
4750 synctest.Test(t, testServerContinuationAfterInvalidHeader)
4751 }
4752 func testServerContinuationAfterInvalidHeader(t *testing.T) {
4753 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4754 fmt.Println(r.Header)
4755 })
4756 defer st.Close()
4757
4758 st.greet()
4759
4760 st.writeHeaders(HeadersFrameParam{
4761 StreamID: 1,
4762 BlockFragment: st.encodeHeader(),
4763 EndStream: true,
4764 })
4765 st.fr.WriteContinuation(1, false, st.encodeHeaderRaw(
4766 "x-invalid-header", "\x00",
4767 ))
4768 st.fr.WriteContinuation(1, true, st.encodeHeaderRaw(
4769 "x-valid-header", "1",
4770 ))
4771
4772 var sawGoAway bool
4773 for {
4774 f := st.readFrame()
4775 if f == nil {
4776 break
4777 }
4778 switch f.(type) {
4779 case *GoAwayFrame:
4780 sawGoAway = true
4781 case *HeadersFrame:
4782 t.Fatalf("received HEADERS frame; want GOAWAY")
4783 }
4784 }
4785 if !sawGoAway {
4786 t.Errorf("connection closed with no GOAWAY frame; want one")
4787 }
4788 }
4789
4790
4791 func TestServerRequestCancelOnError(t *testing.T) { synctest.Test(t, testServerRequestCancelOnError) }
4792 func testServerRequestCancelOnError(t *testing.T) {
4793 recvc := make(chan struct{})
4794 donec := make(chan struct{})
4795 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4796 close(recvc)
4797 <-r.Context().Done()
4798 close(donec)
4799 })
4800 defer st.Close()
4801
4802 st.greet()
4803
4804
4805 st.writeHeaders(HeadersFrameParam{
4806 StreamID: 1,
4807 BlockFragment: st.encodeHeader(),
4808 EndStream: true,
4809 EndHeaders: true,
4810 })
4811 <-recvc
4812
4813
4814
4815
4816 st.writeHeaders(HeadersFrameParam{
4817 StreamID: 1,
4818 BlockFragment: st.encodeHeader(),
4819 EndStream: true,
4820 EndHeaders: true,
4821 })
4822 <-donec
4823 }
4824
4825 func TestServerSetReadWriteDeadlineRace(t *testing.T) {
4826 synctest.Test(t, testServerSetReadWriteDeadlineRace)
4827 }
4828 func testServerSetReadWriteDeadlineRace(t *testing.T) {
4829 ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
4830 ctl := http.NewResponseController(w)
4831 ctl.SetReadDeadline(time.Now().Add(3600 * time.Second))
4832 ctl.SetWriteDeadline(time.Now().Add(3600 * time.Second))
4833 })
4834 resp, err := ts.Client().Get(ts.URL)
4835 if err != nil {
4836 t.Fatal(err)
4837 }
4838 resp.Body.Close()
4839 }
4840
4841 func TestServerWriteByteTimeout(t *testing.T) { synctest.Test(t, testServerWriteByteTimeout) }
4842 func testServerWriteByteTimeout(t *testing.T) {
4843 const timeout = 1 * time.Second
4844 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4845 w.Write(make([]byte, 100))
4846 }, func(s *http.Server) {
4847
4848
4849
4850 s.Protocols = protocols("h2c")
4851 }, func(h2 *http.HTTP2Config) {
4852 h2.WriteByteTimeout = timeout
4853 })
4854 st.greet()
4855
4856 st.cc.(*synctestNetConn).SetReadBufferSize(1)
4857 st.writeHeaders(HeadersFrameParam{
4858 StreamID: 1,
4859 BlockFragment: st.encodeHeader(),
4860 EndStream: true,
4861 EndHeaders: true,
4862 })
4863
4864
4865 for i := range 10 {
4866 st.advance(timeout - 1)
4867 if n, err := st.cc.Read(make([]byte, 1)); n != 1 || err != nil {
4868 t.Fatalf("read %v: %v, %v; want 1, nil", i, n, err)
4869 }
4870 }
4871
4872
4873
4874 st.advance(1 * time.Second)
4875 st.advance(1 * time.Second)
4876 st.wantClosed()
4877 }
4878
4879 func TestServerPingSent(t *testing.T) { synctest.Test(t, testServerPingSent) }
4880 func testServerPingSent(t *testing.T) {
4881 const sendPingTimeout = 15 * time.Second
4882 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4883 }, func(h2 *http.HTTP2Config) {
4884 h2.SendPingTimeout = sendPingTimeout
4885 })
4886 st.greet()
4887
4888 st.wantIdle()
4889
4890 st.advance(sendPingTimeout)
4891 _ = readFrame[*PingFrame](t, st)
4892 st.wantIdle()
4893
4894 st.advance(14 * time.Second)
4895 st.wantIdle()
4896 st.advance(1 * time.Second)
4897 st.wantClosed()
4898 }
4899
4900 func TestServerPingResponded(t *testing.T) { synctest.Test(t, testServerPingResponded) }
4901 func testServerPingResponded(t *testing.T) {
4902 const sendPingTimeout = 15 * time.Second
4903 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4904 }, func(h2 *http.HTTP2Config) {
4905 h2.SendPingTimeout = sendPingTimeout
4906 })
4907 st.greet()
4908
4909 st.wantIdle()
4910
4911 st.advance(sendPingTimeout)
4912 pf := readFrame[*PingFrame](t, st)
4913 st.wantIdle()
4914
4915 st.advance(14 * time.Second)
4916 st.wantIdle()
4917
4918 st.writePing(true, pf.Data)
4919
4920 st.advance(2 * time.Second)
4921 st.wantIdle()
4922 }
4923
4924
4925
4926
4927
4928 func TestServerSendDataAfterRequestBodyClose(t *testing.T) {
4929 synctest.Test(t, testServerSendDataAfterRequestBodyClose)
4930 }
4931 func testServerSendDataAfterRequestBodyClose(t *testing.T) {
4932 st := newServerTester(t, nil)
4933 st.greet()
4934
4935 st.writeHeaders(HeadersFrameParam{
4936 StreamID: 1,
4937 BlockFragment: st.encodeHeader(),
4938 EndStream: false,
4939 EndHeaders: true,
4940 })
4941
4942
4943 call := st.nextHandlerCall()
4944 call.do(func(w http.ResponseWriter, req *http.Request) {
4945 w.Write([]byte("one"))
4946 http.NewResponseController(w).Flush()
4947 })
4948 st.wantFrameType(FrameHeaders)
4949 st.wantData(wantData{
4950 streamID: 1,
4951 endStream: false,
4952 data: []byte("one"),
4953 })
4954 st.wantIdle()
4955
4956
4957
4958 call.do(func(w http.ResponseWriter, req *http.Request) {
4959 req.Body.Close()
4960 })
4961 st.wantIdle()
4962
4963
4964 st.writeData(1, false, []byte("client-sent data"))
4965 st.wantIdle()
4966
4967
4968
4969 call.do(func(w http.ResponseWriter, req *http.Request) {
4970 w.Write([]byte("two"))
4971 http.NewResponseController(w).Flush()
4972 })
4973 st.wantData(wantData{
4974 streamID: 1,
4975 endStream: false,
4976 data: []byte("two"),
4977 })
4978 st.wantIdle()
4979 }
4980
4981 func TestServerSettingNoRFC7540Priorities(t *testing.T) {
4982 synctest.Test(t, testServerSettingNoRFC7540Priorities)
4983 }
4984 func testServerSettingNoRFC7540Priorities(t *testing.T) {
4985 const wantNoRFC7540Setting = true
4986 st := newServerTester(t, nil)
4987 defer st.Close()
4988
4989 var gotNoRFC7540Setting bool
4990 st.greetAndCheckSettings(func(s Setting) error {
4991 if s.ID != SettingNoRFC7540Priorities {
4992 return nil
4993 }
4994 gotNoRFC7540Setting = s.Val == 1
4995 return nil
4996 })
4997 if wantNoRFC7540Setting != gotNoRFC7540Setting {
4998 t.Errorf("want SETTINGS_NO_RFC7540_PRIORITIES to be %v, got %v", wantNoRFC7540Setting, gotNoRFC7540Setting)
4999 }
5000 }
5001
5002 func TestServerSettingNoRFC7540PrioritiesInvalid(t *testing.T) {
5003 synctest.Test(t, testServerSettingNoRFC7540PrioritiesInvalid)
5004 }
5005 func testServerSettingNoRFC7540PrioritiesInvalid(t *testing.T) {
5006 st := newServerTester(t, nil)
5007 defer st.Close()
5008
5009 st.writePreface()
5010 st.writeSettings(Setting{ID: SettingNoRFC7540Priorities, Val: 2})
5011 synctest.Wait()
5012 st.readFrame()
5013 st.readFrame()
5014 st.wantGoAway(0, ErrCodeProtocol)
5015 }
5016
5017
5018
5019 func TestServerRFC9218PrioritySmallPayload(t *testing.T) {
5020 synctest.Test(t, testServerRFC9218PrioritySmallPayload)
5021 }
5022 func testServerRFC9218PrioritySmallPayload(t *testing.T) {
5023 endTest := false
5024 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
5025 for !endTest {
5026 w.Write([]byte("a"))
5027 if f, ok := w.(http.Flusher); ok {
5028 f.Flush()
5029 }
5030 }
5031 }, func(s *http.Server) {
5032 s.Protocols = protocols("h2c")
5033 })
5034 st.greet()
5035 if syncConn, ok := st.cc.(*synctestNetConn); ok {
5036 syncConn.SetReadBufferSize(1)
5037 } else {
5038 t.Fatal("Server connection is not synctestNetConn")
5039 }
5040 defer st.Close()
5041 defer func() { endTest = true }()
5042
5043
5044
5045
5046
5047
5048 for i := 1; i <= 19; i += 2 {
5049 urgency := uint8(0)
5050 if i > 10 {
5051 urgency = 7
5052 }
5053 st.writeHeaders(HeadersFrameParam{
5054 StreamID: uint32(i),
5055 BlockFragment: st.encodeHeader("priority", fmt.Sprintf("u=%d", urgency)),
5056 EndStream: true,
5057 EndHeaders: true,
5058 })
5059 synctest.Wait()
5060 }
5061
5062
5063
5064 streamWriteCount := make(map[uint32]int)
5065 totalWriteCount := 10000
5066 for range totalWriteCount {
5067 f := st.readFrame()
5068 if f == nil {
5069 break
5070 }
5071 streamWriteCount[f.Header().StreamID] += 1
5072 }
5073 for streamID, writeCount := range streamWriteCount {
5074 expectedWriteCount := totalWriteCount / len(streamWriteCount)
5075 errorMargin := expectedWriteCount / 100
5076 if writeCount >= expectedWriteCount+errorMargin || writeCount <= expectedWriteCount-errorMargin {
5077 t.Errorf("Expected stream %v to receive %v±%v writes, got %v", streamID, expectedWriteCount, errorMargin, writeCount)
5078 }
5079 }
5080 }
5081
5082 func TestServerRFC9218Priority(t *testing.T) {
5083 synctest.Test(t, testServerRFC9218Priority)
5084 }
5085 func testServerRFC9218Priority(t *testing.T) {
5086 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
5087 w.Write(slices.Repeat([]byte("a"), 16<<20))
5088 if f, ok := w.(http.Flusher); ok {
5089 f.Flush()
5090 }
5091 }, func(s *http.Server) {
5092 s.Protocols = protocols("h2c")
5093 })
5094 defer st.Close()
5095 st.greet()
5096 if syncConn, ok := st.cc.(*synctestNetConn); ok {
5097 syncConn.SetReadBufferSize(1)
5098 } else {
5099 t.Fatal("Server connection is not synctestNetConn")
5100 }
5101 st.writeWindowUpdate(0, 1<<30)
5102 synctest.Wait()
5103
5104
5105
5106 for i := range 8 {
5107 streamID := uint32(i*2 + 1)
5108 urgency := 7 - i
5109 st.writeHeaders(HeadersFrameParam{
5110 StreamID: streamID,
5111 BlockFragment: st.encodeHeader("priority", fmt.Sprintf("u=%d", urgency)),
5112 EndStream: true,
5113 EndHeaders: true,
5114 })
5115 }
5116 synctest.Wait()
5117
5118
5119
5120 lastFrame := make(map[uint32]int)
5121 for i := 0; ; i++ {
5122 f := st.readFrame()
5123 if f == nil {
5124 break
5125 }
5126 lastFrame[f.Header().StreamID] = i
5127 }
5128 for i := range 7 {
5129 streamID := uint32(i*2 + 1)
5130 nextStreamID := streamID + 2
5131 if lastFrame[streamID] < lastFrame[nextStreamID] {
5132 t.Errorf("stream %d finished before stream %d unexpectedly", streamID, nextStreamID)
5133 }
5134 }
5135 }
5136
5137 func TestServerRFC9218PriorityIgnoredWhenProxied(t *testing.T) {
5138 synctest.Test(t, testServerRFC9218PriorityIgnoredWhenProxied)
5139 }
5140 func testServerRFC9218PriorityIgnoredWhenProxied(t *testing.T) {
5141 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
5142 w.Write(slices.Repeat([]byte("a"), 16<<20))
5143 if f, ok := w.(http.Flusher); ok {
5144 f.Flush()
5145 }
5146 }, func(s *http.Server) {
5147 s.Protocols = protocols("h2c")
5148 })
5149 defer st.Close()
5150 st.greet()
5151 if syncConn, ok := st.cc.(*synctestNetConn); ok {
5152 syncConn.SetReadBufferSize(1)
5153 } else {
5154 t.Fatal("Server connection is not synctestNetConn")
5155 }
5156 st.writeWindowUpdate(0, 1<<30)
5157 synctest.Wait()
5158
5159
5160
5161
5162 for i := range 8 {
5163 streamID := uint32(i*2 + 1)
5164 urgency := 7 - i
5165 st.writeHeaders(HeadersFrameParam{
5166 StreamID: streamID,
5167 BlockFragment: st.encodeHeader("priority", fmt.Sprintf("u=%d", urgency), "via", "a proxy"),
5168 EndStream: true,
5169 EndHeaders: true,
5170 })
5171 }
5172 synctest.Wait()
5173 var streamFrameOrder []uint32
5174 for f := st.readFrame(); f != nil; f = st.readFrame() {
5175 streamFrameOrder = append(streamFrameOrder, f.Header().StreamID)
5176 }
5177
5178
5179
5180 half := streamFrameOrder[len(streamFrameOrder)/4 : len(streamFrameOrder)*3/4]
5181 if !slices.Equal(slices.Compact(half), half) {
5182 t.Errorf("want stream to be processed in round-robin manner when proxied, got: %v", streamFrameOrder)
5183 }
5184 }
5185
5186 func TestServerRFC9218PriorityAware(t *testing.T) {
5187 synctest.Test(t, testServerRFC9218PriorityAware)
5188 }
5189 func testServerRFC9218PriorityAware(t *testing.T) {
5190 st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
5191 w.Write(slices.Repeat([]byte("a"), 16<<20))
5192 if f, ok := w.(http.Flusher); ok {
5193 f.Flush()
5194 }
5195 }, func(s *http.Server) {
5196 s.Protocols = protocols("h2c")
5197 })
5198 defer st.Close()
5199 st.greet()
5200 if syncConn, ok := st.cc.(*synctestNetConn); ok {
5201 syncConn.SetReadBufferSize(1)
5202 } else {
5203 t.Fatal("Server connection is not synctestNetConn")
5204 }
5205 st.writeWindowUpdate(0, 1<<30)
5206 synctest.Wait()
5207
5208
5209
5210 streamCount := 10
5211 for i := range streamCount {
5212 streamID := uint32(i*2 + 1)
5213 st.writeHeaders(HeadersFrameParam{
5214 StreamID: streamID,
5215 BlockFragment: st.encodeHeader(),
5216 EndStream: true,
5217 EndHeaders: true,
5218 })
5219 }
5220 synctest.Wait()
5221 var streamFrameOrder []uint32
5222 for f := st.readFrame(); f != nil; f = st.readFrame() {
5223 streamFrameOrder = append(streamFrameOrder, f.Header().StreamID)
5224 }
5225
5226
5227
5228 half := streamFrameOrder[len(streamFrameOrder)/4 : len(streamFrameOrder)*3/4]
5229 if !slices.Equal(slices.Compact(half), half) {
5230 t.Errorf("want stream to be processed in round-robin manner when unaware of priority, got: %v", streamFrameOrder)
5231 }
5232
5233
5234
5235
5236 st.writePriorityUpdate(1, "")
5237 synctest.Wait()
5238
5239
5240
5241
5242
5243 streamFrameOrder = []uint32{}
5244 for i := range streamCount {
5245 i += streamCount
5246 streamID := uint32(i*2 + 1)
5247 st.writeHeaders(HeadersFrameParam{
5248 StreamID: streamID,
5249 BlockFragment: st.encodeHeader(),
5250 EndStream: true,
5251 EndHeaders: true,
5252 })
5253 }
5254 for f := st.readFrame(); f != nil; f = st.readFrame() {
5255 streamFrameOrder = append(streamFrameOrder, f.Header().StreamID)
5256 }
5257 if !slices.Equal(slices.Compact(half), half) {
5258 t.Errorf("want stream to be processed one-by-one to completion when aware of priority, got: %v", streamFrameOrder)
5259 }
5260 }
5261
5262 func TestServerInvalidPathHeader(t *testing.T) {
5263 synctest.Test(t, testServerInvalidPathHeader)
5264 }
5265 func testServerInvalidPathHeader(t *testing.T) {
5266 for _, path := range []string{
5267 "",
5268 "\x00",
5269 "https://example.com/",
5270 } {
5271 testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
5272 st.fr.AllowIllegalWrites = true
5273 st.writeHeaders(HeadersFrameParam{
5274 StreamID: 1,
5275 BlockFragment: st.encodeHeader(
5276 ":path", path,
5277 ),
5278 EndStream: true,
5279 EndHeaders: true,
5280 })
5281 })
5282 }
5283 }
5284
5285 func TestServerPathInitialSlashes(t *testing.T) {
5286 synctest.Test(t, testServerPathInitialSlashes)
5287 }
5288 func testServerPathInitialSlashes(t *testing.T) {
5289 st := newServerTester(t, nil)
5290 st.greet()
5291
5292
5293
5294 const path = "//narf.com/path"
5295 st.writeHeaders(HeadersFrameParam{
5296 StreamID: 1,
5297 BlockFragment: st.encodeHeader(
5298 ":path", path,
5299 ),
5300 EndStream: true,
5301 EndHeaders: true,
5302 })
5303
5304 call := st.nextHandlerCall()
5305 if got, want := call.req.URL.Host, ""; got != want {
5306 t.Errorf("got req.URL.Host %q, want %q", got, want)
5307 }
5308 if got, want := call.req.URL.Path, path; got != want {
5309 t.Errorf("got req.URL.Path %q, want %q", got, want)
5310 }
5311 }
5312
5313
5314
5315
5316
5317 func TestServerSettingsFlowControlUpdateBeyondLimit(t *testing.T) {
5318 synctest.Test(t, testServerSettingsFlowControlUpdateBeyondLimit)
5319 }
5320 func testServerSettingsFlowControlUpdateBeyondLimit(t *testing.T) {
5321 st := newServerTester(t, nil)
5322 st.greet()
5323
5324 st.writeHeaders(HeadersFrameParam{
5325 StreamID: 1,
5326 BlockFragment: st.encodeHeader(":method", "POST"),
5327 EndStream: false,
5328 EndHeaders: true,
5329 })
5330 call := st.nextHandlerCall()
5331 http.NewResponseController(call.w).Flush()
5332 st.wantFrameType(FrameHeaders)
5333
5334
5335 const windowIncrease = 1000
5336 st.writeWindowUpdate(1, windowIncrease)
5337 st.wantIdle()
5338
5339
5340 const maxWindowSize = (1 << 31) - 1
5341 const maxInitialWindowSize = maxWindowSize - windowIncrease
5342 st.writeSettings(Setting{SettingInitialWindowSize, maxInitialWindowSize + 1})
5343 st.wantSettingsAck()
5344
5345
5346 call.w.Write([]byte("hello"))
5347 http.NewResponseController(call.w).Flush()
5348
5349 st.wantGoAway(1, ErrCodeFlowControl)
5350 }
5351
5352
5353
5354 func TestServerSettingsFlowControlUpdateWithinLimit(t *testing.T) {
5355 synctest.Test(t, testServerSettingsFlowControlUpdateWithinLimit)
5356 }
5357 func testServerSettingsFlowControlUpdateWithinLimit(t *testing.T) {
5358 st := newServerTester(t, nil)
5359 st.greet()
5360
5361 st.writeHeaders(HeadersFrameParam{
5362 StreamID: 1,
5363 BlockFragment: st.encodeHeader(":method", "POST"),
5364 EndStream: false,
5365 EndHeaders: true,
5366 })
5367 call := st.nextHandlerCall()
5368 http.NewResponseController(call.w).Flush()
5369 st.wantFrameType(FrameHeaders)
5370
5371
5372 const windowIncrease = 1000
5373 st.writeWindowUpdate(1, windowIncrease)
5374 st.wantIdle()
5375
5376
5377 const maxWindowSize = (1 << 31) - 1
5378 const maxInitialWindowSize = maxWindowSize - windowIncrease
5379 st.writeSettings(Setting{SettingInitialWindowSize, maxInitialWindowSize})
5380 st.wantSettingsAck()
5381
5382 call.w.Write([]byte("hello"))
5383 http.NewResponseController(call.w).Flush()
5384 st.wantFrameType(FrameData)
5385 st.wantIdle()
5386 }
5387
5388 func TestConsistentConstants(t *testing.T) {
5389 if h1, h2 := http.DefaultMaxHeaderBytes, http2.DefaultMaxHeaderBytes; h1 != h2 {
5390 t.Errorf("DefaultMaxHeaderBytes: http (%v) != http2 (%v)", h1, h2)
5391 }
5392 if h1, h2 := http.TimeFormat, http2.TimeFormat; h1 != h2 {
5393 t.Errorf("TimeFormat: http (%v) != http2 (%v)", h1, h2)
5394 }
5395 }
5396
5397 var (
5398 testServerTLSConfig *tls.Config
5399 testClientTLSConfig *tls.Config
5400 )
5401
5402 func init() {
5403 cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
5404 if err != nil {
5405 panic(err)
5406 }
5407 testServerTLSConfig = &tls.Config{
5408 Certificates: []tls.Certificate{cert},
5409 NextProtos: []string{"h2"},
5410 }
5411
5412 x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
5413 if err != nil {
5414 panic(err)
5415 }
5416 certpool := x509.NewCertPool()
5417 certpool.AddCert(x509Cert)
5418 testClientTLSConfig = &tls.Config{
5419 InsecureSkipVerify: true,
5420 RootCAs: certpool,
5421 NextProtos: []string{"h2"},
5422 }
5423 }
5424
5425 func protocols(protos ...string) *http.Protocols {
5426 p := new(http.Protocols)
5427 for _, s := range protos {
5428 switch s {
5429 case "h1":
5430 p.SetHTTP1(true)
5431 case "h2":
5432 p.SetHTTP2(true)
5433 case "h2c":
5434 p.SetUnencryptedHTTP2(true)
5435 default:
5436 panic("unknown protocol: " + s)
5437 }
5438 }
5439 return p
5440 }
5441
5442
5443 func transportFromH1Transport(tr *http.Transport) any
5444
View as plain text