Adds a bool return value to `Http2VisitorInterface::OnEndStream()` to indicate success.
An implementation of that method will soon invoke nghttp2 callbacks, which can fail.
PiperOrigin-RevId: 488470078
diff --git a/quiche/http2/adapter/callback_visitor.cc b/quiche/http2/adapter/callback_visitor.cc
index 7cdb835..993a8c4 100644
--- a/quiche/http2/adapter/callback_visitor.cc
+++ b/quiche/http2/adapter/callback_visitor.cc
@@ -255,8 +255,9 @@
return result == 0;
}
-void CallbackVisitor::OnEndStream(Http2StreamId stream_id) {
+bool CallbackVisitor::OnEndStream(Http2StreamId stream_id) {
QUICHE_VLOG(1) << "OnEndStream(stream_id=" << stream_id << ")";
+ return true;
}
void CallbackVisitor::OnRstStream(Http2StreamId stream_id,
diff --git a/quiche/http2/adapter/callback_visitor.h b/quiche/http2/adapter/callback_visitor.h
index 7c982e8..5132104 100644
--- a/quiche/http2/adapter/callback_visitor.h
+++ b/quiche/http2/adapter/callback_visitor.h
@@ -45,7 +45,7 @@
size_t payload_length) override;
bool OnDataForStream(Http2StreamId stream_id,
absl::string_view data) override;
- void OnEndStream(Http2StreamId stream_id) override;
+ bool OnEndStream(Http2StreamId stream_id) override;
void OnRstStream(Http2StreamId stream_id, Http2ErrorCode error_code) override;
bool OnCloseStream(Http2StreamId stream_id,
Http2ErrorCode error_code) override;
diff --git a/quiche/http2/adapter/callback_visitor_test.cc b/quiche/http2/adapter/callback_visitor_test.cc
index 3eb16c6..68a83d3 100644
--- a/quiche/http2/adapter/callback_visitor_test.cc
+++ b/quiche/http2/adapter/callback_visitor_test.cc
@@ -168,7 +168,7 @@
EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, NGHTTP2_FLAG_END_STREAM)));
visitor.OnBeginDataForStream(1, 0);
- visitor.OnEndStream(1);
+ EXPECT_TRUE(visitor.OnEndStream(1));
EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);
@@ -388,7 +388,7 @@
"This is the request body."));
EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, NGHTTP2_FLAG_END_STREAM)));
visitor.OnDataForStream(1, "This is the request body.");
- visitor.OnEndStream(1);
+ EXPECT_TRUE(visitor.OnEndStream(1));
EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);
@@ -431,7 +431,7 @@
OnDataChunkRecv(kFlags, 1, "This is the request body."));
EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, kFlags, kPaddingLength)));
EXPECT_TRUE(visitor.OnDataForStream(1, "This is the request body."));
- visitor.OnEndStream(1);
+ EXPECT_TRUE(visitor.OnEndStream(1));
EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);
@@ -449,7 +449,7 @@
EXPECT_CALL(callbacks, OnFrameRecv(IsData(3, _, kFlags, kPaddingLength)));
EXPECT_TRUE(visitor.OnDataPaddingLength(3, kPaddingLength));
- visitor.OnEndStream(3);
+ EXPECT_TRUE(visitor.OnEndStream(3));
EXPECT_CALL(callbacks, OnStreamClose(3, NGHTTP2_NO_ERROR));
visitor.OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR);
@@ -468,7 +468,7 @@
EXPECT_CALL(callbacks, OnFrameRecv(IsData(5, _, kFlags, kPaddingLength)))
.WillOnce(testing::Return(NGHTTP2_ERR_CALLBACK_FAILURE));
EXPECT_FALSE(visitor.OnDataPaddingLength(5, kPaddingLength));
- visitor.OnEndStream(3);
+ EXPECT_TRUE(visitor.OnEndStream(3));
EXPECT_CALL(callbacks, OnStreamClose(5, NGHTTP2_NO_ERROR));
visitor.OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR);
diff --git a/quiche/http2/adapter/http2_visitor_interface.h b/quiche/http2/adapter/http2_visitor_interface.h
index 77bcd7f..fa8491d 100644
--- a/quiche/http2/adapter/http2_visitor_interface.h
+++ b/quiche/http2/adapter/http2_visitor_interface.h
@@ -166,7 +166,7 @@
// Called when the peer sends the END_STREAM flag on a stream, indicating that
// the peer will not send additional headers or data for that stream.
- virtual void OnEndStream(Http2StreamId stream_id) = 0;
+ virtual bool OnEndStream(Http2StreamId stream_id) = 0;
// Called when the connection receives a RST_STREAM for a stream. This call
// will be followed by either OnCloseStream().
diff --git a/quiche/http2/adapter/mock_http2_visitor.h b/quiche/http2/adapter/mock_http2_visitor.h
index d6f437b..86345d3 100644
--- a/quiche/http2/adapter/mock_http2_visitor.h
+++ b/quiche/http2/adapter/mock_http2_visitor.h
@@ -23,6 +23,7 @@
ON_CALL(*this, OnDataPaddingLength).WillByDefault(testing::Return(true));
ON_CALL(*this, OnBeginDataForStream).WillByDefault(testing::Return(true));
ON_CALL(*this, OnDataForStream).WillByDefault(testing::Return(true));
+ ON_CALL(*this, OnEndStream).WillByDefault(testing::Return(true));
ON_CALL(*this, OnCloseStream).WillByDefault(testing::Return(true));
ON_CALL(*this, OnGoAway).WillByDefault(testing::Return(true));
ON_CALL(*this, OnInvalidFrame).WillByDefault(testing::Return(true));
@@ -61,7 +62,7 @@
MOCK_METHOD(bool, OnDataForStream,
(Http2StreamId stream_id, absl::string_view data), (override));
- MOCK_METHOD(void, OnEndStream, (Http2StreamId stream_id), (override));
+ MOCK_METHOD(bool, OnEndStream, (Http2StreamId stream_id), (override));
MOCK_METHOD(void, OnRstStream,
(Http2StreamId stream_id, Http2ErrorCode error_code), (override));
diff --git a/quiche/http2/adapter/nghttp2_callbacks.cc b/quiche/http2/adapter/nghttp2_callbacks.cc
index 067c522..200a709 100644
--- a/quiche/http2/adapter/nghttp2_callbacks.cc
+++ b/quiche/http2/adapter/nghttp2_callbacks.cc
@@ -73,7 +73,10 @@
visitor->OnDataPaddingLength(stream_id, frame->data.padlen);
}
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
- visitor->OnEndStream(stream_id);
+ const bool result = visitor->OnEndStream(stream_id);
+ if (!result) {
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
}
break;
case NGHTTP2_HEADERS: {
@@ -84,7 +87,10 @@
}
}
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
- visitor->OnEndStream(stream_id);
+ const bool result = visitor->OnEndStream(stream_id);
+ if (!result) {
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
}
break;
}
diff --git a/quiche/http2/adapter/oghttp2_session.cc b/quiche/http2/adapter/oghttp2_session.cc
index 52c0a12..c0c2c61 100644
--- a/quiche/http2/adapter/oghttp2_session.cc
+++ b/quiche/http2/adapter/oghttp2_session.cc
@@ -1120,7 +1120,11 @@
return;
}
- visitor_.OnEndStream(stream_id);
+ const bool result = visitor_.OnEndStream(stream_id);
+ if (!result) {
+ fatal_visitor_callback_failure_ = true;
+ decoder_.StopProcessing();
+ }
}
auto queued_frames_iter = queued_frames_.find(stream_id);
diff --git a/quiche/http2/adapter/recording_http2_visitor.cc b/quiche/http2/adapter/recording_http2_visitor.cc
index 6321fd8..d55045f 100644
--- a/quiche/http2/adapter/recording_http2_visitor.cc
+++ b/quiche/http2/adapter/recording_http2_visitor.cc
@@ -80,8 +80,9 @@
return true;
}
-void RecordingHttp2Visitor::OnEndStream(Http2StreamId stream_id) {
+bool RecordingHttp2Visitor::OnEndStream(Http2StreamId stream_id) {
events_.push_back(absl::StrFormat("OnEndStream %d", stream_id));
+ return true;
}
void RecordingHttp2Visitor::OnRstStream(Http2StreamId stream_id,
diff --git a/quiche/http2/adapter/recording_http2_visitor.h b/quiche/http2/adapter/recording_http2_visitor.h
index 4310e4c..d796fe7 100644
--- a/quiche/http2/adapter/recording_http2_visitor.h
+++ b/quiche/http2/adapter/recording_http2_visitor.h
@@ -39,7 +39,7 @@
size_t payload_length) override;
bool OnDataForStream(Http2StreamId stream_id,
absl::string_view data) override;
- void OnEndStream(Http2StreamId stream_id) override;
+ bool OnEndStream(Http2StreamId stream_id) override;
void OnRstStream(Http2StreamId stream_id, Http2ErrorCode error_code) override;
bool OnCloseStream(Http2StreamId stream_id,
Http2ErrorCode error_code) override;