Skip to content

Commit dbc3a0e

Browse files
committed
add test
1 parent 135c1ac commit dbc3a0e

2 files changed

Lines changed: 61 additions & 1 deletion

File tree

test/end2end_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6090,6 +6090,49 @@ func testClientMaxHeaderListSizeServerIntentionalViolation(t *testing.T, e env)
60906090
}
60916091
}
60926092

6093+
// TestEarlyAbortStreamHeaderListSizeCheck tests that when the server decides to
6094+
// abort the stream early (e.g., due to invalid content-type), it respects the
6095+
// client's MaxHeaderListSize setting. If the response headers would exceed
6096+
// the limit, the server should send a RST_STREAM instead of the headers.
6097+
func (s) TestEarlyAbortStreamHeaderListSizeCheck(t *testing.T) {
6098+
lis, err := net.Listen("tcp", "localhost:0")
6099+
if err != nil {
6100+
t.Fatalf("Failed to listen: %v", err)
6101+
}
6102+
s := grpc.NewServer()
6103+
defer s.Stop()
6104+
go s.Serve(lis)
6105+
6106+
conn, err := net.DialTimeout("tcp", lis.Addr().String(), defaultTestTimeout)
6107+
if err != nil {
6108+
t.Fatalf("Failed to dial: %v", err)
6109+
}
6110+
defer conn.Close()
6111+
st := newServerTesterFromConn(t, conn)
6112+
6113+
// Set a very small MaxHeaderListSize that any response headers would violate.
6114+
// The early abort response includes :status, content-type, grpc-status, and grpc-message,
6115+
// which together will exceed 1 byte.
6116+
st.greetWithSettings(http2.Setting{ID: http2.SettingMaxHeaderListSize, Val: 1})
6117+
6118+
// Send a request with an invalid content-type to trigger early abort.
6119+
st.writeHeaders(http2.HeadersFrameParam{
6120+
StreamID: 1,
6121+
BlockFragment: st.encodeHeader(
6122+
":method", "POST",
6123+
":path", "/grpc.testing.TestService/UnaryCall",
6124+
"content-type", "text/plain", // Invalid content-type to trigger early abort
6125+
"te", "trailers",
6126+
),
6127+
EndStream: true,
6128+
EndHeaders: true,
6129+
})
6130+
6131+
// We should receive a RST_STREAM with ErrCodeInternal because the response
6132+
// headers exceed the MaxHeaderListSize limit.
6133+
st.wantRSTStream(http2.ErrCodeInternal)
6134+
}
6135+
60936136
func (s) TestNetPipeConn(t *testing.T) {
60946137
// This test will block indefinitely if grpc writes both client and server
60956138
// prefaces without either reading from the Conn.

test/servertester.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,19 @@ func (st *serverTester) readFrame() (http2.Frame, error) {
9191
// greet initiates the client's HTTP/2 connection into a state where
9292
// frames may be sent.
9393
func (st *serverTester) greet() {
94+
st.greetWithSettings()
95+
}
96+
97+
// greetWithSettings initiates the client's HTTP/2 connection with custom settings.
98+
func (st *serverTester) greetWithSettings(settings ...http2.Setting) {
9499
st.writePreface()
95-
st.writeInitialSettings()
100+
if len(settings) > 0 {
101+
if err := st.fr.WriteSettings(settings...); err != nil {
102+
st.t.Fatalf("Error writing initial SETTINGS frame from client to server: %v", err)
103+
}
104+
} else {
105+
st.writeInitialSettings()
106+
}
96107
st.wantSettings()
97108
st.writeSettingsAck()
98109
for {
@@ -132,6 +143,12 @@ func (st *serverTester) writeInitialSettings() {
132143
}
133144
}
134145

146+
func (st *serverTester) writeInitialSettingsWithMaxHeaderListSize(maxHeaderListSize uint32) {
147+
if err := st.fr.WriteSettings(http2.Setting{ID: http2.SettingMaxHeaderListSize, Val: maxHeaderListSize}); err != nil {
148+
st.t.Fatalf("Error writing initial SETTINGS frame from client to server: %v", err)
149+
}
150+
}
151+
135152
func (st *serverTester) writeSettingsAck() {
136153
if err := st.fr.WriteSettingsAck(); err != nil {
137154
st.t.Fatalf("Error writing ACK of server's SETTINGS: %v", err)

0 commit comments

Comments
 (0)