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