Stop processing data in QuicSpdyStream::OnDataAvailable() if connection is closed.
If the connection is closed, for example, QuicSpdyStream itself closes it
because a frame of invalid type is received, or because a QPACK error occurs,
then no more data should be fed into HttpDecoder.
gfe-relnote: n/a, change to QUIC v99-only class.
PiperOrigin-RevId: 258752154
Change-Id: Ibb60b00662160582a075e1a5353bab74e95490d5
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc
index 43a14d9..f9777ec 100644
--- a/quic/core/http/quic_spdy_stream_test.cc
+++ b/quic/core/http/quic_spdy_stream_test.cc
@@ -2286,6 +2286,40 @@
stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data2));
}
+// SETTINGS frames are invalid on bidirectional streams. If one is received,
+// the connection is closed. No more data should be processed.
+TEST_P(QuicSpdyStreamTest, StopProcessingIfConnectionClosed) {
+ if (!VersionUsesQpack(GetParam().transport_version)) {
+ return;
+ }
+
+ Initialize(kShouldProcessData);
+
+ // SETTINGS frame with empty payload.
+ std::string settings = QuicTextUtils::HexDecode("0400");
+ // HEADERS frame with QPACK encoded single header field "foo: bar".
+ // Since it arrives after a SETTINGS frame, it should never be read.
+ std::string headers =
+ HeadersFrame(QuicTextUtils::HexDecode("00002a94e703626172"));
+
+ // Combine the two frames to make sure they are processed in a single
+ // QuicSpdyStream::OnDataAvailable() call.
+ std::string frames = QuicStrCat(settings, headers);
+
+ EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
+
+ EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_DECODER_ERROR, _, _))
+ .WillOnce(
+ Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+ EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _));
+ EXPECT_CALL(*session_, OnConnectionClosed(_, _));
+
+ stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), /* fin = */ false,
+ /* offset = */ 0, frames));
+
+ EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
+}
+
} // namespace
} // namespace test
} // namespace quic