gfe-relnote: Ignore CANCEL_PUSH frames on the control stream. Protected by gfe2_reloadable_flag_quic_enable_version_draft_25_v3 and gfe2_reloadable_flag_quic_enable_version_draft_27. PiperOrigin-RevId: 301808309 Change-Id: I3bafbaa3b76e8a4267d25cb95b354cef8db02677
diff --git a/quic/core/http/quic_receive_control_stream.cc b/quic/core/http/quic_receive_control_stream.cc index f77bdea..7f8007a 100644 --- a/quic/core/http/quic_receive_control_stream.cc +++ b/quic/core/http/quic_receive_control_stream.cc
@@ -30,8 +30,8 @@ } bool OnCancelPushFrame(const CancelPushFrame& /*frame*/) override { - OnWrongFrame("Cancel Push"); - return false; + // TODO(b/151841240): Handle CANCEL_PUSH frames instead of ignoring them. + return true; } bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) override {
diff --git a/quic/core/http/quic_receive_control_stream_test.cc b/quic/core/http/quic_receive_control_stream_test.cc index 8bbf789..61d8229 100644 --- a/quic/core/http/quic_receive_control_stream_test.cc +++ b/quic/core/http/quic_receive_control_stream_test.cc
@@ -235,11 +235,10 @@ } TEST_P(QuicReceiveControlStreamTest, ReceiveWrongFrame) { - CancelPushFrame cancel; - cancel.push_id = 0x1; + // DATA frame header without payload. std::unique_ptr<char[]> buffer; QuicByteCount header_length = - HttpEncoder::SerializeCancelPushFrame(cancel, &buffer); + HttpEncoder::SerializeDataFrameHeader(/* payload_length = */ 2, &buffer); std::string data = std::string(buffer.get(), header_length); QuicStreamFrame frame(receive_control_stream_->id(), false, 1, data);
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc index caca24c..b14db0b 100644 --- a/quic/core/http/quic_spdy_session_test.cc +++ b/quic/core/http/quic_spdy_session_test.cc
@@ -2802,6 +2802,36 @@ session_.OnHttp3GoAway(stream_id); } +// Test that receipt of CANCEL_PUSH frame does not result in closing the +// connection. +// TODO(b/151841240): Handle CANCEL_PUSH frames instead of ignoring them. +TEST_P(QuicSpdySessionTestClient, IgnoreCancelPush) { + if (!VersionUsesHttp3(transport_version())) { + return; + } + + // Create control stream. + QuicStreamId receive_control_stream_id = + GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3); + char type[] = {kControlStream}; + quiche::QuicheStringPiece stream_type(type, 1); + QuicStreamOffset offset = 0; + QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset, + stream_type); + offset += stream_type.length(); + session_.OnStreamFrame(data1); + EXPECT_EQ(receive_control_stream_id, + QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id()); + + CancelPushFrame cancel_push{/* push_id = */ 0}; + std::unique_ptr<char[]> buffer; + auto frame_length = + HttpEncoder::SerializeCancelPushFrame(cancel_push, &buffer); + QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset, + quiche::QuicheStringPiece(buffer.get(), frame_length)); + session_.OnStreamFrame(data2); +} + TEST_P(QuicSpdySessionTestServer, ServerPushEnabledDefaultValue) { if (VersionUsesHttp3(transport_version())) { EXPECT_FALSE(session_.server_push_enabled()); @@ -2966,6 +2996,36 @@ session_.OnStopSendingFrame(stop_sending_encoder_stream); } +// Test that receipt of CANCEL_PUSH frame does not result in closing the +// connection. +// TODO(b/151841240): Handle CANCEL_PUSH frames instead of ignoring them. +TEST_P(QuicSpdySessionTestServer, IgnoreCancelPush) { + if (!VersionUsesHttp3(transport_version())) { + return; + } + + // Create control stream. + QuicStreamId receive_control_stream_id = + GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3); + char type[] = {kControlStream}; + quiche::QuicheStringPiece stream_type(type, 1); + QuicStreamOffset offset = 0; + QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset, + stream_type); + offset += stream_type.length(); + session_.OnStreamFrame(data1); + EXPECT_EQ(receive_control_stream_id, + QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id()); + + CancelPushFrame cancel_push{/* push_id = */ 0}; + std::unique_ptr<char[]> buffer; + auto frame_length = + HttpEncoder::SerializeCancelPushFrame(cancel_push, &buffer); + QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset, + quiche::QuicheStringPiece(buffer.get(), frame_length)); + session_.OnStreamFrame(data2); +} + } // namespace } // namespace test } // namespace quic