xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/adapter/nghttp2_util_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 #include "quiche/http2/adapter/nghttp2_util.h"
2 
3 #include "quiche/http2/adapter/nghttp2_test_utils.h"
4 #include "quiche/http2/adapter/test_utils.h"
5 #include "quiche/common/platform/api/quiche_test.h"
6 
7 namespace http2 {
8 namespace adapter {
9 namespace test {
10 namespace {
11 
12 // This send callback assumes |source|'s pointer is a TestDataSource, and
13 // |user_data| is a std::string.
FakeSendCallback(nghttp2_session *,nghttp2_frame *,const uint8_t * framehd,size_t length,nghttp2_data_source * source,void * user_data)14 int FakeSendCallback(nghttp2_session*, nghttp2_frame* /*frame*/,
15                      const uint8_t* framehd, size_t length,
16                      nghttp2_data_source* source, void* user_data) {
17   auto* dest = static_cast<std::string*>(user_data);
18   // Appends the frame header to the string.
19   absl::StrAppend(dest, ToStringView(framehd, 9));
20   auto* test_source = static_cast<TestDataSource*>(source->ptr);
21   absl::string_view payload = test_source->ReadNext(length);
22   // Appends the frame payload to the string.
23   absl::StrAppend(dest, payload);
24   return 0;
25 }
26 
TEST(MakeZeroCopyDataFrameSource,EmptyPayload)27 TEST(MakeZeroCopyDataFrameSource, EmptyPayload) {
28   std::string result;
29 
30   const absl::string_view kEmptyBody = "";
31   TestDataSource body1{kEmptyBody};
32   // The TestDataSource is wrapped in the nghttp2_data_provider data type.
33   nghttp2_data_provider provider = body1.MakeDataProvider();
34 
35   // This call transforms it back into a DataFrameSource, which is compatible
36   // with the Http2Adapter API.
37   std::unique_ptr<DataFrameSource> frame_source =
38       MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback);
39   auto [length, eof] = frame_source->SelectPayloadLength(100);
40   EXPECT_EQ(length, 0);
41   EXPECT_TRUE(eof);
42   frame_source->Send("ninebytes", 0);
43   EXPECT_EQ(result, "ninebytes");
44 }
45 
TEST(MakeZeroCopyDataFrameSource,ShortPayload)46 TEST(MakeZeroCopyDataFrameSource, ShortPayload) {
47   std::string result;
48 
49   const absl::string_view kShortBody =
50       "<html><head><title>Example Page!</title></head>"
51       "<body><div><span><table><tr><th><blink>Wow!!"
52       "</blink></th></tr></table></span></div></body>"
53       "</html>";
54   TestDataSource body1{kShortBody};
55   // The TestDataSource is wrapped in the nghttp2_data_provider data type.
56   nghttp2_data_provider provider = body1.MakeDataProvider();
57 
58   // This call transforms it back into a DataFrameSource, which is compatible
59   // with the Http2Adapter API.
60   std::unique_ptr<DataFrameSource> frame_source =
61       MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback);
62   auto [length, eof] = frame_source->SelectPayloadLength(200);
63   EXPECT_EQ(length, kShortBody.size());
64   EXPECT_TRUE(eof);
65   frame_source->Send("ninebytes", length);
66   EXPECT_EQ(result, absl::StrCat("ninebytes", kShortBody));
67 }
68 
TEST(MakeZeroCopyDataFrameSource,MultiFramePayload)69 TEST(MakeZeroCopyDataFrameSource, MultiFramePayload) {
70   std::string result;
71 
72   const absl::string_view kShortBody =
73       "<html><head><title>Example Page!</title></head>"
74       "<body><div><span><table><tr><th><blink>Wow!!"
75       "</blink></th></tr></table></span></div></body>"
76       "</html>";
77   TestDataSource body1{kShortBody};
78   // The TestDataSource is wrapped in the nghttp2_data_provider data type.
79   nghttp2_data_provider provider = body1.MakeDataProvider();
80 
81   // This call transforms it back into a DataFrameSource, which is compatible
82   // with the Http2Adapter API.
83   std::unique_ptr<DataFrameSource> frame_source =
84       MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback);
85   auto ret = frame_source->SelectPayloadLength(50);
86   EXPECT_EQ(ret.first, 50);
87   EXPECT_FALSE(ret.second);
88   frame_source->Send("ninebyte1", ret.first);
89 
90   ret = frame_source->SelectPayloadLength(50);
91   EXPECT_EQ(ret.first, 50);
92   EXPECT_FALSE(ret.second);
93   frame_source->Send("ninebyte2", ret.first);
94 
95   ret = frame_source->SelectPayloadLength(50);
96   EXPECT_EQ(ret.first, 44);
97   EXPECT_TRUE(ret.second);
98   frame_source->Send("ninebyte3", ret.first);
99 
100   EXPECT_EQ(result,
101             "ninebyte1<html><head><title>Example Page!</title></head><bo"
102             "ninebyte2dy><div><span><table><tr><th><blink>Wow!!</blink><"
103             "ninebyte3/th></tr></table></span></div></body></html>");
104 }
105 
106 }  // namespace
107 }  // namespace test
108 }  // namespace adapter
109 }  // namespace http2
110