Remove static stream checks in QuicSession::OnRstStream() and let static sub-streams handle it. The advantage of having sub stream classes override rather than QuicStream base class sanity check is that HTTP/3 streams are now able to throw HTTP/3 specific errors. gfe-relnote: no behavior change. not protected. PiperOrigin-RevId: 299190484 Change-Id: Icaa957f91eba4acb3518515b75d205bc22001ddc
diff --git a/quic/core/http/quic_headers_stream.cc b/quic/core/http/quic_headers_stream.cc index 1e7feb3..8157dae 100644 --- a/quic/core/http/quic_headers_stream.cc +++ b/quic/core/http/quic_headers_stream.cc
@@ -155,4 +155,9 @@ } } +void QuicHeadersStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) { + stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID, + "Attempt to reset headers stream"); +} + } // namespace quic
diff --git a/quic/core/http/quic_headers_stream.h b/quic/core/http/quic_headers_stream.h index e97a78d..3786ddf 100644 --- a/quic/core/http/quic_headers_stream.h +++ b/quic/core/http/quic_headers_stream.h
@@ -50,6 +50,8 @@ QuicByteCount data_length, bool fin_retransmitted) override; + void OnStreamReset(const QuicRstStreamFrame& frame) override; + private: friend class test::QuicHeadersStreamPeer;
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc index 2e46a5c..bd62260 100644 --- a/quic/core/http/quic_spdy_session_test.cc +++ b/quic/core/http/quic_spdy_session_test.cc
@@ -1171,6 +1171,7 @@ TEST_P(QuicSpdySessionTestServer, OnRstStreamStaticStreamId) { QuicStreamId id; + std::string error_message; // Initialize HTTP/3 control stream. if (VersionUsesHttp3(transport_version())) { id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3); @@ -1178,17 +1179,19 @@ QuicStreamFrame data1(id, false, 0, quiche::QuicheStringPiece(type, 1)); session_.OnStreamFrame(data1); + error_message = "Attempt to reset receive control stream"; } else { id = QuicUtils::GetHeadersStreamId(transport_version()); + error_message = "Attempt to reset headers stream"; } // Send two bytes of payload. QuicRstStreamFrame rst1(kInvalidControlFrameId, id, QUIC_ERROR_PROCESSING_STREAM, 0); - EXPECT_CALL(*connection_, - CloseConnection( - QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream", - ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET)); + EXPECT_CALL( + *connection_, + CloseConnection(QUIC_INVALID_STREAM_ID, error_message, + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET)); session_.OnRstStream(rst1); }
diff --git a/quic/core/quic_crypto_stream.cc b/quic/core/quic_crypto_stream.cc index b368b61..094613c 100644 --- a/quic/core/quic_crypto_stream.cc +++ b/quic/core/quic_crypto_stream.cc
@@ -194,6 +194,11 @@ return newly_acked_length > 0; } +void QuicCryptoStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) { + stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID, + "Attempt to reset crypto stream"); +} + void QuicCryptoStream::NeuterUnencryptedStreamData() { if (!QuicVersionUsesCryptoFrames(session()->transport_version())) { for (const auto& interval : bytes_consumed_[ENCRYPTION_INITIAL]) {
diff --git a/quic/core/quic_crypto_stream.h b/quic/core/quic_crypto_stream.h index 425d8c6..82f81fe 100644 --- a/quic/core/quic_crypto_stream.h +++ b/quic/core/quic_crypto_stream.h
@@ -57,6 +57,8 @@ bool OnCryptoFrameAcked(const QuicCryptoFrame& frame, QuicTime::Delta ack_delay_time); + void OnStreamReset(const QuicRstStreamFrame& frame) override; + // Performs key extraction to derive a new secret of |result_len| bytes // dependent on |label|, |context|, and the stream's negotiated subkey secret. // Returns false if the handshake has not been confirmed or the parameters are
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc index e6f1aa7..0ca240e 100644 --- a/quic/core/quic_session.cc +++ b/quic/core/quic_session.cc
@@ -366,12 +366,6 @@ HandleRstOnValidNonexistentStream(frame); return; // Errors are handled by GetOrCreateStream. } - if (stream->is_static()) { - connection()->CloseConnection( - QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream", - ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); - return; - } stream->OnStreamReset(frame); }
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc index 152e159..4f8dd4f 100644 --- a/quic/core/quic_session_test.cc +++ b/quic/core/quic_session_test.cc
@@ -1472,27 +1472,6 @@ session_.OnStreamFrame(data1); } -TEST_P(QuicSessionTestServer, OnRstStreamStaticStreamId) { - if (VersionUsesHttp3(connection_->transport_version())) { - // The test relies on headers stream, which no longer exists in IETF QUIC. - return; - } - QuicStreamId headers_stream_id = - QuicUtils::GetHeadersStreamId(connection_->transport_version()); - std::unique_ptr<TestStream> fake_headers_stream = - std::make_unique<TestStream>(headers_stream_id, &session_, - /*is_static*/ true, BIDIRECTIONAL); - QuicSessionPeer::ActivateStream(&session_, std::move(fake_headers_stream)); - // Send two bytes of payload. - QuicRstStreamFrame rst1(kInvalidControlFrameId, headers_stream_id, - QUIC_ERROR_PROCESSING_STREAM, 0); - EXPECT_CALL(*connection_, - CloseConnection( - QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream", - ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET)); - session_.OnRstStream(rst1); -} - TEST_P(QuicSessionTestServer, OnStreamFrameInvalidStreamId) { // Send two bytes of payload. QuicStreamFrame data1(
diff --git a/quic/qbone/qbone_control_stream.cc b/quic/qbone/qbone_control_stream.cc index 31a5070..0b453a7 100644 --- a/quic/qbone/qbone_control_stream.cc +++ b/quic/qbone/qbone_control_stream.cc
@@ -65,4 +65,10 @@ return true; } +void QboneControlStreamBase::OnStreamReset( + const QuicRstStreamFrame& /*frame*/) { + stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID, + "Attempt to reset control stream"); +} + } // namespace quic
diff --git a/quic/qbone/qbone_control_stream.h b/quic/qbone/qbone_control_stream.h index 0f4127b..10da82c 100644 --- a/quic/qbone/qbone_control_stream.h +++ b/quic/qbone/qbone_control_stream.h
@@ -19,6 +19,8 @@ void OnDataAvailable() override; + void OnStreamReset(const QuicRstStreamFrame& frame) override; + protected: virtual void OnMessage(const std::string& data) = 0; bool SendMessage(const proto2::Message& proto);