| #include "http2/adapter/nghttp2_util.h" | 
 |  | 
 | #include "http2/adapter/nghttp2_test_utils.h" | 
 | #include "http2/adapter/test_utils.h" | 
 | #include "common/platform/api/quiche_test.h" | 
 |  | 
 | namespace http2 { | 
 | namespace adapter { | 
 | namespace test { | 
 | namespace { | 
 |  | 
 | // This send callback assumes |source|'s pointer is a TestDataSource, and | 
 | // |user_data| is a std::string. | 
 | int FakeSendCallback(nghttp2_session*, nghttp2_frame* /*frame*/, | 
 |                      const uint8_t* framehd, size_t length, | 
 |                      nghttp2_data_source* source, void* user_data) { | 
 |   auto* dest = static_cast<std::string*>(user_data); | 
 |   // Appends the frame header to the string. | 
 |   absl::StrAppend(dest, ToStringView(framehd, 9)); | 
 |   auto* test_source = static_cast<TestDataSource*>(source->ptr); | 
 |   absl::string_view payload = test_source->ReadNext(length); | 
 |   // Appends the frame payload to the string. | 
 |   absl::StrAppend(dest, payload); | 
 |   return 0; | 
 | } | 
 |  | 
 | TEST(MakeZeroCopyDataFrameSource, EmptyPayload) { | 
 |   std::string result; | 
 |  | 
 |   const absl::string_view kEmptyBody = ""; | 
 |   TestDataSource body1{kEmptyBody}; | 
 |   // The TestDataSource is wrapped in the nghttp2_data_provider data type. | 
 |   nghttp2_data_provider provider = body1.MakeDataProvider(); | 
 |  | 
 |   // This call transforms it back into a DataFrameSource, which is compatible | 
 |   // with the Http2Adapter API. | 
 |   std::unique_ptr<DataFrameSource> frame_source = | 
 |       MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback); | 
 |   auto [length, eof] = frame_source->SelectPayloadLength(100); | 
 |   EXPECT_EQ(length, 0); | 
 |   EXPECT_TRUE(eof); | 
 |   frame_source->Send("ninebytes", 0); | 
 |   EXPECT_EQ(result, "ninebytes"); | 
 | } | 
 |  | 
 | TEST(MakeZeroCopyDataFrameSource, ShortPayload) { | 
 |   std::string result; | 
 |  | 
 |   const absl::string_view kShortBody = | 
 |       "<html><head><title>Example Page!</title></head>" | 
 |       "<body><div><span><table><tr><th><blink>Wow!!" | 
 |       "</blink></th></tr></table></span></div></body>" | 
 |       "</html>"; | 
 |   TestDataSource body1{kShortBody}; | 
 |   // The TestDataSource is wrapped in the nghttp2_data_provider data type. | 
 |   nghttp2_data_provider provider = body1.MakeDataProvider(); | 
 |  | 
 |   // This call transforms it back into a DataFrameSource, which is compatible | 
 |   // with the Http2Adapter API. | 
 |   std::unique_ptr<DataFrameSource> frame_source = | 
 |       MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback); | 
 |   auto [length, eof] = frame_source->SelectPayloadLength(200); | 
 |   EXPECT_EQ(length, kShortBody.size()); | 
 |   EXPECT_TRUE(eof); | 
 |   frame_source->Send("ninebytes", length); | 
 |   EXPECT_EQ(result, absl::StrCat("ninebytes", kShortBody)); | 
 | } | 
 |  | 
 | TEST(MakeZeroCopyDataFrameSource, MultiFramePayload) { | 
 |   std::string result; | 
 |  | 
 |   const absl::string_view kShortBody = | 
 |       "<html><head><title>Example Page!</title></head>" | 
 |       "<body><div><span><table><tr><th><blink>Wow!!" | 
 |       "</blink></th></tr></table></span></div></body>" | 
 |       "</html>"; | 
 |   TestDataSource body1{kShortBody}; | 
 |   // The TestDataSource is wrapped in the nghttp2_data_provider data type. | 
 |   nghttp2_data_provider provider = body1.MakeDataProvider(); | 
 |  | 
 |   // This call transforms it back into a DataFrameSource, which is compatible | 
 |   // with the Http2Adapter API. | 
 |   std::unique_ptr<DataFrameSource> frame_source = | 
 |       MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback); | 
 |   auto ret = frame_source->SelectPayloadLength(50); | 
 |   EXPECT_EQ(ret.first, 50); | 
 |   EXPECT_FALSE(ret.second); | 
 |   frame_source->Send("ninebyte1", ret.first); | 
 |  | 
 |   ret = frame_source->SelectPayloadLength(50); | 
 |   EXPECT_EQ(ret.first, 50); | 
 |   EXPECT_FALSE(ret.second); | 
 |   frame_source->Send("ninebyte2", ret.first); | 
 |  | 
 |   ret = frame_source->SelectPayloadLength(50); | 
 |   EXPECT_EQ(ret.first, 44); | 
 |   EXPECT_TRUE(ret.second); | 
 |   frame_source->Send("ninebyte3", ret.first); | 
 |  | 
 |   EXPECT_EQ(result, | 
 |             "ninebyte1<html><head><title>Example Page!</title></head><bo" | 
 |             "ninebyte2dy><div><span><table><tr><th><blink>Wow!!</blink><" | 
 |             "ninebyte3/th></tr></table></span></div></body></html>"); | 
 | } | 
 |  | 
 | }  // namespace | 
 | }  // namespace test | 
 | }  // namespace adapter | 
 | }  // namespace http2 |