Adds a unit test demonstrating that CallbackVisitor revives stream state even for closed streams.
PiperOrigin-RevId: 592325925
diff --git a/quiche/http2/adapter/callback_visitor_test.cc b/quiche/http2/adapter/callback_visitor_test.cc
index 4d0355e..88856ee 100644
--- a/quiche/http2/adapter/callback_visitor_test.cc
+++ b/quiche/http2/adapter/callback_visitor_test.cc
@@ -530,6 +530,61 @@
EXPECT_EQ(frames.size(), result);
}
+TEST(ServerCallbackVisitorUnitTest, HeadersAfterFin) {
+ testing::StrictMock<MockNghttp2Callbacks> callbacks;
+ CallbackVisitor visitor(Perspective::kServer,
+ *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
+
+ testing::InSequence seq;
+
+ // HEADERS on stream 1
+ EXPECT_CALL(
+ callbacks,
+ OnBeginFrame(HasFrameHeader(
+ 1, HEADERS, NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_END_STREAM)));
+ visitor.OnFrameHeader(1, 23, HEADERS, 5);
+
+ EXPECT_CALL(callbacks,
+ OnBeginHeaders(IsHeaders(
+ 1, NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_END_STREAM,
+ NGHTTP2_HCAT_REQUEST)));
+ visitor.OnBeginHeadersForStream(1);
+
+ EXPECT_EQ(visitor.stream_map_size(), 1);
+
+ EXPECT_CALL(callbacks, OnHeader).Times(5);
+ visitor.OnHeaderForStream(1, ":method", "POST");
+ visitor.OnHeaderForStream(1, ":path", "/example/path");
+ visitor.OnHeaderForStream(1, ":scheme", "https");
+ visitor.OnHeaderForStream(1, ":authority", "example.com");
+ visitor.OnHeaderForStream(1, "accept", "text/html");
+
+ EXPECT_CALL(callbacks,
+ OnFrameRecv(IsHeaders(
+ 1, NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_END_STREAM,
+ NGHTTP2_HCAT_REQUEST)));
+ visitor.OnEndHeadersForStream(1);
+
+ EXPECT_TRUE(visitor.OnEndStream(1));
+
+ EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
+ visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);
+
+ EXPECT_EQ(visitor.stream_map_size(), 0);
+
+ // Invalid repeat HEADERS on closed stream 1
+ EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(
+ 1, HEADERS, NGHTTP2_FLAG_END_HEADERS)));
+ visitor.OnFrameHeader(1, 23, HEADERS, 4);
+
+ EXPECT_CALL(callbacks, OnBeginHeaders(IsHeaders(1, NGHTTP2_FLAG_END_HEADERS,
+ NGHTTP2_HCAT_REQUEST)));
+ visitor.OnBeginHeadersForStream(1);
+
+ // Bug: the visitor should not revive streams that have already been closed.
+ EXPECT_EQ(visitor.stream_map_size(), 1);
+}
+
} // namespace
} // namespace test
} // namespace adapter