Skip to content

Commit 3e863de

Browse files
committed
Send GoAwayFrame when illegal streamID is received
1 parent c68ded3 commit 3e863de

File tree

3 files changed

+16
-24
lines changed

3 files changed

+16
-24
lines changed

internal/transport/http2_server.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,15 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade
349349
})
350350
return nil
351351
}
352-
352+
353353
if streamID%2 != 1 || streamID <= t.maxStreamID {
354354
// illegal gRPC stream id.
355-
return fmt.Errorf("received an illegal stream id: %v. headers frame: %+v", streamID, frame)
355+
t.controlBuf.put(&goAway{
356+
code: http2.ErrCodeProtocol,
357+
debugData: []byte(fmt.Sprintf("received an illegal stream id, %+v", streamID)),
358+
closeConn: fmt.Errorf("received an illegal stream id: %v. headers frame: %+v", streamID, frame),
359+
})
360+
return nil
356361
}
357362
t.maxStreamID = streamID
358363

internal/transport/transport_test.go

-19
Original file line numberDiff line numberDiff line change
@@ -2592,22 +2592,3 @@ func TestConnectionError_Unwrap(t *testing.T) {
25922592
t.Error("ConnectionError does not unwrap")
25932593
}
25942594
}
2595-
2596-
// Test gRPC server's operateHeaders on a header with even stream ID.
2597-
// Per [HTTP/2 spec]: Streams initiated by a client MUST use
2598-
// odd-numbered stream identifiers. When received even stream ID, the
2599-
// operateHeader returns error instead of writing the frame to the transport.
2600-
//
2601-
// [HTTP/2 spec]: https://httpwg.org/specs/rfc7540.html#StreamIdentifiers
2602-
func TestServerOperateHeaderFailOnEvenStreamID(t *testing.T) {
2603-
hf := &http2.HeadersFrame{FrameHeader: http2.FrameHeader{StreamID: 2}}
2604-
metaHeaderFrame := &http2.MetaHeadersFrame{HeadersFrame: hf}
2605-
s := http2Server{}
2606-
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
2607-
defer cancel()
2608-
err := s.operateHeaders(ctx, metaHeaderFrame, nil)
2609-
want := "received an illegal stream id: 2. headers frame: [FrameHeader DATA stream=2 len=0]"
2610-
if got := err.Error(); got != want {
2611-
t.Fatalf("http2Server.operateHeaders() returned err: %v; want: %v", got, want)
2612-
}
2613-
}

test/end2end_test.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -3925,9 +3925,15 @@ func (s) TestClientInvalidStreamID(t *testing.T) {
39253925
st := newServerTesterFromConn(t, conn)
39263926
st.greet()
39273927
st.writeHeadersGRPC(2, "/grpc.testing.TestService/StreamingInputCall", true)
3928-
_, err = st.fr.ReadFrame()
3929-
if err != io.EOF {
3930-
t.Fatalf("Error expected when Client StreamID is even %v", err)
3928+
frame, err := st.fr.ReadFrame()
3929+
switch frame := frame.(type) {
3930+
case *http2.GoAwayFrame:
3931+
// do nothing since GoAwayFrame is expected.
3932+
if frame.ErrCode != http2.ErrCodeProtocol {
3933+
t.Fatalf("GoAway Frame received with code %v, want code: http.ErrCodeProtocol", frame.ErrCode)
3934+
}
3935+
default:
3936+
t.Fatalf("want: GoAwayFrame. got: %v", frame)
39313937
}
39323938
}
39333939

0 commit comments

Comments
 (0)