Adds a method to Http2Adapter to determine if it represents a server-side HTTP/2 session.

PiperOrigin-RevId: 378148676
diff --git a/http2/adapter/http2_adapter.h b/http2/adapter/http2_adapter.h
index ab21d7a..0dbb54a 100644
--- a/http2/adapter/http2_adapter.h
+++ b/http2/adapter/http2_adapter.h
@@ -23,6 +23,8 @@
   Http2Adapter(const Http2Adapter&) = delete;
   Http2Adapter& operator=(const Http2Adapter&) = delete;
 
+  virtual bool IsServerSession() const = 0;
+
   // Processes the incoming |bytes| as HTTP/2 and invokes callbacks on the
   // |visitor_| as appropriate.
   virtual ssize_t ProcessBytes(absl::string_view bytes) = 0;
diff --git a/http2/adapter/nghttp2_adapter.cc b/http2/adapter/nghttp2_adapter.cc
index 1898a7e..947bb1f 100644
--- a/http2/adapter/nghttp2_adapter.cc
+++ b/http2/adapter/nghttp2_adapter.cc
@@ -28,6 +28,12 @@
   return absl::WrapUnique(adapter);
 }
 
+bool NgHttp2Adapter::IsServerSession() const {
+  int result = nghttp2_session_check_server_session(session_->raw_ptr());
+  QUICHE_DCHECK_EQ(perspective_ == Perspective::kServer, result > 0);
+  return result > 0;
+}
+
 ssize_t NgHttp2Adapter::ProcessBytes(absl::string_view bytes) {
   const ssize_t processed_bytes = session_->ProcessBytes(bytes);
   if (processed_bytes < 0) {
diff --git a/http2/adapter/nghttp2_adapter.h b/http2/adapter/nghttp2_adapter.h
index 862629a..61b906e 100644
--- a/http2/adapter/nghttp2_adapter.h
+++ b/http2/adapter/nghttp2_adapter.h
@@ -21,6 +21,8 @@
   static std::unique_ptr<NgHttp2Adapter> CreateServerAdapter(
       Http2VisitorInterface& visitor);
 
+  bool IsServerSession() const override;
+
   ssize_t ProcessBytes(absl::string_view bytes) override;
   void SubmitSettings(absl::Span<const Http2Setting> settings) override;
   void SubmitPriorityForStream(Http2StreamId stream_id,
diff --git a/http2/adapter/nghttp2_adapter_test.cc b/http2/adapter/nghttp2_adapter_test.cc
index ed1804e..90b0166 100644
--- a/http2/adapter/nghttp2_adapter_test.cc
+++ b/http2/adapter/nghttp2_adapter_test.cc
@@ -30,6 +30,7 @@
   ASSERT_NE(nullptr, adapter);
   EXPECT_TRUE(adapter->session().want_read());
   EXPECT_FALSE(adapter->session().want_write());
+  EXPECT_FALSE(adapter->IsServerSession());
 }
 
 TEST(NgHttp2AdapterTest, ClientHandlesFrames) {
@@ -288,6 +289,7 @@
   ASSERT_NE(nullptr, adapter);
   EXPECT_TRUE(adapter->session().want_read());
   EXPECT_FALSE(adapter->session().want_write());
+  EXPECT_TRUE(adapter->IsServerSession());
 }
 
 TEST(NgHttp2AdapterTest, ServerHandlesFrames) {
diff --git a/http2/adapter/oghttp2_adapter.cc b/http2/adapter/oghttp2_adapter.cc
index d78b08b..6334e4f 100644
--- a/http2/adapter/oghttp2_adapter.cc
+++ b/http2/adapter/oghttp2_adapter.cc
@@ -30,6 +30,10 @@
 
 OgHttp2Adapter::~OgHttp2Adapter() {}
 
+bool OgHttp2Adapter::IsServerSession() const {
+  return session_->IsServerSession();
+}
+
 ssize_t OgHttp2Adapter::ProcessBytes(absl::string_view bytes) {
   return session_->ProcessBytes(bytes);
 }
diff --git a/http2/adapter/oghttp2_adapter.h b/http2/adapter/oghttp2_adapter.h
index cf1b3e2..26d5743 100644
--- a/http2/adapter/oghttp2_adapter.h
+++ b/http2/adapter/oghttp2_adapter.h
@@ -19,6 +19,7 @@
   ~OgHttp2Adapter();
 
   // From Http2Adapter.
+  bool IsServerSession() const override;
   ssize_t ProcessBytes(absl::string_view bytes) override;
   void SubmitSettings(absl::Span<const Http2Setting> settings) override;
   void SubmitPriorityForStream(Http2StreamId stream_id,
diff --git a/http2/adapter/oghttp2_adapter_test.cc b/http2/adapter/oghttp2_adapter_test.cc
index 2b39d23..bee8640 100644
--- a/http2/adapter/oghttp2_adapter_test.cc
+++ b/http2/adapter/oghttp2_adapter_test.cc
@@ -24,6 +24,10 @@
   std::unique_ptr<OgHttp2Adapter> adapter_;
 };
 
+TEST_F(OgHttp2AdapterTest, IsServerSession) {
+  EXPECT_TRUE(adapter_->IsServerSession());
+}
+
 TEST_F(OgHttp2AdapterTest, ProcessBytes) {
   testing::InSequence seq;
   EXPECT_CALL(http2_visitor_, OnFrameHeader(0, 0, 4, 0));
diff --git a/http2/adapter/oghttp2_session.h b/http2/adapter/oghttp2_session.h
index 4ffb140..778af35 100644
--- a/http2/adapter/oghttp2_session.h
+++ b/http2/adapter/oghttp2_session.h
@@ -24,7 +24,7 @@
     Perspective perspective = Perspective::kClient;
   };
 
-  OgHttp2Session(Http2VisitorInterface& visitor, Options /*options*/);
+  OgHttp2Session(Http2VisitorInterface& visitor, Options options);
   ~OgHttp2Session() override;
 
   // Enqueues a frame for transmission to the peer.
@@ -45,6 +45,10 @@
                          DataFrameSource* data_source);
   int SubmitTrailer(Http2StreamId stream_id, absl::Span<const Header> trailers);
 
+  bool IsServerSession() const {
+    return options_.perspective == Perspective::kServer;
+  }
+
   // From Http2Session.
   ssize_t ProcessBytes(absl::string_view bytes) override;
   int Consume(Http2StreamId stream_id, size_t num_bytes) override;
diff --git a/http2/adapter/oghttp2_session_test.cc b/http2/adapter/oghttp2_session_test.cc
index 90853f4..28ddb57 100644
--- a/http2/adapter/oghttp2_session_test.cc
+++ b/http2/adapter/oghttp2_session_test.cc
@@ -34,6 +34,7 @@
   EXPECT_TRUE(session.want_read());
   EXPECT_FALSE(session.want_write());
   EXPECT_EQ(session.GetRemoteWindowSize(), kDefaultInitialStreamWindowSize);
+  EXPECT_FALSE(session.IsServerSession());
 }
 
 TEST(OgHttp2SessionTest, ClientHandlesFrames) {
@@ -225,6 +226,7 @@
   EXPECT_TRUE(session.want_read());
   EXPECT_FALSE(session.want_write());
   EXPECT_EQ(session.GetRemoteWindowSize(), kDefaultInitialStreamWindowSize);
+  EXPECT_TRUE(session.IsServerSession());
 }
 
 TEST(OgHttp2SessionTest, ServerHandlesFrames) {