Fixes the nghttp2_data_provider adapter to return an accurate status value when a DataFrameSource indicates fin with no data.
PiperOrigin-RevId: 386564110
diff --git a/http2/adapter/nghttp2_data_provider.cc b/http2/adapter/nghttp2_data_provider.cc
index 83037e4..200aa67 100644
--- a/http2/adapter/nghttp2_data_provider.cc
+++ b/http2/adapter/nghttp2_data_provider.cc
@@ -21,7 +21,7 @@
*data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
auto* frame_source = static_cast<DataFrameSource*>(source->ptr);
auto [result_length, done] = frame_source->SelectPayloadLength(length);
- if (result_length == DataFrameSource::kBlocked) {
+ if (result_length == 0 && !done) {
return NGHTTP2_ERR_DEFERRED;
} else if (result_length == DataFrameSource::kError) {
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
diff --git a/http2/adapter/nghttp2_data_provider_test.cc b/http2/adapter/nghttp2_data_provider_test.cc
index 7cf53d0..394aea4 100644
--- a/http2/adapter/nghttp2_data_provider_test.cc
+++ b/http2/adapter/nghttp2_data_provider_test.cc
@@ -98,8 +98,16 @@
ssize_t result =
provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
&data_flags, &provider->source, nullptr);
- // BUG: should return a zero-length read and EOF.
- ASSERT_EQ(NGHTTP2_ERR_DEFERRED, result);
+ ASSERT_EQ(0, result);
+ EXPECT_EQ(NGHTTP2_DATA_FLAG_NO_COPY | NGHTTP2_DATA_FLAG_EOF, data_flags);
+
+ const uint8_t framehd[kFrameHeaderSize] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ int send_result = callbacks::DataFrameSourceSendCallback(
+ nullptr, nullptr, framehd, result, &provider->source, nullptr);
+ EXPECT_EQ(0, send_result);
+ // Data accepted by the visitor includes a frame header with fin and zero
+ // bytes of payload.
+ EXPECT_EQ(visitor.data().size(), kFrameHeaderSize);
}
} // namespace test