Introduce NoOpHeadersHandler in OgHttp2Session.

This CL adds a NoOpHeadersHandler member to OgHttp2Session, which then returns
this member for receiving headers on unknown streams (e.g., closed locally).
This addition follows Http2Dispatcher behavior, e.g.,
http://google3/gfe/gfe2/http2/http2_dispatcher.cc;l=916-922;rcl=406920946.
This addition allows OgHttp2Session to avoid delivering header events to the
visitor, bringing oghttp2 behavior more in line with nghttp2.

PiperOrigin-RevId: 410128615
diff --git a/http2/adapter/oghttp2_adapter_test.cc b/http2/adapter/oghttp2_adapter_test.cc
index 88595fc..f5a8cb9 100644
--- a/http2/adapter/oghttp2_adapter_test.cc
+++ b/http2/adapter/oghttp2_adapter_test.cc
@@ -1251,11 +1251,8 @@
           .Serialize();
 
   // The visitor gets notified about the HEADERS frame and DATA frame for the
-  // closed stream with further processing for both.
+  // closed stream with further processing on the DATA frame.
   EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 0x4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, _, _)).Times(3);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
   EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, DATA, 0x1));
   EXPECT_CALL(visitor, OnBeginDataForStream(stream_id, _));
   EXPECT_CALL(visitor,
diff --git a/http2/adapter/oghttp2_session.cc b/http2/adapter/oghttp2_session.cc
index 5ab95a6..a48dc47 100644
--- a/http2/adapter/oghttp2_session.cc
+++ b/http2/adapter/oghttp2_session.cc
@@ -236,6 +236,7 @@
           TracePerspectiveAsString(options.perspective),
           []() { return kTraceLoggingEnabled; }, this),
       headers_handler_(*this, visitor),
+      noop_headers_handler_(/*listener=*/nullptr),
       connection_window_manager_(kInitialFlowControlWindowSize,
                                  [this](size_t window_update_delta) {
                                    SendWindowUpdate(kConnectionStreamId,
@@ -806,13 +807,15 @@
 
 spdy::SpdyHeadersHandlerInterface* OgHttp2Session::OnHeaderFrameStart(
     spdy::SpdyStreamId stream_id) {
-  headers_handler_.set_stream_id(stream_id);
   auto it = stream_map_.find(stream_id);
   if (it != stream_map_.end()) {
+    headers_handler_.set_stream_id(stream_id);
     headers_handler_.set_header_type(
         NextHeaderType(it->second.received_header_type));
+    return &headers_handler_;
+  } else {
+    return &noop_headers_handler_;
   }
-  return &headers_handler_;
 }
 
 void OgHttp2Session::OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) {
@@ -827,8 +830,8 @@
     } else {
       it->second.received_header_type = headers_handler_.header_type();
     }
+    headers_handler_.set_stream_id(0);
   }
-  headers_handler_.set_stream_id(0);
 }
 
 void OgHttp2Session::OnRstStream(spdy::SpdyStreamId stream_id,
diff --git a/http2/adapter/oghttp2_session.h b/http2/adapter/oghttp2_session.h
index a3a0232..b11b57c 100644
--- a/http2/adapter/oghttp2_session.h
+++ b/http2/adapter/oghttp2_session.h
@@ -18,6 +18,7 @@
 #include "common/platform/api/quiche_bug_tracker.h"
 #include "common/platform/api/quiche_export.h"
 #include "spdy/core/http2_frame_decoder_adapter.h"
+#include "spdy/core/no_op_headers_handler.h"
 #include "spdy/core/spdy_framer.h"
 #include "spdy/core/spdy_header_block.h"
 #include "spdy/core/spdy_protocol.h"
@@ -342,6 +343,9 @@
   // Delivers header name-value pairs to the visitor.
   PassthroughHeadersHandler headers_handler_;
 
+  // Ignores header data, e.g., for an unknown or rejected stream.
+  spdy::NoOpHeadersHandler noop_headers_handler_;
+
   // Tracks the remaining client connection preface, in the case of a server
   // session.
   absl::string_view remaining_preface_;