diff options
author | Damien Neil <dneil@google.com> | 2024-02-26 12:25:37 -0800 |
---|---|---|
committer | Damien Neil <dneil@google.com> | 2024-03-11 21:02:17 +0000 |
commit | 12ddef72728707026a3d9adbbc28affa76faf688 (patch) | |
tree | 71964ef63b69c631e9c3d8b91900b78e9804e767 | |
parent | d600ae05799943851536e26ab37ee23294912c3d (diff) | |
download | golang-x-net-12ddef72728707026a3d9adbbc28affa76faf688.tar.gz |
http2: reject DATA frames after 1xx and before final headers
When checking to see if a DATA frame can be accepted, check to
see if we have received a non-1xx header, not whether we have
received any header.
Fixes golang/go#65927
Change-Id: Id4fae1862de6179f8fc95e02dec7d4c47a7640e1
Reviewed-on: https://go-review.googlesource.com/c/net/+/567175
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
-rw-r--r-- | http2/transport.go | 2 | ||||
-rw-r--r-- | http2/transport_test.go | 29 |
2 files changed, 30 insertions, 1 deletions
diff --git a/http2/transport.go b/http2/transport.go index 04db292..44845ba 100644 --- a/http2/transport.go +++ b/http2/transport.go @@ -2787,7 +2787,7 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { }) return nil } - if !cs.firstByte { + if !cs.pastHeaders { cc.logf("protocol error: received DATA before a HEADERS frame") rl.endStreamError(cs, StreamError{ StreamID: f.StreamID, diff --git a/http2/transport_test.go b/http2/transport_test.go index f889cd1..836d455 100644 --- a/http2/transport_test.go +++ b/http2/transport_test.go @@ -6254,3 +6254,32 @@ func TestDialRaceResumesDial(t *testing.T) { case <-successCh: } } + +func TestTransportDataAfter1xxHeader(t *testing.T) { + // Discard logger output to avoid spamming stderr. + log.SetOutput(io.Discard) + defer log.SetOutput(os.Stderr) + + // https://go.dev/issue/65927 - server sends a 1xx response, followed by a DATA frame. + tc := newTestClientConn(t) + tc.greet() + + req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) + rt := tc.roundTrip(req) + + tc.wantFrameType(FrameHeaders) + tc.writeHeaders(HeadersFrameParam{ + StreamID: rt.streamID(), + EndHeaders: true, + EndStream: false, + BlockFragment: tc.makeHeaderBlockFragment( + ":status", "100", + ), + }) + tc.writeData(rt.streamID(), true, []byte{0}) + err := rt.err() + if err, ok := err.(StreamError); !ok || err.Code != ErrCodeProtocol { + t.Errorf("RoundTrip error: %v; want ErrCodeProtocol", err) + } + tc.wantFrameType(FrameRSTStream) +} |