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