Changes error handling so that when OgHttp2Adapter receives a header field that's too long, it is handled as a stream error rather than a connection error.

This fixes the `MultiplexedUpstreamIntegrationTest.LargeResponseHeadersRejected` test case in //third_party/envoy/src/test/integration:multiplexed_upstream_integration_test.

PiperOrigin-RevId: 423401595
diff --git a/http2/adapter/oghttp2_adapter_test.cc b/http2/adapter/oghttp2_adapter_test.cc
index 2d0adb7..3596ce0 100644
--- a/http2/adapter/oghttp2_adapter_test.cc
+++ b/http2/adapter/oghttp2_adapter_test.cc
@@ -34,6 +34,13 @@
   CONTINUATION,
 };
 
+// TODO(birenroy): replace numeric flag values with named constants
+enum FrameFlag {
+  END_STREAM = 0x01,
+  ACK = END_STREAM,
+  END_HEADERS = 0x04,
+};
+
 using spdy::SpdyFrameType;
 
 class OgHttp2AdapterTest : public testing::Test {
@@ -3846,7 +3853,13 @@
                                            {":authority", "example.com"},
                                            {":path", "/this/is/request/one"},
                                            {"x-toobig", too_large_value}},
-                                          /*fin=*/false)
+                                          /*fin=*/true)
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
                                  .Serialize();
   testing::InSequence s;
 
@@ -3855,17 +3868,22 @@
   EXPECT_CALL(visitor, OnSettingsStart());
   EXPECT_CALL(visitor, OnSettingsEnd());
 
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, END_STREAM));
   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
   EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 0)).Times(3);
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 4));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kHeaderError));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, END_HEADERS));
   // Further header processing is skipped, as the header field is too large.
 
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, END_STREAM | END_HEADERS));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnEndStream(3));
+
   const int64_t result = adapter->ProcessBytes(frames);
   EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
 
@@ -3873,19 +3891,19 @@
 
   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  // Since the library opted not to process the header, it generates a GOAWAY
-  // with error code COMPRESSION_ERROR.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
   EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::COMPRESSION_ERROR)));
+              OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
 
   int send_result = adapter->Send();
-  // Some bytes should have been serialized.
   EXPECT_EQ(0, send_result);
-  // SETTINGS and GOAWAY.
   EXPECT_THAT(visitor.data(), EqualsFrames({spdy::SpdyFrameType::SETTINGS,
-                                            spdy::SpdyFrameType::GOAWAY}));
+                                            spdy::SpdyFrameType::SETTINGS,
+                                            spdy::SpdyFrameType::RST_STREAM}));
 }
 
 TEST(OgHttp2AdapterServerTest, ServerReceivesInvalidAuthority) {
diff --git a/http2/adapter/oghttp2_session.cc b/http2/adapter/oghttp2_session.cc
index 2467009..5aea9f7 100644
--- a/http2/adapter/oghttp2_session.cc
+++ b/http2/adapter/oghttp2_session.cc
@@ -235,7 +235,7 @@
     case HeaderValidator::HEADER_FIELD_INVALID:
       return Http2VisitorInterface::HEADER_FIELD_INVALID;
     case HeaderValidator::HEADER_FIELD_TOO_LONG:
-      return Http2VisitorInterface::HEADER_COMPRESSION_ERROR;
+      return Http2VisitorInterface::HEADER_RST_STREAM;
   }
   return Http2VisitorInterface::HEADER_CONNECTION_ERROR;
 }