Update goaway behavior. protected by gfe2_reloadable_flag_quic_http3_goaway_new_behavior.

Updating behavior to https://github.com/quicwg/base-drafts/pull/3129.
If client receives GOAWAY with Stream ID that is not client-initiated
bidirectional stream ID, it now closes connection with application error
H3_ID_ERROR instead of transport error PROTOCOL_VIOLATION (draft-04 behavior).
If server receives GOAWAY, it ignores it instead of closing connection with
H3_FRAME_UNEXPECTED (draft-27 behavior).  Stream ID/push ID carried by GOAWAY
frame is ignored in all cases.

This updates behavior to draft-28.  While we are still supporting draft-27,
this should be okay as the new behavior is more permissive.

PiperOrigin-RevId: 323358652
Change-Id: I17919364a259a38a110284bab0023779b194094e
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index df83890..18b3951 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -1114,6 +1114,29 @@
   session_.OnGoAway(go_away);
 }
 
+TEST_P(QuicSpdySessionTestServer, Http3GoAwayLargerIdThanBefore) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  if (!GetQuicReloadableFlag(quic_http3_goaway_new_behavior)) {
+    return;
+  }
+
+  EXPECT_FALSE(session_.http3_goaway_received());
+  PushId push_id1 = 0;
+  session_.OnHttp3GoAway(push_id1);
+  EXPECT_TRUE(session_.http3_goaway_received());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
+          "GOAWAY received with ID 1 greater than previously received ID 0",
+          _));
+  PushId push_id2 = 1;
+  session_.OnHttp3GoAway(push_id2);
+}
+
 // Test that server session will send a connectivity probe in response to a
 // connectivity probe on the same path.
 TEST_P(QuicSpdySessionTestServer, ServerReplyToConnecitivityProbe) {
@@ -2831,16 +2854,47 @@
   if (!VersionUsesHttp3(transport_version())) {
     return;
   }
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(
-          QUIC_INVALID_STREAM_ID,
-          "GOAWAY's last stream id has to point to a request stream", _));
+  if (GetQuicReloadableFlag(quic_http3_goaway_new_behavior)) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
+                                "GOAWAY with invalid stream ID", _));
+  } else {
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(
+            QUIC_INVALID_STREAM_ID,
+            "GOAWAY's last stream id has to point to a request stream", _));
+  }
   QuicStreamId stream_id =
       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
   session_.OnHttp3GoAway(stream_id);
 }
 
+TEST_P(QuicSpdySessionTestClient, Http3GoAwayLargerIdThanBefore) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  if (!GetQuicReloadableFlag(quic_http3_goaway_new_behavior)) {
+    return;
+  }
+
+  EXPECT_FALSE(session_.http3_goaway_received());
+  QuicStreamId stream_id1 =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
+  session_.OnHttp3GoAway(stream_id1);
+  EXPECT_TRUE(session_.http3_goaway_received());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
+          "GOAWAY received with ID 4 greater than previously received ID 0",
+          _));
+  QuicStreamId stream_id2 =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
+  session_.OnHttp3GoAway(stream_id2);
+}
+
 // 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.