| // Copyright 2024 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| //go:build !(go1.27 && !http2legacy) | |
| package http2_test | |
| import ( | |
| "net/http" | |
| "testing" | |
| "time" | |
| . "golang.org/x/net/http2" | |
| ) | |
| func TestConfigServerSettings(t *testing.T) { synctestTest(t, testConfigServerSettings) } | |
| func testConfigServerSettings(t testing.TB) { | |
| config := &http.HTTP2Config{ | |
| MaxConcurrentStreams: 1, | |
| MaxDecoderHeaderTableSize: 1<<20 + 2, | |
| MaxEncoderHeaderTableSize: 1<<20 + 3, | |
| MaxReadFrameSize: 1<<20 + 4, | |
| MaxReceiveBufferPerConnection: 64<<10 + 5, | |
| MaxReceiveBufferPerStream: 64<<10 + 6, | |
| } | |
| const maxHeaderBytes = 4096 + 7 | |
| st := newServerTester(t, nil, func(s *http.Server) { | |
| s.MaxHeaderBytes = maxHeaderBytes | |
| s.HTTP2 = config | |
| }) | |
| st.writePreface() | |
| st.writeSettings() | |
| st.wantSettings(map[SettingID]uint32{ | |
| SettingMaxConcurrentStreams: uint32(config.MaxConcurrentStreams), | |
| SettingHeaderTableSize: uint32(config.MaxDecoderHeaderTableSize), | |
| SettingInitialWindowSize: uint32(config.MaxReceiveBufferPerStream), | |
| SettingMaxFrameSize: uint32(config.MaxReadFrameSize), | |
| SettingMaxHeaderListSize: maxHeaderBytes + (32 * 10), | |
| }) | |
| } | |
| func TestConfigTransportSettings(t *testing.T) { synctestTest(t, testConfigTransportSettings) } | |
| func testConfigTransportSettings(t testing.TB) { | |
| config := &http.HTTP2Config{ | |
| MaxConcurrentStreams: 1, // ignored by Transport | |
| MaxDecoderHeaderTableSize: 1<<20 + 2, | |
| MaxEncoderHeaderTableSize: 1<<20 + 3, | |
| MaxReadFrameSize: 1<<20 + 4, | |
| MaxReceiveBufferPerConnection: 64<<10 + 5, | |
| MaxReceiveBufferPerStream: 64<<10 + 6, | |
| } | |
| const maxHeaderBytes = 4096 + 7 | |
| tc := newTestClientConn(t, func(tr *http.Transport) { | |
| tr.HTTP2 = config | |
| tr.MaxResponseHeaderBytes = maxHeaderBytes | |
| }) | |
| tc.wantSettings(map[SettingID]uint32{ | |
| SettingHeaderTableSize: uint32(config.MaxDecoderHeaderTableSize), | |
| SettingInitialWindowSize: uint32(config.MaxReceiveBufferPerStream), | |
| SettingMaxFrameSize: uint32(config.MaxReadFrameSize), | |
| SettingMaxHeaderListSize: maxHeaderBytes + (32 * 10), | |
| }) | |
| tc.wantWindowUpdate(0, uint32(config.MaxReceiveBufferPerConnection)) | |
| } | |
| func TestConfigPingTimeoutServer(t *testing.T) { synctestTest(t, testConfigPingTimeoutServer) } | |
| func testConfigPingTimeoutServer(t testing.TB) { | |
| st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { | |
| }, func(s *Server) { | |
| s.ReadIdleTimeout = 2 * time.Second | |
| s.PingTimeout = 3 * time.Second | |
| }) | |
| st.greet() | |
| time.Sleep(2 * time.Second) | |
| _ = readFrame[*PingFrame](t, st) | |
| time.Sleep(3 * time.Second) | |
| st.wantClosed() | |
| } | |
| func TestConfigPingTimeoutTransport(t *testing.T) { synctestTest(t, testConfigPingTimeoutTransport) } | |
| func testConfigPingTimeoutTransport(t testing.TB) { | |
| tc := newTestClientConn(t, func(tr *Transport) { | |
| tr.ReadIdleTimeout = 2 * time.Second | |
| tr.PingTimeout = 3 * time.Second | |
| }) | |
| tc.greet() | |
| req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) | |
| rt := tc.roundTrip(req) | |
| tc.wantFrameType(FrameHeaders) | |
| time.Sleep(2 * time.Second) | |
| tc.wantFrameType(FramePing) | |
| time.Sleep(3 * time.Second) | |
| err := rt.err() | |
| if err == nil { | |
| t.Fatalf("expected connection to close") | |
| } | |
| } |