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);