xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/adapter/nghttp2_adapter_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 #include "quiche/http2/adapter/nghttp2_adapter.h"
2 
3 #include <memory>
4 
5 #include "quiche/http2/adapter/http2_protocol.h"
6 #include "quiche/http2/adapter/http2_visitor_interface.h"
7 #include "quiche/http2/adapter/mock_http2_visitor.h"
8 #include "quiche/http2/adapter/nghttp2.h"
9 #include "quiche/http2/adapter/nghttp2_test_utils.h"
10 #include "quiche/http2/adapter/oghttp2_util.h"
11 #include "quiche/http2/adapter/test_frame_sequence.h"
12 #include "quiche/http2/adapter/test_utils.h"
13 #include "quiche/common/platform/api/quiche_test.h"
14 
15 namespace http2 {
16 namespace adapter {
17 namespace test {
18 namespace {
19 
20 using ConnectionError = Http2VisitorInterface::ConnectionError;
21 
22 using spdy::SpdyFrameType;
23 using testing::_;
24 
25 enum FrameType {
26   DATA,
27   HEADERS,
28   PRIORITY,
29   RST_STREAM,
30   SETTINGS,
31   PUSH_PROMISE,
32   PING,
33   GOAWAY,
34   WINDOW_UPDATE,
35   CONTINUATION,
36 };
37 
38 // This send callback assumes |source|'s pointer is a TestDataSource, and
39 // |user_data| is a Http2VisitorInterface.
TestSendCallback(nghttp2_session *,nghttp2_frame *,const uint8_t * framehd,size_t length,nghttp2_data_source * source,void * user_data)40 int TestSendCallback(nghttp2_session*, nghttp2_frame* /*frame*/,
41                      const uint8_t* framehd, size_t length,
42                      nghttp2_data_source* source, void* user_data) {
43   auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
44   // Send the frame header via the visitor.
45   ssize_t result = visitor->OnReadyToSend(ToStringView(framehd, 9));
46   if (result == 0) {
47     return NGHTTP2_ERR_WOULDBLOCK;
48   }
49   auto* test_source = static_cast<TestDataSource*>(source->ptr);
50   absl::string_view payload = test_source->ReadNext(length);
51   // Send the frame payload via the visitor.
52   visitor->OnReadyToSend(payload);
53   return 0;
54 }
55 
TEST(NgHttp2AdapterTest,ClientConstruction)56 TEST(NgHttp2AdapterTest, ClientConstruction) {
57   testing::StrictMock<MockHttp2Visitor> visitor;
58   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
59   ASSERT_NE(nullptr, adapter);
60   EXPECT_TRUE(adapter->want_read());
61   EXPECT_FALSE(adapter->want_write());
62   EXPECT_FALSE(adapter->IsServerSession());
63 }
64 
TEST(NgHttp2AdapterTest,ClientHandlesFrames)65 TEST(NgHttp2AdapterTest, ClientHandlesFrames) {
66   DataSavingVisitor visitor;
67   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
68   int result = adapter->Send();
69   EXPECT_EQ(0, result);
70   EXPECT_THAT(visitor.data(),
71               testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
72   visitor.Clear();
73 
74   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
75 
76   const std::string initial_frames = TestFrameSequence()
77                                          .ServerPreface()
78                                          .Ping(42)
79                                          .WindowUpdate(0, 1000)
80                                          .Serialize();
81   testing::InSequence s;
82 
83   // Server preface (empty SETTINGS)
84   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
85   EXPECT_CALL(visitor, OnSettingsStart());
86   EXPECT_CALL(visitor, OnSettingsEnd());
87 
88   EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
89   EXPECT_CALL(visitor, OnPing(42, false));
90   EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
91   EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
92 
93   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
94   EXPECT_EQ(initial_frames.size(), initial_result);
95 
96   EXPECT_EQ(adapter->GetSendWindowSize(), kInitialFlowControlWindowSize + 1000);
97 
98   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
99   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
100   EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, 8, 0x1));
101   EXPECT_CALL(visitor, OnFrameSent(PING, 0, 8, 0x1, 0));
102 
103   result = adapter->Send();
104   // Some bytes should have been serialized.
105   EXPECT_EQ(0, result);
106   EXPECT_THAT(visitor.data(),
107               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
108   visitor.Clear();
109 
110   const std::vector<Header> headers1 =
111       ToHeaders({{":method", "GET"},
112                  {":scheme", "http"},
113                  {":authority", "example.com"},
114                  {":path", "/this/is/request/one"}});
115 
116   const std::vector<Header> headers2 =
117       ToHeaders({{":method", "GET"},
118                  {":scheme", "http"},
119                  {":authority", "example.com"},
120                  {":path", "/this/is/request/two"}});
121 
122   const std::vector<Header> headers3 =
123       ToHeaders({{":method", "GET"},
124                  {":scheme", "http"},
125                  {":authority", "example.com"},
126                  {":path", "/this/is/request/three"}});
127 
128   const char* kSentinel1 = "arbitrary pointer 1";
129   const char* kSentinel3 = "arbitrary pointer 3";
130   const int32_t stream_id1 =
131       adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
132   ASSERT_GT(stream_id1, 0);
133   QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
134 
135   const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
136   ASSERT_GT(stream_id2, 0);
137   QUICHE_LOG(INFO) << "Created stream: " << stream_id2;
138 
139   const int32_t stream_id3 =
140       adapter->SubmitRequest(headers3, nullptr, const_cast<char*>(kSentinel3));
141   ASSERT_GT(stream_id3, 0);
142   QUICHE_LOG(INFO) << "Created stream: " << stream_id3;
143 
144   const char* kSentinel2 = "arbitrary pointer 2";
145   adapter->SetStreamUserData(stream_id2, const_cast<char*>(kSentinel2));
146   adapter->SetStreamUserData(stream_id3, nullptr);
147 
148   EXPECT_EQ(adapter->sources_size(), 3);
149 
150   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
151   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
152   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
153   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
154   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id3, _, 0x5));
155   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id3, _, 0x5, 0));
156 
157   result = adapter->Send();
158   EXPECT_EQ(0, result);
159   EXPECT_THAT(visitor.data(),
160               EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::HEADERS,
161                             SpdyFrameType::HEADERS}));
162   visitor.Clear();
163 
164   // All streams are active and have not yet received any data, so the receive
165   // window should be at the initial value.
166   EXPECT_EQ(kInitialFlowControlWindowSize,
167             adapter->GetStreamReceiveWindowSize(stream_id1));
168   EXPECT_EQ(kInitialFlowControlWindowSize,
169             adapter->GetStreamReceiveWindowSize(stream_id2));
170   EXPECT_EQ(kInitialFlowControlWindowSize,
171             adapter->GetStreamReceiveWindowSize(stream_id3));
172 
173   // Upper bound on the flow control receive window should be the initial value.
174   EXPECT_EQ(kInitialFlowControlWindowSize,
175             adapter->GetStreamReceiveWindowLimit(stream_id1));
176 
177   // Connection has not yet received any data.
178   EXPECT_EQ(kInitialFlowControlWindowSize, adapter->GetReceiveWindowSize());
179 
180   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
181 
182   EXPECT_EQ(kSentinel1, adapter->GetStreamUserData(stream_id1));
183   EXPECT_EQ(kSentinel2, adapter->GetStreamUserData(stream_id2));
184   EXPECT_EQ(nullptr, adapter->GetStreamUserData(stream_id3));
185 
186   EXPECT_EQ(0, adapter->GetHpackDecoderDynamicTableSize());
187 
188   const std::string stream_frames =
189       TestFrameSequence()
190           .Headers(1,
191                    {{":status", "200"},
192                     {"server", "my-fake-server"},
193                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
194                    /*fin=*/false)
195           .Data(1, "This is the response body.")
196           .RstStream(3, Http2ErrorCode::INTERNAL_ERROR)
197           .GoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!")
198           .Serialize();
199 
200   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
201   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
202   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
203   EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
204   EXPECT_CALL(visitor,
205               OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
206   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
207   EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
208   EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
209   EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
210   EXPECT_CALL(visitor, OnFrameHeader(3, 4, RST_STREAM, 0));
211   EXPECT_CALL(visitor, OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR));
212   EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR))
213       .WillOnce(
214           [&adapter](Http2StreamId stream_id, Http2ErrorCode /*error_code*/) {
215             adapter->RemoveStream(stream_id);
216             return true;
217           });
218   EXPECT_CALL(visitor, OnFrameHeader(0, 19, GOAWAY, 0));
219   EXPECT_CALL(visitor,
220               OnGoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!"));
221   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
222   EXPECT_EQ(stream_frames.size(), stream_result);
223 
224   // First stream has received some data.
225   EXPECT_GT(kInitialFlowControlWindowSize,
226             adapter->GetStreamReceiveWindowSize(stream_id1));
227   // Second stream was closed.
228   EXPECT_EQ(-1, adapter->GetStreamReceiveWindowSize(stream_id2));
229   // Third stream has not received any data.
230   EXPECT_EQ(kInitialFlowControlWindowSize,
231             adapter->GetStreamReceiveWindowSize(stream_id3));
232 
233   // One stream was closed.
234   EXPECT_EQ(adapter->sources_size(), 2);
235 
236   // Connection window should be the same as the first stream.
237   EXPECT_EQ(adapter->GetReceiveWindowSize(),
238             adapter->GetStreamReceiveWindowSize(stream_id1));
239 
240   // Upper bound on the flow control receive window should still be the initial
241   // value.
242   EXPECT_EQ(kInitialFlowControlWindowSize,
243             adapter->GetStreamReceiveWindowLimit(stream_id1));
244 
245   EXPECT_GT(adapter->GetHpackDecoderDynamicTableSize(), 0);
246 
247   // Should be 3, but this method only works for server adapters.
248   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
249 
250   // Even though the client recieved a GOAWAY, streams 1 and 5 are still active.
251   EXPECT_TRUE(adapter->want_read());
252 
253   EXPECT_CALL(visitor, OnFrameHeader(1, 0, DATA, 1));
254   EXPECT_CALL(visitor, OnBeginDataForStream(1, 0));
255   EXPECT_CALL(visitor, OnEndStream(1));
256   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR))
257       .WillOnce(
258           [&adapter](Http2StreamId stream_id, Http2ErrorCode /*error_code*/) {
259             adapter->RemoveStream(stream_id);
260             return true;
261           });
262   EXPECT_CALL(visitor, OnFrameHeader(5, 4, RST_STREAM, 0));
263   EXPECT_CALL(visitor, OnRstStream(5, Http2ErrorCode::REFUSED_STREAM));
264   EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::REFUSED_STREAM))
265       .WillOnce(
266           [&adapter](Http2StreamId stream_id, Http2ErrorCode /*error_code*/) {
267             adapter->RemoveStream(stream_id);
268             return true;
269           });
270   adapter->ProcessBytes(TestFrameSequence()
271                             .Data(1, "", true)
272                             .RstStream(5, Http2ErrorCode::REFUSED_STREAM)
273                             .Serialize());
274 
275   // Should be 5, but this method only works for server adapters.
276   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
277 
278   // After receiving END_STREAM for 1 and RST_STREAM for 5, the session no
279   // longer expects reads.
280   EXPECT_FALSE(adapter->want_read());
281   EXPECT_EQ(adapter->sources_size(), 0);
282 
283   // Client will not have anything else to write.
284   EXPECT_FALSE(adapter->want_write());
285   result = adapter->Send();
286   EXPECT_EQ(0, result);
287   EXPECT_THAT(visitor.data(), testing::IsEmpty());
288 }
289 
TEST(NgHttp2AdapterTest,QueuingWindowUpdateAffectsWindow)290 TEST(NgHttp2AdapterTest, QueuingWindowUpdateAffectsWindow) {
291   DataSavingVisitor visitor;
292   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
293 
294   EXPECT_EQ(adapter->GetReceiveWindowSize(), kInitialFlowControlWindowSize);
295   adapter->SubmitWindowUpdate(0, 10000);
296   EXPECT_EQ(adapter->GetReceiveWindowSize(),
297             kInitialFlowControlWindowSize + 10000);
298 
299   const std::vector<Header> headers =
300       ToHeaders({{":method", "GET"},
301                  {":scheme", "http"},
302                  {":authority", "example.com"},
303                  {":path", "/this/is/request/one"}});
304   const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
305 
306   EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
307   EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
308   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
309   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
310 
311   int result = adapter->Send();
312   EXPECT_EQ(0, result);
313 
314   EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id),
315             kInitialFlowControlWindowSize);
316   adapter->SubmitWindowUpdate(1, 20000);
317   EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id),
318             kInitialFlowControlWindowSize + 20000);
319 }
320 
TEST(NgHttp2AdapterTest,AckOfSettingInitialWindowSizeAffectsWindow)321 TEST(NgHttp2AdapterTest, AckOfSettingInitialWindowSizeAffectsWindow) {
322   DataSavingVisitor visitor;
323   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
324 
325   testing::InSequence s;
326 
327   const std::vector<Header> headers =
328       ToHeaders({{":method", "GET"},
329                  {":scheme", "http"},
330                  {":authority", "example.com"},
331                  {":path", "/this/is/request/one"}});
332   const int32_t stream_id1 = adapter->SubmitRequest(headers, nullptr, nullptr);
333 
334   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
335   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
336 
337   int result = adapter->Send();
338   EXPECT_EQ(0, result);
339 
340   const std::string initial_frames =
341       TestFrameSequence().ServerPreface().Serialize();
342   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x0));
343   EXPECT_CALL(visitor, OnSettingsStart());
344   EXPECT_CALL(visitor, OnSettingsEnd());
345 
346   int64_t parse_result = adapter->ProcessBytes(initial_frames);
347   EXPECT_EQ(initial_frames.size(), static_cast<size_t>(parse_result));
348 
349   EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
350             kInitialFlowControlWindowSize);
351   adapter->SubmitSettings({{INITIAL_WINDOW_SIZE, 80000u}});
352   // No update for the first stream, yet.
353   EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
354             kInitialFlowControlWindowSize);
355 
356   // Ack of server's initial settings.
357   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
358   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
359 
360   // Outbound SETTINGS containing INITIAL_WINDOW_SIZE.
361   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
362   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
363 
364   result = adapter->Send();
365   EXPECT_EQ(0, result);
366 
367   // Still no update, as a SETTINGS ack has not yet been received.
368   EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
369             kInitialFlowControlWindowSize);
370 
371   const std::string settings_ack =
372       TestFrameSequence().SettingsAck().Serialize();
373 
374   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
375   EXPECT_CALL(visitor, OnSettingsAck);
376 
377   parse_result = adapter->ProcessBytes(settings_ack);
378   EXPECT_EQ(settings_ack.size(), static_cast<size_t>(parse_result));
379 
380   // Stream window has been updated.
381   EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1), 80000);
382 
383   const std::vector<Header> headers2 =
384       ToHeaders({{":method", "GET"},
385                  {":scheme", "http"},
386                  {":authority", "example.com"},
387                  {":path", "/this/is/request/two"}});
388   const int32_t stream_id2 = adapter->SubmitRequest(headers, nullptr, nullptr);
389 
390   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
391   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
392   result = adapter->Send();
393   EXPECT_EQ(0, result);
394 
395   EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id2), 80000);
396 }
397 
TEST(NgHttp2AdapterTest,ClientRejects100HeadersWithFin)398 TEST(NgHttp2AdapterTest, ClientRejects100HeadersWithFin) {
399   DataSavingVisitor visitor;
400   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
401 
402   testing::InSequence s;
403 
404   const std::vector<Header> headers1 =
405       ToHeaders({{":method", "GET"},
406                  {":scheme", "http"},
407                  {":authority", "example.com"},
408                  {":path", "/this/is/request/one"}});
409 
410   const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
411   ASSERT_GT(stream_id1, 0);
412   QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
413 
414   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
415   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
416 
417   int result = adapter->Send();
418   EXPECT_EQ(0, result);
419   visitor.Clear();
420 
421   const std::string stream_frames =
422       TestFrameSequence()
423           .ServerPreface()
424           .Headers(1, {{":status", "100"}}, /*fin=*/false)
425           .Headers(1, {{":status", "100"}}, /*fin=*/true)
426           .Serialize();
427 
428   // Server preface (empty SETTINGS)
429   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
430   EXPECT_CALL(visitor, OnSettingsStart());
431   EXPECT_CALL(visitor, OnSettingsEnd());
432 
433   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
434   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
435   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
436   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
437 
438   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
439   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
440   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
441   EXPECT_CALL(visitor,
442               OnInvalidFrame(
443                   1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
444 
445   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
446   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
447 
448   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
449   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
450   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
451   EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, _, 0x0, 1));
452   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
453 
454   EXPECT_TRUE(adapter->want_write());
455   result = adapter->Send();
456   EXPECT_EQ(0, result);
457   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
458                                             SpdyFrameType::RST_STREAM}));
459 }
460 
TEST(NgHttp2AdapterTest,ClientRejects100HeadersWithContent)461 TEST(NgHttp2AdapterTest, ClientRejects100HeadersWithContent) {
462   DataSavingVisitor visitor;
463   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
464 
465   testing::InSequence s;
466 
467   const std::vector<Header> headers1 =
468       ToHeaders({{":method", "GET"},
469                  {":scheme", "http"},
470                  {":authority", "example.com"},
471                  {":path", "/this/is/request/one"}});
472 
473   const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
474   ASSERT_GT(stream_id1, 0);
475 
476   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
477   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
478 
479   int result = adapter->Send();
480   EXPECT_EQ(0, result);
481   visitor.Clear();
482 
483   const std::string stream_frames =
484       TestFrameSequence()
485           .ServerPreface()
486           .Headers(1, {{":status", "100"}},
487                    /*fin=*/false)
488           .Data(1, "We needed the final headers before data, whoops")
489           .Serialize();
490 
491   // Server preface (empty SETTINGS)
492   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
493   EXPECT_CALL(visitor, OnSettingsStart());
494   EXPECT_CALL(visitor, OnSettingsEnd());
495 
496   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
497   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
498   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
499   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
500   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
501   EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
502 
503   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
504   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
505 
506   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
507   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
508   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
509   EXPECT_CALL(visitor,
510               OnFrameSent(RST_STREAM, 1, _, 0x0,
511                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
512   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
513 
514   EXPECT_TRUE(adapter->want_write());
515   result = adapter->Send();
516   EXPECT_EQ(0, result);
517   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
518                                             SpdyFrameType::RST_STREAM}));
519 }
520 
TEST(NgHttp2AdapterTest,ClientRejects100HeadersWithContentLength)521 TEST(NgHttp2AdapterTest, ClientRejects100HeadersWithContentLength) {
522   DataSavingVisitor visitor;
523   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
524 
525   testing::InSequence s;
526 
527   const std::vector<Header> headers1 =
528       ToHeaders({{":method", "GET"},
529                  {":scheme", "http"},
530                  {":authority", "example.com"},
531                  {":path", "/this/is/request/one"}});
532 
533   const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
534   ASSERT_GT(stream_id1, 0);
535 
536   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
537   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
538 
539   int result = adapter->Send();
540   EXPECT_EQ(0, result);
541   visitor.Clear();
542 
543   const std::string stream_frames =
544       TestFrameSequence()
545           .ServerPreface()
546           .Headers(1, {{":status", "100"}, {"content-length", "42"}},
547                    /*fin=*/false)
548           .Headers(1,
549                    {{":status", "200"},
550                     {"server", "my-fake-server"},
551                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
552                    /*fin=*/true)
553           .Serialize();
554 
555   // Server preface (empty SETTINGS)
556   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
557   EXPECT_CALL(visitor, OnSettingsStart());
558   EXPECT_CALL(visitor, OnSettingsEnd());
559 
560   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
561   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
562   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
563   EXPECT_CALL(
564       visitor,
565       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
566                    "stream: 1, name: [content-length], value: [42]"));
567   EXPECT_CALL(
568       visitor,
569       OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
570   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
571 
572   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
573   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
574 
575   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
576   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
577   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
578   EXPECT_CALL(visitor,
579               OnFrameSent(RST_STREAM, 1, _, 0x0,
580                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
581   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
582 
583   EXPECT_TRUE(adapter->want_write());
584   result = adapter->Send();
585   EXPECT_EQ(0, result);
586   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
587                                             SpdyFrameType::RST_STREAM}));
588 }
589 
TEST(NgHttp2AdapterTest,ClientHandles204WithContent)590 TEST(NgHttp2AdapterTest, ClientHandles204WithContent) {
591   DataSavingVisitor visitor;
592   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
593 
594   testing::InSequence s;
595 
596   const std::vector<Header> headers1 =
597       ToHeaders({{":method", "GET"},
598                  {":scheme", "http"},
599                  {":authority", "example.com"},
600                  {":path", "/this/is/request/one"}});
601 
602   const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
603   ASSERT_GT(stream_id1, 0);
604 
605   const std::vector<Header> headers2 =
606       ToHeaders({{":method", "GET"},
607                  {":scheme", "http"},
608                  {":authority", "example.com"},
609                  {":path", "/this/is/request/two"}});
610 
611   const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
612   ASSERT_GT(stream_id2, stream_id1);
613 
614   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
615   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
616   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
617   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
618 
619   int result = adapter->Send();
620   EXPECT_EQ(0, result);
621   visitor.Clear();
622 
623   const std::string stream_frames =
624       TestFrameSequence()
625           .ServerPreface()
626           .Headers(1, {{":status", "204"}, {"content-length", "2"}},
627                    /*fin=*/false)
628           .Data(1, "hi")
629           .Headers(3, {{":status", "204"}}, /*fin=*/false)
630           .Data(3, "hi")
631           .Serialize();
632 
633   // Server preface (empty SETTINGS)
634   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
635   EXPECT_CALL(visitor, OnSettingsStart());
636   EXPECT_CALL(visitor, OnSettingsEnd());
637 
638   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
639   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
640   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "204"));
641   EXPECT_CALL(
642       visitor,
643       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
644                    "stream: 1, name: [content-length], value: [2]"));
645   EXPECT_CALL(
646       visitor,
647       OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
648   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
649   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
650   EXPECT_CALL(visitor, OnHeaderForStream(3, ":status", "204"));
651   EXPECT_CALL(visitor, OnEndHeadersForStream(3));
652   EXPECT_CALL(visitor, OnFrameHeader(3, _, DATA, 0));
653   EXPECT_CALL(visitor, OnBeginDataForStream(3, 2));
654 
655   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
656   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
657 
658   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
659   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
660   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
661   EXPECT_CALL(visitor,
662               OnFrameSent(RST_STREAM, 1, _, 0x0,
663                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
664   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
665   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
666   EXPECT_CALL(visitor,
667               OnFrameSent(RST_STREAM, 3, _, 0x0,
668                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
669   EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
670 
671   EXPECT_TRUE(adapter->want_write());
672   result = adapter->Send();
673   EXPECT_EQ(0, result);
674   EXPECT_THAT(visitor.data(),
675               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
676                             SpdyFrameType::RST_STREAM}));
677 }
678 
TEST(NgHttp2AdapterTest,ClientHandles304WithContent)679 TEST(NgHttp2AdapterTest, ClientHandles304WithContent) {
680   DataSavingVisitor visitor;
681   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
682 
683   testing::InSequence s;
684 
685   const std::vector<Header> headers1 =
686       ToHeaders({{":method", "GET"},
687                  {":scheme", "http"},
688                  {":authority", "example.com"},
689                  {":path", "/this/is/request/one"}});
690 
691   const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
692   ASSERT_GT(stream_id1, 0);
693 
694   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
695   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
696 
697   int result = adapter->Send();
698   EXPECT_EQ(0, result);
699   visitor.Clear();
700 
701   const std::string stream_frames =
702       TestFrameSequence()
703           .ServerPreface()
704           .Headers(1, {{":status", "304"}, {"content-length", "2"}},
705                    /*fin=*/false)
706           .Data(1, "hi")
707           .Serialize();
708 
709   // Server preface (empty SETTINGS)
710   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
711   EXPECT_CALL(visitor, OnSettingsStart());
712   EXPECT_CALL(visitor, OnSettingsEnd());
713 
714   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
715   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
716   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "304"));
717   EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "2"));
718   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
719   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
720   EXPECT_CALL(visitor, OnBeginDataForStream(1, 2));
721 
722   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
723   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
724 
725   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
726   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
727   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
728   EXPECT_CALL(visitor,
729               OnFrameSent(RST_STREAM, 1, _, 0x0,
730                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
731   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
732 
733   EXPECT_TRUE(adapter->want_write());
734   result = adapter->Send();
735   EXPECT_EQ(0, result);
736   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
737                                             SpdyFrameType::RST_STREAM}));
738 }
739 
TEST(NgHttp2AdapterTest,ClientHandles304WithContentLength)740 TEST(NgHttp2AdapterTest, ClientHandles304WithContentLength) {
741   DataSavingVisitor visitor;
742   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
743 
744   testing::InSequence s;
745 
746   const std::vector<Header> headers =
747       ToHeaders({{":method", "GET"},
748                  {":scheme", "http"},
749                  {":authority", "example.com"},
750                  {":path", "/this/is/request/one"}});
751 
752   const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
753   ASSERT_GT(stream_id, 0);
754 
755   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
756   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
757 
758   int result = adapter->Send();
759   EXPECT_EQ(0, result);
760   visitor.Clear();
761 
762   const std::string stream_frames =
763       TestFrameSequence()
764           .ServerPreface()
765           .Headers(1, {{":status", "304"}, {"content-length", "2"}},
766                    /*fin=*/true)
767           .Serialize();
768 
769   // Server preface (empty SETTINGS)
770   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
771   EXPECT_CALL(visitor, OnSettingsStart());
772   EXPECT_CALL(visitor, OnSettingsEnd());
773 
774   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
775   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
776   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "304"));
777   EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "2"));
778   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
779   EXPECT_CALL(visitor, OnEndStream(1));
780   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
781 
782   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
783   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
784 
785   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
786   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
787 
788   EXPECT_TRUE(adapter->want_write());
789   result = adapter->Send();
790   EXPECT_EQ(0, result);
791   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
792 }
793 
TEST(NgHttp2AdapterTest,ClientHandlesTrailers)794 TEST(NgHttp2AdapterTest, ClientHandlesTrailers) {
795   DataSavingVisitor visitor;
796   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
797 
798   testing::InSequence s;
799 
800   const std::vector<Header> headers1 =
801       ToHeaders({{":method", "GET"},
802                  {":scheme", "http"},
803                  {":authority", "example.com"},
804                  {":path", "/this/is/request/one"}});
805 
806   const char* kSentinel1 = "arbitrary pointer 1";
807   const int32_t stream_id1 =
808       adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
809   ASSERT_GT(stream_id1, 0);
810   QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
811 
812   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
813   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
814 
815   int result = adapter->Send();
816   EXPECT_EQ(0, result);
817   absl::string_view data = visitor.data();
818   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
819   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
820   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
821   visitor.Clear();
822 
823   const std::string stream_frames =
824       TestFrameSequence()
825           .ServerPreface()
826           .Headers(1,
827                    {{":status", "200"},
828                     {"server", "my-fake-server"},
829                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
830                    /*fin=*/false)
831           .Data(1, "This is the response body.")
832           .Headers(1, {{"final-status", "A-OK"}},
833                    /*fin=*/true)
834           .Serialize();
835 
836   // Server preface (empty SETTINGS)
837   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
838   EXPECT_CALL(visitor, OnSettingsStart());
839   EXPECT_CALL(visitor, OnSettingsEnd());
840 
841   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
842   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
843   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
844   EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
845   EXPECT_CALL(visitor,
846               OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
847   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
848   EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
849   EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
850   EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
851   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
852   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
853   EXPECT_CALL(visitor, OnHeaderForStream(1, "final-status", "A-OK"));
854   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
855   EXPECT_CALL(visitor, OnEndStream(1));
856   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
857 
858   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
859   EXPECT_EQ(stream_frames.size(), stream_result);
860 
861   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
862   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
863 
864   EXPECT_TRUE(adapter->want_write());
865   result = adapter->Send();
866   EXPECT_EQ(0, result);
867   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
868 }
869 
TEST(NgHttp2AdapterTest,ClientSendsTrailers)870 TEST(NgHttp2AdapterTest, ClientSendsTrailers) {
871   DataSavingVisitor visitor;
872   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
873 
874   testing::InSequence s;
875 
876   const std::vector<Header> headers1 =
877       ToHeaders({{":method", "GET"},
878                  {":scheme", "http"},
879                  {":authority", "example.com"},
880                  {":path", "/this/is/request/one"}});
881 
882   const std::string kBody = "This is an example request body.";
883   auto body1 = std::make_unique<TestDataFrameSource>(visitor, false);
884   body1->AppendPayload(kBody);
885   // nghttp2 does not require that the data source indicate the end of data
886   // before trailers are enqueued.
887 
888   const int32_t stream_id1 =
889       adapter->SubmitRequest(headers1, std::move(body1), nullptr);
890   ASSERT_GT(stream_id1, 0);
891 
892   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x4));
893   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x4, 0));
894   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0));
895 
896   int result = adapter->Send();
897   EXPECT_EQ(0, result);
898   absl::string_view data = visitor.data();
899   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
900   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
901   EXPECT_THAT(data,
902               EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
903   visitor.Clear();
904 
905   const std::vector<Header> trailers1 =
906       ToHeaders({{"extra-info", "Trailers are weird but good?"}});
907   adapter->SubmitTrailer(stream_id1, trailers1);
908 
909   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
910   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
911 
912   result = adapter->Send();
913   EXPECT_EQ(0, result);
914   data = visitor.data();
915   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
916 }
917 
TEST(NgHttp2AdapterTest,ClientHandlesMetadata)918 TEST(NgHttp2AdapterTest, ClientHandlesMetadata) {
919   DataSavingVisitor visitor;
920   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
921 
922   testing::InSequence s;
923 
924   const std::vector<Header> headers1 =
925       ToHeaders({{":method", "GET"},
926                  {":scheme", "http"},
927                  {":authority", "example.com"},
928                  {":path", "/this/is/request/one"}});
929 
930   const char* kSentinel1 = "arbitrary pointer 1";
931   const int32_t stream_id1 =
932       adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
933   ASSERT_GT(stream_id1, 0);
934   QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
935 
936   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
937   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
938 
939   int result = adapter->Send();
940   EXPECT_EQ(0, result);
941   absl::string_view data = visitor.data();
942   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
943   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
944   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
945   visitor.Clear();
946 
947   const std::string stream_frames =
948       TestFrameSequence()
949           .ServerPreface()
950           .Metadata(0, "Example connection metadata")
951           .Headers(1,
952                    {{":status", "200"},
953                     {"server", "my-fake-server"},
954                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
955                    /*fin=*/false)
956           .Metadata(1, "Example stream metadata")
957           .Data(1, "This is the response body.", true)
958           .Serialize();
959 
960   // Server preface (empty SETTINGS)
961   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
962   EXPECT_CALL(visitor, OnSettingsStart());
963   EXPECT_CALL(visitor, OnSettingsEnd());
964 
965   EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
966   EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
967   EXPECT_CALL(visitor, OnMetadataForStream(0, _));
968   EXPECT_CALL(visitor, OnMetadataEndForStream(0));
969   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
970   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
971   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
972   EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
973   EXPECT_CALL(visitor,
974               OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
975   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
976   EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
977   EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
978   EXPECT_CALL(visitor, OnMetadataForStream(1, _));
979   EXPECT_CALL(visitor, OnMetadataEndForStream(1));
980   EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 1));
981   EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
982   EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
983   EXPECT_CALL(visitor, OnEndStream(1));
984   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
985 
986   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
987   EXPECT_EQ(stream_frames.size(), stream_result);
988 
989   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
990   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
991 
992   EXPECT_TRUE(adapter->want_write());
993   result = adapter->Send();
994   EXPECT_EQ(0, result);
995   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
996 }
997 
TEST(NgHttp2AdapterTest,ClientHandlesMetadataWithEmptyPayload)998 TEST(NgHttp2AdapterTest, ClientHandlesMetadataWithEmptyPayload) {
999   DataSavingVisitor visitor;
1000   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1001 
1002   testing::InSequence s;
1003 
1004   const std::vector<Header> headers1 =
1005       ToHeaders({{":method", "GET"},
1006                  {":scheme", "http"},
1007                  {":authority", "example.com"},
1008                  {":path", "/this/is/request/one"}});
1009 
1010   const int32_t stream_id = adapter->SubmitRequest(headers1, nullptr, nullptr);
1011   ASSERT_GT(stream_id, 0);
1012 
1013   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
1014   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
1015 
1016   int result = adapter->Send();
1017   EXPECT_EQ(0, result);
1018   absl::string_view data = visitor.data();
1019   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
1020   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
1021   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
1022   visitor.Clear();
1023 
1024   const std::string stream_frames =
1025       TestFrameSequence()
1026           .ServerPreface()
1027           .Headers(1,
1028                    {{":status", "200"},
1029                     {"server", "my-fake-server"},
1030                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
1031                    /*fin=*/false)
1032           .Metadata(1, "")
1033           .Data(1, "This is the response body.", true)
1034           .Serialize();
1035 
1036   // Server preface (empty SETTINGS)
1037   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1038   EXPECT_CALL(visitor, OnSettingsStart());
1039   EXPECT_CALL(visitor, OnSettingsEnd());
1040 
1041   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
1042   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
1043   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(3);
1044   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
1045   EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
1046   EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
1047   EXPECT_CALL(visitor, OnMetadataEndForStream(1));
1048   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
1049   EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
1050   EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
1051   EXPECT_CALL(visitor, OnEndStream(1));
1052   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
1053 
1054   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
1055   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
1056 }
1057 
TEST(NgHttp2AdapterTest,ClientHandlesMetadataWithError)1058 TEST(NgHttp2AdapterTest, ClientHandlesMetadataWithError) {
1059   DataSavingVisitor visitor;
1060   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1061 
1062   testing::InSequence s;
1063 
1064   const std::vector<Header> headers1 =
1065       ToHeaders({{":method", "GET"},
1066                  {":scheme", "http"},
1067                  {":authority", "example.com"},
1068                  {":path", "/this/is/request/one"}});
1069 
1070   const char* kSentinel1 = "arbitrary pointer 1";
1071   const int32_t stream_id1 =
1072       adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
1073   ASSERT_GT(stream_id1, 0);
1074   QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
1075 
1076   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1077   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1078 
1079   int result = adapter->Send();
1080   EXPECT_EQ(0, result);
1081   visitor.Clear();
1082 
1083   const std::string stream_frames =
1084       TestFrameSequence()
1085           .ServerPreface()
1086           .Metadata(0, "Example connection metadata")
1087           .Headers(1,
1088                    {{":status", "200"},
1089                     {"server", "my-fake-server"},
1090                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
1091                    /*fin=*/false)
1092           .Metadata(1, "Example stream metadata")
1093           .Data(1, "This is the response body.", true)
1094           .Serialize();
1095 
1096   // Server preface (empty SETTINGS)
1097   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1098   EXPECT_CALL(visitor, OnSettingsStart());
1099   EXPECT_CALL(visitor, OnSettingsEnd());
1100 
1101   EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
1102   EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
1103   EXPECT_CALL(visitor, OnMetadataForStream(0, _));
1104   EXPECT_CALL(visitor, OnMetadataEndForStream(0));
1105   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
1106   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
1107   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
1108   EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
1109   EXPECT_CALL(visitor,
1110               OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
1111   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
1112   EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
1113   EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
1114   EXPECT_CALL(visitor, OnMetadataForStream(1, _))
1115       .WillOnce(testing::Return(false));
1116   // Remaining frames are not processed due to the error.
1117   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
1118 
1119   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
1120   // The false return from OnMetadataForStream() results in a connection error.
1121   EXPECT_EQ(stream_result, NGHTTP2_ERR_CALLBACK_FAILURE);
1122 
1123   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
1124   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
1125 
1126   EXPECT_TRUE(adapter->want_write());
1127   EXPECT_TRUE(adapter->want_read());  // Even after an error. Why?
1128   result = adapter->Send();
1129   EXPECT_EQ(0, result);
1130   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
1131 }
1132 
TEST(NgHttp2AdapterTest,ClientHandlesHpackHeaderTableSetting)1133 TEST(NgHttp2AdapterTest, ClientHandlesHpackHeaderTableSetting) {
1134   DataSavingVisitor visitor;
1135   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1136 
1137   testing::InSequence s;
1138 
1139   const std::vector<Header> headers1 = ToHeaders({
1140       {":method", "GET"},
1141       {":scheme", "http"},
1142       {":authority", "example.com"},
1143       {":path", "/this/is/request/one"},
1144       {"x-i-do-not-like", "green eggs and ham"},
1145       {"x-i-will-not-eat-them", "here or there, in a box, with a fox"},
1146       {"x-like-them-in-a-house", "no"},
1147       {"x-like-them-with-a-mouse", "no"},
1148   });
1149 
1150   const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
1151   ASSERT_GT(stream_id1, 0);
1152 
1153   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1154   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1155 
1156   int result = adapter->Send();
1157   EXPECT_EQ(0, result);
1158   visitor.Clear();
1159 
1160   EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 100);
1161 
1162   const std::string stream_frames =
1163       TestFrameSequence().Settings({{HEADER_TABLE_SIZE, 100u}}).Serialize();
1164   // Server preface (SETTINGS)
1165   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
1166   EXPECT_CALL(visitor, OnSettingsStart());
1167   EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 100u}));
1168 
1169   EXPECT_CALL(visitor, OnSettingsEnd());
1170 
1171   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
1172   EXPECT_EQ(stream_frames.size(), stream_result);
1173 
1174   EXPECT_LE(adapter->GetHpackEncoderDynamicTableSize(), 100);
1175 }
1176 
TEST(NgHttp2AdapterTest,ClientHandlesInvalidTrailers)1177 TEST(NgHttp2AdapterTest, ClientHandlesInvalidTrailers) {
1178   DataSavingVisitor visitor;
1179   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1180 
1181   testing::InSequence s;
1182 
1183   const std::vector<Header> headers1 =
1184       ToHeaders({{":method", "GET"},
1185                  {":scheme", "http"},
1186                  {":authority", "example.com"},
1187                  {":path", "/this/is/request/one"}});
1188 
1189   const char* kSentinel1 = "arbitrary pointer 1";
1190   const int32_t stream_id1 =
1191       adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
1192   ASSERT_GT(stream_id1, 0);
1193   QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
1194 
1195   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1196   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1197 
1198   int result = adapter->Send();
1199   EXPECT_EQ(0, result);
1200   absl::string_view data = visitor.data();
1201   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
1202   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
1203   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
1204   visitor.Clear();
1205 
1206   const std::string stream_frames =
1207       TestFrameSequence()
1208           .ServerPreface()
1209           .Headers(1,
1210                    {{":status", "200"},
1211                     {"server", "my-fake-server"},
1212                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
1213                    /*fin=*/false)
1214           .Data(1, "This is the response body.")
1215           .Headers(1, {{":bad-status", "9000"}},
1216                    /*fin=*/true)
1217           .Serialize();
1218 
1219   // Server preface (empty SETTINGS)
1220   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1221   EXPECT_CALL(visitor, OnSettingsStart());
1222   EXPECT_CALL(visitor, OnSettingsEnd());
1223 
1224   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
1225   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
1226   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
1227   EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
1228   EXPECT_CALL(visitor,
1229               OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
1230   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
1231   EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
1232   EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
1233   EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
1234   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
1235   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
1236   EXPECT_CALL(
1237       visitor,
1238       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
1239                    "stream: 1, name: [:bad-status], value: [9000]"));
1240   EXPECT_CALL(
1241       visitor,
1242       OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
1243 
1244   // Bad status trailer will cause a PROTOCOL_ERROR. The header is never
1245   // delivered in an OnHeaderForStream callback.
1246 
1247   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
1248   EXPECT_EQ(stream_frames.size(), stream_result);
1249 
1250   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
1251   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
1252   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id1, 4, 0x0));
1253   EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, stream_id1, 4, 0x0, 1));
1254   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
1255 
1256   EXPECT_TRUE(adapter->want_write());
1257   result = adapter->Send();
1258   EXPECT_EQ(0, result);
1259   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
1260                                             SpdyFrameType::RST_STREAM}));
1261 }
1262 
TEST(NgHttp2AdapterTest,ClientRstStreamWhileHandlingHeaders)1263 TEST(NgHttp2AdapterTest, ClientRstStreamWhileHandlingHeaders) {
1264   DataSavingVisitor visitor;
1265   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1266 
1267   testing::InSequence s;
1268 
1269   const std::vector<Header> headers1 =
1270       ToHeaders({{":method", "GET"},
1271                  {":scheme", "http"},
1272                  {":authority", "example.com"},
1273                  {":path", "/this/is/request/one"}});
1274 
1275   const char* kSentinel1 = "arbitrary pointer 1";
1276   const int32_t stream_id1 =
1277       adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
1278   ASSERT_GT(stream_id1, 0);
1279   QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
1280 
1281   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1282   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1283 
1284   int result = adapter->Send();
1285   EXPECT_EQ(0, result);
1286   absl::string_view data = visitor.data();
1287   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
1288   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
1289   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
1290   visitor.Clear();
1291 
1292   const std::string stream_frames =
1293       TestFrameSequence()
1294           .ServerPreface()
1295           .Headers(1,
1296                    {{":status", "200"},
1297                     {"server", "my-fake-server"},
1298                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
1299                    /*fin=*/false)
1300           .Data(1, "This is the response body.")
1301           .Serialize();
1302 
1303   // Server preface (empty SETTINGS)
1304   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1305   EXPECT_CALL(visitor, OnSettingsStart());
1306   EXPECT_CALL(visitor, OnSettingsEnd());
1307 
1308   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
1309   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
1310   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
1311   EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
1312   EXPECT_CALL(visitor,
1313               OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
1314       .WillOnce(testing::DoAll(
1315           testing::InvokeWithoutArgs([&adapter]() {
1316             adapter->SubmitRst(1, Http2ErrorCode::REFUSED_STREAM);
1317           }),
1318           testing::Return(Http2VisitorInterface::HEADER_RST_STREAM)));
1319 
1320   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
1321   EXPECT_EQ(stream_frames.size(), stream_result);
1322 
1323   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
1324   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
1325   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id1, 4, 0x0));
1326   EXPECT_CALL(visitor,
1327               OnFrameSent(RST_STREAM, stream_id1, 4, 0x0,
1328                           static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
1329   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::REFUSED_STREAM));
1330 
1331   EXPECT_TRUE(adapter->want_write());
1332   result = adapter->Send();
1333   EXPECT_EQ(0, result);
1334   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
1335                                             SpdyFrameType::RST_STREAM}));
1336 }
1337 
TEST(NgHttp2AdapterTest,ClientConnectionErrorWhileHandlingHeaders)1338 TEST(NgHttp2AdapterTest, ClientConnectionErrorWhileHandlingHeaders) {
1339   DataSavingVisitor visitor;
1340   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1341 
1342   testing::InSequence s;
1343 
1344   const std::vector<Header> headers1 =
1345       ToHeaders({{":method", "GET"},
1346                  {":scheme", "http"},
1347                  {":authority", "example.com"},
1348                  {":path", "/this/is/request/one"}});
1349 
1350   const char* kSentinel1 = "arbitrary pointer 1";
1351   const int32_t stream_id1 =
1352       adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
1353   ASSERT_GT(stream_id1, 0);
1354   QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
1355 
1356   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1357   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1358 
1359   int result = adapter->Send();
1360   EXPECT_EQ(0, result);
1361   absl::string_view data = visitor.data();
1362   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
1363   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
1364   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
1365   visitor.Clear();
1366 
1367   const std::string stream_frames =
1368       TestFrameSequence()
1369           .ServerPreface()
1370           .Headers(1,
1371                    {{":status", "200"},
1372                     {"server", "my-fake-server"},
1373                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
1374                    /*fin=*/false)
1375           .Data(1, "This is the response body.")
1376           .Serialize();
1377 
1378   // Server preface (empty SETTINGS)
1379   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1380   EXPECT_CALL(visitor, OnSettingsStart());
1381   EXPECT_CALL(visitor, OnSettingsEnd());
1382 
1383   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
1384   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
1385   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
1386   EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
1387   EXPECT_CALL(visitor,
1388               OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
1389       .WillOnce(
1390           testing::Return(Http2VisitorInterface::HEADER_CONNECTION_ERROR));
1391   // Translation to nghttp2 treats this error as a general parsing error.
1392   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
1393 
1394   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
1395   EXPECT_EQ(-902 /* NGHTTP2_ERR_CALLBACK_FAILURE */, stream_result);
1396 
1397   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
1398   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
1399 
1400   EXPECT_TRUE(adapter->want_write());
1401   result = adapter->Send();
1402   EXPECT_EQ(0, result);
1403   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
1404 }
1405 
TEST(NgHttp2AdapterTest,ClientConnectionErrorWhileHandlingHeadersOnly)1406 TEST(NgHttp2AdapterTest, ClientConnectionErrorWhileHandlingHeadersOnly) {
1407   DataSavingVisitor visitor;
1408   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1409 
1410   testing::InSequence s;
1411 
1412   const std::vector<Header> headers1 =
1413       ToHeaders({{":method", "GET"},
1414                  {":scheme", "http"},
1415                  {":authority", "example.com"},
1416                  {":path", "/this/is/request/one"}});
1417 
1418   const char* kSentinel1 = "arbitrary pointer 1";
1419   const int32_t stream_id1 =
1420       adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
1421   ASSERT_GT(stream_id1, 0);
1422   QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
1423 
1424   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1425   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1426 
1427   int result = adapter->Send();
1428   EXPECT_EQ(0, result);
1429   absl::string_view data = visitor.data();
1430   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
1431   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
1432   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
1433   visitor.Clear();
1434 
1435   const std::string stream_frames =
1436       TestFrameSequence()
1437           .ServerPreface()
1438           .Headers(1,
1439                    {{":status", "200"},
1440                     {"server", "my-fake-server"},
1441                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
1442                    /*fin=*/true)
1443           .Serialize();
1444 
1445   // Server preface (empty SETTINGS)
1446   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1447   EXPECT_CALL(visitor, OnSettingsStart());
1448   EXPECT_CALL(visitor, OnSettingsEnd());
1449 
1450   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
1451   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
1452   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
1453   EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
1454   EXPECT_CALL(visitor,
1455               OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
1456       .WillOnce(
1457           testing::Return(Http2VisitorInterface::HEADER_CONNECTION_ERROR));
1458   // Translation to nghttp2 treats this error as a general parsing error.
1459   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
1460 
1461   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
1462   EXPECT_EQ(-902 /* NGHTTP2_ERR_CALLBACK_FAILURE */, stream_result);
1463 
1464   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
1465   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
1466 
1467   EXPECT_TRUE(adapter->want_write());
1468   result = adapter->Send();
1469   EXPECT_EQ(0, result);
1470   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
1471 }
1472 
TEST(NgHttp2AdapterTest,ClientRejectsHeaders)1473 TEST(NgHttp2AdapterTest, ClientRejectsHeaders) {
1474   DataSavingVisitor visitor;
1475   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1476 
1477   testing::InSequence s;
1478 
1479   const std::vector<Header> headers1 =
1480       ToHeaders({{":method", "GET"},
1481                  {":scheme", "http"},
1482                  {":authority", "example.com"},
1483                  {":path", "/this/is/request/one"}});
1484 
1485   const char* kSentinel1 = "arbitrary pointer 1";
1486   const int32_t stream_id1 =
1487       adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
1488   ASSERT_GT(stream_id1, 0);
1489   QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
1490 
1491   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1492   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1493 
1494   int result = adapter->Send();
1495   EXPECT_EQ(0, result);
1496   absl::string_view data = visitor.data();
1497   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
1498   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
1499   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
1500   visitor.Clear();
1501 
1502   const std::string stream_frames =
1503       TestFrameSequence()
1504           .ServerPreface()
1505           .Headers(1,
1506                    {{":status", "200"},
1507                     {"server", "my-fake-server"},
1508                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
1509                    /*fin=*/false)
1510           .Data(1, "This is the response body.")
1511           .Serialize();
1512 
1513   // Server preface (empty SETTINGS)
1514   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1515   EXPECT_CALL(visitor, OnSettingsStart());
1516   EXPECT_CALL(visitor, OnSettingsEnd());
1517 
1518   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
1519   EXPECT_CALL(visitor, OnBeginHeadersForStream(1))
1520       .WillOnce(testing::Return(false));
1521   // Rejecting headers leads to a connection error.
1522   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
1523 
1524   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
1525   EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, stream_result);
1526 
1527   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
1528   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
1529 
1530   EXPECT_TRUE(adapter->want_write());
1531   result = adapter->Send();
1532   EXPECT_EQ(0, result);
1533   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
1534 }
1535 
TEST(NgHttp2AdapterTest,ClientStartsShutdown)1536 TEST(NgHttp2AdapterTest, ClientStartsShutdown) {
1537   DataSavingVisitor visitor;
1538   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1539 
1540   EXPECT_FALSE(adapter->want_write());
1541 
1542   // No-op for a client implementation.
1543   adapter->SubmitShutdownNotice();
1544   EXPECT_FALSE(adapter->want_write());
1545 
1546   int result = adapter->Send();
1547   EXPECT_EQ(0, result);
1548 
1549   EXPECT_EQ(visitor.data(), spdy::kHttp2ConnectionHeaderPrefix);
1550 }
1551 
TEST(NgHttp2AdapterTest,ClientReceivesGoAway)1552 TEST(NgHttp2AdapterTest, ClientReceivesGoAway) {
1553   DataSavingVisitor visitor;
1554   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1555 
1556   testing::InSequence s;
1557 
1558   const std::vector<Header> headers1 =
1559       ToHeaders({{":method", "GET"},
1560                  {":scheme", "http"},
1561                  {":authority", "example.com"},
1562                  {":path", "/this/is/request/one"}});
1563 
1564   const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
1565   ASSERT_GT(stream_id1, 0);
1566 
1567   const std::vector<Header> headers2 =
1568       ToHeaders({{":method", "GET"},
1569                  {":scheme", "http"},
1570                  {":authority", "example.com"},
1571                  {":path", "/this/is/request/two"}});
1572 
1573   const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
1574   ASSERT_GT(stream_id2, stream_id1);
1575 
1576   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1577   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1578   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
1579   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
1580 
1581   int result = adapter->Send();
1582   EXPECT_EQ(0, result);
1583   absl::string_view data = visitor.data();
1584   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
1585   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
1586   EXPECT_THAT(data,
1587               EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::HEADERS}));
1588   visitor.Clear();
1589 
1590   // Submit a pending WINDOW_UPDATE for a stream that will be closed due to
1591   // GOAWAY. The WINDOW_UPDATE should not be sent.
1592   adapter->SubmitWindowUpdate(3, 42);
1593 
1594   const std::string stream_frames =
1595       TestFrameSequence()
1596           .ServerPreface()
1597           .RstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM)
1598           .GoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
1599           .WindowUpdate(0, 42)
1600           .WindowUpdate(1, 42)
1601           .Serialize();
1602 
1603   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1604   EXPECT_CALL(visitor, OnSettingsStart());
1605   EXPECT_CALL(visitor, OnSettingsEnd());
1606   EXPECT_CALL(visitor, OnFrameHeader(1, 4, RST_STREAM, 0));
1607   EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM));
1608   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM));
1609   EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
1610   EXPECT_CALL(visitor,
1611               OnGoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion"));
1612   EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::REFUSED_STREAM));
1613   EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
1614   EXPECT_CALL(visitor, OnWindowUpdate(0, 42));
1615   EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
1616 
1617   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
1618   EXPECT_EQ(stream_frames.size(), stream_result);
1619 
1620   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
1621   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
1622 
1623   // SETTINGS ack (but only after the enqueue of the seemingly unrelated
1624   // WINDOW_UPDATE). The WINDOW_UPDATE is not written.
1625   EXPECT_TRUE(adapter->want_write());
1626   result = adapter->Send();
1627   EXPECT_EQ(0, result);
1628   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
1629 }
1630 
TEST(NgHttp2AdapterTest,ClientReceivesMultipleGoAways)1631 TEST(NgHttp2AdapterTest, ClientReceivesMultipleGoAways) {
1632   DataSavingVisitor visitor;
1633   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1634 
1635   testing::InSequence s;
1636 
1637   const std::vector<Header> headers1 =
1638       ToHeaders({{":method", "GET"},
1639                  {":scheme", "http"},
1640                  {":authority", "example.com"},
1641                  {":path", "/this/is/request/one"}});
1642 
1643   const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
1644   ASSERT_GT(stream_id1, 0);
1645 
1646   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1647   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1648 
1649   int result = adapter->Send();
1650   EXPECT_EQ(0, result);
1651   absl::string_view data = visitor.data();
1652   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
1653   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
1654   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
1655   visitor.Clear();
1656 
1657   const std::string initial_frames =
1658       TestFrameSequence()
1659           .ServerPreface()
1660           .GoAway(kMaxStreamId, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
1661           .Serialize();
1662 
1663   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1664   EXPECT_CALL(visitor, OnSettingsStart());
1665   EXPECT_CALL(visitor, OnSettingsEnd());
1666   EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
1667   EXPECT_CALL(visitor, OnGoAway(kMaxStreamId, Http2ErrorCode::INTERNAL_ERROR,
1668                                 "indigestion"));
1669 
1670   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
1671   EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
1672 
1673   // Submit a WINDOW_UPDATE for the open stream. Because the stream is below the
1674   // GOAWAY's last_stream_id, it should be sent.
1675   adapter->SubmitWindowUpdate(1, 42);
1676 
1677   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
1678   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
1679   EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 1, 4, 0x0));
1680   EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 1, 4, 0x0, 0));
1681 
1682   result = adapter->Send();
1683   EXPECT_EQ(0, result);
1684   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
1685                                             SpdyFrameType::WINDOW_UPDATE}));
1686   visitor.Clear();
1687 
1688   const std::string final_frames =
1689       TestFrameSequence()
1690           .GoAway(0, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
1691           .Serialize();
1692 
1693   EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
1694   EXPECT_CALL(visitor,
1695               OnGoAway(0, Http2ErrorCode::INTERNAL_ERROR, "indigestion"));
1696   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::REFUSED_STREAM));
1697 
1698   const int64_t final_result = adapter->ProcessBytes(final_frames);
1699   EXPECT_EQ(final_frames.size(), static_cast<size_t>(final_result));
1700 
1701   EXPECT_FALSE(adapter->want_write());
1702   result = adapter->Send();
1703   EXPECT_EQ(0, result);
1704   EXPECT_THAT(visitor.data(), testing::IsEmpty());
1705 }
1706 
TEST(NgHttp2AdapterTest,ClientReceivesMultipleGoAwaysWithIncreasingStreamId)1707 TEST(NgHttp2AdapterTest, ClientReceivesMultipleGoAwaysWithIncreasingStreamId) {
1708   DataSavingVisitor visitor;
1709   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1710 
1711   testing::InSequence s;
1712 
1713   const std::vector<Header> headers1 =
1714       ToHeaders({{":method", "GET"},
1715                  {":scheme", "http"},
1716                  {":authority", "example.com"},
1717                  {":path", "/this/is/request/one"}});
1718 
1719   const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
1720   ASSERT_GT(stream_id1, 0);
1721 
1722   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1723   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1724 
1725   int result = adapter->Send();
1726   EXPECT_EQ(0, result);
1727   absl::string_view data = visitor.data();
1728   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
1729   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
1730   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
1731   visitor.Clear();
1732 
1733   auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
1734       {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
1735   adapter->SubmitMetadata(stream_id1, 16384u, std::move(source));
1736 
1737   const std::string frames =
1738       TestFrameSequence()
1739           .ServerPreface()
1740           .GoAway(0, Http2ErrorCode::HTTP2_NO_ERROR, "")
1741           .GoAway(0, Http2ErrorCode::ENHANCE_YOUR_CALM, "")
1742           .GoAway(1, Http2ErrorCode::INTERNAL_ERROR, "")
1743           .Serialize();
1744 
1745   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1746   EXPECT_CALL(visitor, OnSettingsStart());
1747   EXPECT_CALL(visitor, OnSettingsEnd());
1748   EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
1749   EXPECT_CALL(visitor, OnGoAway(0, Http2ErrorCode::HTTP2_NO_ERROR, ""));
1750   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::REFUSED_STREAM));
1751   EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
1752   EXPECT_CALL(visitor, OnGoAway(0, Http2ErrorCode::ENHANCE_YOUR_CALM, ""));
1753   EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
1754   EXPECT_CALL(
1755       visitor,
1756       OnInvalidFrame(0, Http2VisitorInterface::InvalidFrameError::kProtocol));
1757 
1758   const int64_t frames_result = adapter->ProcessBytes(frames);
1759   EXPECT_EQ(frames.size(), static_cast<size_t>(frames_result));
1760 
1761   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
1762   EXPECT_CALL(visitor,
1763               OnFrameSent(GOAWAY, 0, _, 0x0,
1764                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
1765 
1766   EXPECT_TRUE(adapter->want_write());
1767   result = adapter->Send();
1768   EXPECT_EQ(0, result);
1769   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
1770 }
1771 
TEST(NgHttp2AdapterTest,ClientReceivesGoAwayWithPendingStreams)1772 TEST(NgHttp2AdapterTest, ClientReceivesGoAwayWithPendingStreams) {
1773   DataSavingVisitor visitor;
1774   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1775 
1776   int result = adapter->Send();
1777   EXPECT_EQ(0, result);
1778   // Client preface does not appear to include the mandatory SETTINGS frame.
1779   EXPECT_THAT(visitor.data(),
1780               testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
1781   visitor.Clear();
1782 
1783   testing::InSequence s;
1784 
1785   const std::string initial_frames =
1786       TestFrameSequence()
1787           .ServerPreface({{MAX_CONCURRENT_STREAMS, 1}})
1788           .Serialize();
1789 
1790   // Server preface (SETTINGS with MAX_CONCURRENT_STREAMS)
1791   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
1792   EXPECT_CALL(visitor, OnSettingsStart());
1793   EXPECT_CALL(visitor, OnSetting);
1794   EXPECT_CALL(visitor, OnSettingsEnd());
1795 
1796   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
1797   EXPECT_EQ(initial_frames.size(), initial_result);
1798 
1799   const std::vector<Header> headers1 =
1800       ToHeaders({{":method", "GET"},
1801                  {":scheme", "http"},
1802                  {":authority", "example.com"},
1803                  {":path", "/this/is/request/one"}});
1804 
1805   const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
1806   ASSERT_GT(stream_id1, 0);
1807 
1808   const std::vector<Header> headers2 =
1809       ToHeaders({{":method", "GET"},
1810                  {":scheme", "http"},
1811                  {":authority", "example.com"},
1812                  {":path", "/this/is/request/two"}});
1813 
1814   const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
1815   ASSERT_GT(stream_id2, stream_id1);
1816 
1817   // The second request should be pending because of
1818   // SETTINGS_MAX_CONCURRENT_STREAMS.
1819   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
1820   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
1821   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1822   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1823 
1824   result = adapter->Send();
1825   EXPECT_EQ(0, result);
1826   EXPECT_THAT(visitor.data(),
1827               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
1828   visitor.Clear();
1829 
1830   // Let the client receive a GOAWAY and raise MAX_CONCURRENT_STREAMS. Even
1831   // though the GOAWAY last_stream_id is higher than the pending request's
1832   // stream ID, pending request should not be sent.
1833   const std::string stream_frames =
1834       TestFrameSequence()
1835           .GoAway(kMaxStreamId, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
1836           .Settings({{MAX_CONCURRENT_STREAMS, 42u}})
1837           .Serialize();
1838 
1839   EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
1840   EXPECT_CALL(visitor, OnGoAway(kMaxStreamId, Http2ErrorCode::INTERNAL_ERROR,
1841                                 "indigestion"));
1842   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
1843   EXPECT_CALL(visitor, OnSettingsStart());
1844   EXPECT_CALL(visitor, OnSetting(Http2Setting{MAX_CONCURRENT_STREAMS, 42u}));
1845   EXPECT_CALL(visitor, OnSettingsEnd());
1846 
1847   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
1848   EXPECT_EQ(stream_frames.size(), stream_result);
1849 
1850   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
1851   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
1852 
1853   // Nghttp2 closes the pending stream on the next write attempt.
1854   EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::REFUSED_STREAM));
1855 
1856   EXPECT_TRUE(adapter->want_write());
1857   result = adapter->Send();
1858   EXPECT_EQ(0, result);
1859   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
1860   visitor.Clear();
1861 
1862   // Requests submitted after receiving the GOAWAY should not be sent.
1863   const std::vector<Header> headers3 =
1864       ToHeaders({{":method", "GET"},
1865                  {":scheme", "http"},
1866                  {":authority", "example.com"},
1867                  {":path", "/this/is/request/three"}});
1868 
1869   const int32_t stream_id3 = adapter->SubmitRequest(headers3, nullptr, nullptr);
1870   ASSERT_GT(stream_id3, stream_id2);
1871 
1872   // Nghttp2 closes the pending stream on the next write attempt.
1873   EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::REFUSED_STREAM));
1874 
1875   EXPECT_TRUE(adapter->want_write());
1876   result = adapter->Send();
1877   EXPECT_EQ(0, result);
1878   EXPECT_THAT(visitor.data(), testing::IsEmpty());
1879   EXPECT_FALSE(adapter->want_write());
1880 }
1881 
TEST(NgHttp2AdapterTest,ClientFailsOnGoAway)1882 TEST(NgHttp2AdapterTest, ClientFailsOnGoAway) {
1883   DataSavingVisitor visitor;
1884   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1885 
1886   testing::InSequence s;
1887 
1888   const std::vector<Header> headers1 =
1889       ToHeaders({{":method", "GET"},
1890                  {":scheme", "http"},
1891                  {":authority", "example.com"},
1892                  {":path", "/this/is/request/one"}});
1893 
1894   const char* kSentinel1 = "arbitrary pointer 1";
1895   const int32_t stream_id1 =
1896       adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
1897   ASSERT_GT(stream_id1, 0);
1898   QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
1899 
1900   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1901   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1902 
1903   int result = adapter->Send();
1904   EXPECT_EQ(0, result);
1905   absl::string_view data = visitor.data();
1906   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
1907   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
1908   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
1909   visitor.Clear();
1910 
1911   const std::string stream_frames =
1912       TestFrameSequence()
1913           .ServerPreface()
1914           .Headers(1,
1915                    {{":status", "200"},
1916                     {"server", "my-fake-server"},
1917                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
1918                    /*fin=*/false)
1919           .GoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
1920           .Data(1, "This is the response body.")
1921           .Serialize();
1922 
1923   // Server preface (empty SETTINGS)
1924   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1925   EXPECT_CALL(visitor, OnSettingsStart());
1926   EXPECT_CALL(visitor, OnSettingsEnd());
1927 
1928   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
1929   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
1930   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
1931   EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
1932   EXPECT_CALL(visitor,
1933               OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
1934   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
1935   EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
1936   EXPECT_CALL(visitor,
1937               OnGoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion"))
1938       .WillOnce(testing::Return(false));
1939   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
1940 
1941   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
1942   EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, stream_result);
1943 
1944   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
1945   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
1946 
1947   EXPECT_TRUE(adapter->want_write());
1948   result = adapter->Send();
1949   EXPECT_EQ(0, result);
1950   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
1951 }
1952 
TEST(NgHttp2AdapterTest,ClientRejects101Response)1953 TEST(NgHttp2AdapterTest, ClientRejects101Response) {
1954   DataSavingVisitor visitor;
1955   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
1956 
1957   testing::InSequence s;
1958 
1959   const std::vector<Header> headers1 =
1960       ToHeaders({{":method", "GET"},
1961                  {":scheme", "http"},
1962                  {":authority", "example.com"},
1963                  {":path", "/this/is/request/one"},
1964                  {"upgrade", "new-protocol"}});
1965 
1966   const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
1967   ASSERT_GT(stream_id1, 0);
1968 
1969   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
1970   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
1971 
1972   int result = adapter->Send();
1973   EXPECT_EQ(0, result);
1974   absl::string_view data = visitor.data();
1975   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
1976   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
1977   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
1978   visitor.Clear();
1979 
1980   const std::string stream_frames =
1981       TestFrameSequence()
1982           .ServerPreface()
1983           .Headers(1,
1984                    {{":status", "101"},
1985                     {"server", "my-fake-server"},
1986                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
1987                    /*fin=*/false)
1988           .Serialize();
1989 
1990   // Server preface (empty SETTINGS)
1991   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
1992   EXPECT_CALL(visitor, OnSettingsStart());
1993   EXPECT_CALL(visitor, OnSettingsEnd());
1994 
1995   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
1996   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
1997   EXPECT_CALL(
1998       visitor,
1999       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
2000                    "stream: 1, name: [:status], value: [101]"));
2001   EXPECT_CALL(
2002       visitor,
2003       OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
2004 
2005   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
2006   EXPECT_EQ(static_cast<int64_t>(stream_frames.size()), stream_result);
2007 
2008   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
2009   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
2010   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
2011   EXPECT_CALL(
2012       visitor,
2013       OnFrameSent(RST_STREAM, 1, 4, 0x0,
2014                   static_cast<uint32_t>(Http2ErrorCode::PROTOCOL_ERROR)));
2015   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
2016 
2017   EXPECT_TRUE(adapter->want_write());
2018   result = adapter->Send();
2019   EXPECT_EQ(0, result);
2020   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
2021                                             SpdyFrameType::RST_STREAM}));
2022 }
2023 
TEST(NgHttp2AdapterTest,ClientSubmitRequest)2024 TEST(NgHttp2AdapterTest, ClientSubmitRequest) {
2025   DataSavingVisitor visitor;
2026   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2027   int result = adapter->Send();
2028   EXPECT_EQ(0, result);
2029   // Client preface does not appear to include the mandatory SETTINGS frame.
2030   EXPECT_THAT(visitor.data(),
2031               testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
2032   visitor.Clear();
2033 
2034   const std::string initial_frames =
2035       TestFrameSequence().ServerPreface().Serialize();
2036   testing::InSequence s;
2037 
2038   // Server preface (empty SETTINGS)
2039   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
2040   EXPECT_CALL(visitor, OnSettingsStart());
2041   EXPECT_CALL(visitor, OnSettingsEnd());
2042 
2043   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
2044   EXPECT_EQ(initial_frames.size(), initial_result);
2045 
2046   EXPECT_TRUE(adapter->want_write());
2047 
2048   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
2049   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
2050 
2051   result = adapter->Send();
2052   EXPECT_EQ(0, result);
2053   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
2054   visitor.Clear();
2055 
2056   EXPECT_EQ(0, adapter->GetHpackEncoderDynamicTableSize());
2057   EXPECT_FALSE(adapter->want_write());
2058   const char* kSentinel = "";
2059   const absl::string_view kBody = "This is an example request body.";
2060   auto body1 = std::make_unique<TestDataFrameSource>(visitor, true);
2061   body1->AppendPayload(kBody);
2062   body1->EndData();
2063   int stream_id =
2064       adapter->SubmitRequest(ToHeaders({{":method", "POST"},
2065                                         {":scheme", "http"},
2066                                         {":authority", "example.com"},
2067                                         {":path", "/this/is/request/one"}}),
2068                              std::move(body1), const_cast<char*>(kSentinel));
2069   EXPECT_GT(stream_id, 0);
2070   EXPECT_TRUE(adapter->want_write());
2071 
2072   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
2073   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
2074   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
2075 
2076   result = adapter->Send();
2077   EXPECT_EQ(0, result);
2078 
2079   EXPECT_EQ(kInitialFlowControlWindowSize,
2080             adapter->GetStreamReceiveWindowSize(stream_id));
2081   EXPECT_EQ(kInitialFlowControlWindowSize, adapter->GetReceiveWindowSize());
2082   EXPECT_EQ(kInitialFlowControlWindowSize,
2083             adapter->GetStreamReceiveWindowLimit(stream_id));
2084 
2085   EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 0);
2086 
2087   // Some data was sent, so the remaining send window size should be less than
2088   // the default.
2089   EXPECT_LT(adapter->GetStreamSendWindowSize(stream_id),
2090             kInitialFlowControlWindowSize);
2091   EXPECT_GT(adapter->GetStreamSendWindowSize(stream_id), 0);
2092   // Send window for a nonexistent stream is not available.
2093   EXPECT_EQ(-1, adapter->GetStreamSendWindowSize(stream_id + 2));
2094 
2095   EXPECT_THAT(visitor.data(),
2096               EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
2097   EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
2098   visitor.Clear();
2099   EXPECT_FALSE(adapter->want_write());
2100 
2101   stream_id =
2102       adapter->SubmitRequest(ToHeaders({{":method", "POST"},
2103                                         {":scheme", "http"},
2104                                         {":authority", "example.com"},
2105                                         {":path", "/this/is/request/one"}}),
2106                              nullptr, nullptr);
2107   EXPECT_GT(stream_id, 0);
2108   EXPECT_TRUE(adapter->want_write());
2109   const char* kSentinel2 = "arbitrary pointer 2";
2110   EXPECT_EQ(nullptr, adapter->GetStreamUserData(stream_id));
2111   adapter->SetStreamUserData(stream_id, const_cast<char*>(kSentinel2));
2112 
2113   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
2114   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
2115 
2116   result = adapter->Send();
2117   EXPECT_EQ(0, result);
2118   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
2119 
2120   EXPECT_EQ(kSentinel2, adapter->GetStreamUserData(stream_id));
2121 
2122   // No data was sent (just HEADERS), so the remaining send window size should
2123   // still be the default.
2124   EXPECT_EQ(adapter->GetStreamSendWindowSize(stream_id),
2125             kInitialFlowControlWindowSize);
2126 }
2127 
2128 // This is really a test of the MakeZeroCopyDataFrameSource adapter, but I
2129 // wasn't sure where else to put it.
TEST(NgHttp2AdapterTest,ClientSubmitRequestWithDataProvider)2130 TEST(NgHttp2AdapterTest, ClientSubmitRequestWithDataProvider) {
2131   DataSavingVisitor visitor;
2132   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2133   int result = adapter->Send();
2134   EXPECT_EQ(0, result);
2135   // Client preface does not appear to include the mandatory SETTINGS frame.
2136   EXPECT_THAT(visitor.data(),
2137               testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
2138   visitor.Clear();
2139 
2140   const std::string initial_frames =
2141       TestFrameSequence().ServerPreface().Serialize();
2142   testing::InSequence s;
2143 
2144   // Server preface (empty SETTINGS)
2145   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
2146   EXPECT_CALL(visitor, OnSettingsStart());
2147   EXPECT_CALL(visitor, OnSettingsEnd());
2148 
2149   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
2150   EXPECT_EQ(initial_frames.size(), initial_result);
2151 
2152   EXPECT_TRUE(adapter->want_write());
2153 
2154   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
2155   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
2156 
2157   result = adapter->Send();
2158   EXPECT_EQ(0, result);
2159   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
2160   visitor.Clear();
2161 
2162   EXPECT_FALSE(adapter->want_write());
2163   const absl::string_view kBody = "This is an example request body.";
2164   // This test will use TestDataSource as the source of the body payload data.
2165   TestDataSource body1{kBody};
2166   // The TestDataSource is wrapped in the nghttp2_data_provider data type.
2167   nghttp2_data_provider provider = body1.MakeDataProvider();
2168   nghttp2_send_data_callback send_callback = &TestSendCallback;
2169 
2170   // This call transforms it back into a DataFrameSource, which is compatible
2171   // with the Http2Adapter API.
2172   std::unique_ptr<DataFrameSource> frame_source =
2173       MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
2174   int stream_id =
2175       adapter->SubmitRequest(ToHeaders({{":method", "POST"},
2176                                         {":scheme", "http"},
2177                                         {":authority", "example.com"},
2178                                         {":path", "/this/is/request/one"}}),
2179                              std::move(frame_source), nullptr);
2180   EXPECT_GT(stream_id, 0);
2181   EXPECT_TRUE(adapter->want_write());
2182 
2183   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
2184   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
2185   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
2186 
2187   result = adapter->Send();
2188   EXPECT_EQ(0, result);
2189   EXPECT_THAT(visitor.data(),
2190               EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
2191   EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
2192   EXPECT_FALSE(adapter->want_write());
2193 }
2194 
2195 // This test verifies how nghttp2 behaves when a data source becomes
2196 // read-blocked.
TEST(NgHttp2AdapterTest,ClientSubmitRequestWithDataProviderAndReadBlock)2197 TEST(NgHttp2AdapterTest, ClientSubmitRequestWithDataProviderAndReadBlock) {
2198   DataSavingVisitor visitor;
2199   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2200 
2201   const absl::string_view kBody = "This is an example request body.";
2202   // This test will use TestDataSource as the source of the body payload data.
2203   TestDataSource body1{kBody};
2204   body1.set_is_data_available(false);
2205   // The TestDataSource is wrapped in the nghttp2_data_provider data type.
2206   nghttp2_data_provider provider = body1.MakeDataProvider();
2207   nghttp2_send_data_callback send_callback = &TestSendCallback;
2208 
2209   // This call transforms it back into a DataFrameSource, which is compatible
2210   // with the Http2Adapter API.
2211   std::unique_ptr<DataFrameSource> frame_source =
2212       MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
2213   int stream_id =
2214       adapter->SubmitRequest(ToHeaders({{":method", "POST"},
2215                                         {":scheme", "http"},
2216                                         {":authority", "example.com"},
2217                                         {":path", "/this/is/request/one"}}),
2218                              std::move(frame_source), nullptr);
2219   EXPECT_GT(stream_id, 0);
2220   EXPECT_TRUE(adapter->want_write());
2221 
2222   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
2223   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
2224 
2225   int result = adapter->Send();
2226   EXPECT_EQ(0, result);
2227   // Client preface does not appear to include the mandatory SETTINGS frame.
2228   absl::string_view serialized = visitor.data();
2229   EXPECT_THAT(serialized,
2230               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
2231   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
2232   EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::HEADERS}));
2233   visitor.Clear();
2234   EXPECT_FALSE(adapter->want_write());
2235 
2236   // Resume the deferred stream.
2237   body1.set_is_data_available(true);
2238   EXPECT_TRUE(adapter->ResumeStream(stream_id));
2239   EXPECT_TRUE(adapter->want_write());
2240 
2241   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
2242 
2243   result = adapter->Send();
2244   EXPECT_EQ(0, result);
2245   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
2246   EXPECT_FALSE(adapter->want_write());
2247 
2248   // Stream data is done, so this stream cannot be resumed.
2249   EXPECT_FALSE(adapter->ResumeStream(stream_id));
2250   EXPECT_FALSE(adapter->want_write());
2251 }
2252 
2253 // This test verifies how nghttp2 behaves when a data source is read block, then
2254 // ends with an empty DATA frame.
TEST(NgHttp2AdapterTest,ClientSubmitRequestEmptyDataWithFin)2255 TEST(NgHttp2AdapterTest, ClientSubmitRequestEmptyDataWithFin) {
2256   DataSavingVisitor visitor;
2257   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2258 
2259   const absl::string_view kEmptyBody = "";
2260   // This test will use TestDataSource as the source of the body payload data.
2261   TestDataSource body1{kEmptyBody};
2262   body1.set_is_data_available(false);
2263   // The TestDataSource is wrapped in the nghttp2_data_provider data type.
2264   nghttp2_data_provider provider = body1.MakeDataProvider();
2265   nghttp2_send_data_callback send_callback = &TestSendCallback;
2266 
2267   // This call transforms it back into a DataFrameSource, which is compatible
2268   // with the Http2Adapter API.
2269   std::unique_ptr<DataFrameSource> frame_source =
2270       MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
2271   int stream_id =
2272       adapter->SubmitRequest(ToHeaders({{":method", "POST"},
2273                                         {":scheme", "http"},
2274                                         {":authority", "example.com"},
2275                                         {":path", "/this/is/request/one"}}),
2276                              std::move(frame_source), nullptr);
2277   EXPECT_GT(stream_id, 0);
2278   EXPECT_TRUE(adapter->want_write());
2279 
2280   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
2281   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
2282 
2283   int result = adapter->Send();
2284   EXPECT_EQ(0, result);
2285   // Client preface does not appear to include the mandatory SETTINGS frame.
2286   absl::string_view serialized = visitor.data();
2287   EXPECT_THAT(serialized,
2288               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
2289   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
2290   EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::HEADERS}));
2291   visitor.Clear();
2292   EXPECT_FALSE(adapter->want_write());
2293 
2294   // Resume the deferred stream.
2295   body1.set_is_data_available(true);
2296   EXPECT_TRUE(adapter->ResumeStream(stream_id));
2297   EXPECT_TRUE(adapter->want_write());
2298 
2299   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 0, 0x1, 0));
2300 
2301   result = adapter->Send();
2302   EXPECT_EQ(0, result);
2303   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
2304   EXPECT_FALSE(adapter->want_write());
2305 
2306   // Stream data is done, so this stream cannot be resumed.
2307   EXPECT_FALSE(adapter->ResumeStream(stream_id));
2308   EXPECT_FALSE(adapter->want_write());
2309 }
2310 
2311 // This test verifies how nghttp2 behaves when a connection becomes
2312 // write-blocked.
TEST(NgHttp2AdapterTest,ClientSubmitRequestWithDataProviderAndWriteBlock)2313 TEST(NgHttp2AdapterTest, ClientSubmitRequestWithDataProviderAndWriteBlock) {
2314   DataSavingVisitor visitor;
2315   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2316 
2317   const absl::string_view kBody = "This is an example request body.";
2318   // This test will use TestDataSource as the source of the body payload data.
2319   TestDataSource body1{kBody};
2320   // The TestDataSource is wrapped in the nghttp2_data_provider data type.
2321   nghttp2_data_provider provider = body1.MakeDataProvider();
2322   nghttp2_send_data_callback send_callback = &TestSendCallback;
2323 
2324   // This call transforms it back into a DataFrameSource, which is compatible
2325   // with the Http2Adapter API.
2326   std::unique_ptr<DataFrameSource> frame_source =
2327       MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
2328   int stream_id =
2329       adapter->SubmitRequest(ToHeaders({{":method", "POST"},
2330                                         {":scheme", "http"},
2331                                         {":authority", "example.com"},
2332                                         {":path", "/this/is/request/one"}}),
2333                              std::move(frame_source), nullptr);
2334   EXPECT_GT(stream_id, 0);
2335   EXPECT_TRUE(adapter->want_write());
2336 
2337   visitor.set_is_write_blocked(true);
2338   int result = adapter->Send();
2339   EXPECT_EQ(0, result);
2340   EXPECT_THAT(visitor.data(), testing::IsEmpty());
2341   EXPECT_TRUE(adapter->want_write());
2342 
2343   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
2344   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
2345   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
2346 
2347   visitor.set_is_write_blocked(false);
2348   result = adapter->Send();
2349   EXPECT_EQ(0, result);
2350 
2351   // Client preface does not appear to include the mandatory SETTINGS frame.
2352   absl::string_view serialized = visitor.data();
2353   EXPECT_THAT(serialized,
2354               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
2355   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
2356   EXPECT_THAT(serialized,
2357               EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
2358   EXPECT_FALSE(adapter->want_write());
2359 }
2360 
TEST(NgHttp2AdapterTest,ClientReceivesDataOnClosedStream)2361 TEST(NgHttp2AdapterTest, ClientReceivesDataOnClosedStream) {
2362   DataSavingVisitor visitor;
2363   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2364   int result = adapter->Send();
2365   EXPECT_EQ(0, result);
2366   // Client preface does not appear to include the mandatory SETTINGS frame.
2367   EXPECT_THAT(visitor.data(),
2368               testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
2369   visitor.Clear();
2370 
2371   const std::string initial_frames =
2372       TestFrameSequence().ServerPreface().Serialize();
2373   testing::InSequence s;
2374 
2375   // Server preface (empty SETTINGS)
2376   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
2377   EXPECT_CALL(visitor, OnSettingsStart());
2378   EXPECT_CALL(visitor, OnSettingsEnd());
2379 
2380   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
2381   EXPECT_EQ(initial_frames.size(), initial_result);
2382 
2383   // Client SETTINGS ack
2384   EXPECT_TRUE(adapter->want_write());
2385   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
2386   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
2387 
2388   result = adapter->Send();
2389   EXPECT_EQ(0, result);
2390   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
2391   visitor.Clear();
2392 
2393   // Let the client open a stream with a request.
2394   int stream_id =
2395       adapter->SubmitRequest(ToHeaders({{":method", "GET"},
2396                                         {":scheme", "http"},
2397                                         {":authority", "example.com"},
2398                                         {":path", "/this/is/request/one"}}),
2399                              nullptr, nullptr);
2400   EXPECT_GT(stream_id, 0);
2401 
2402   EXPECT_TRUE(adapter->want_write());
2403   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
2404   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
2405 
2406   result = adapter->Send();
2407   EXPECT_EQ(0, result);
2408   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
2409   visitor.Clear();
2410 
2411   // Let the client RST_STREAM the stream it opened.
2412   adapter->SubmitRst(stream_id, Http2ErrorCode::CANCEL);
2413   EXPECT_TRUE(adapter->want_write());
2414   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id, _, 0x0));
2415   EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, stream_id, _, 0x0,
2416                                    static_cast<int>(Http2ErrorCode::CANCEL)));
2417   EXPECT_CALL(visitor, OnCloseStream(stream_id, Http2ErrorCode::CANCEL));
2418 
2419   result = adapter->Send();
2420   EXPECT_EQ(0, result);
2421   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
2422   visitor.Clear();
2423 
2424   // Let the server send a response on the stream. (It might not have received
2425   // the RST_STREAM yet.)
2426   const std::string response_frames =
2427       TestFrameSequence()
2428           .Headers(stream_id,
2429                    {{":status", "200"},
2430                     {"server", "my-fake-server"},
2431                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
2432                    /*fin=*/false)
2433           .Data(stream_id, "This is the response body.", /*fin=*/true)
2434           .Serialize();
2435 
2436   // The visitor gets notified about the HEADERS frame but not the DATA frame on
2437   // the closed stream. No further processing for either frame occurs.
2438   EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 0x4));
2439   EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, DATA, _)).Times(0);
2440 
2441   const int64_t response_result = adapter->ProcessBytes(response_frames);
2442   EXPECT_EQ(response_frames.size(), response_result);
2443 
2444   EXPECT_FALSE(adapter->want_write());
2445 }
2446 
TEST(NgHttp2AdapterTest,ClientQueuesRequests)2447 TEST(NgHttp2AdapterTest, ClientQueuesRequests) {
2448   DataSavingVisitor visitor;
2449   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2450 
2451   testing::InSequence s;
2452 
2453   adapter->SubmitSettings({});
2454 
2455   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
2456   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
2457   adapter->Send();
2458 
2459   const std::string initial_frames =
2460       TestFrameSequence()
2461           .ServerPreface({{MAX_CONCURRENT_STREAMS, 2}})
2462           .SettingsAck()
2463           .Serialize();
2464 
2465   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
2466   EXPECT_CALL(visitor, OnSettingsStart());
2467   EXPECT_CALL(visitor, OnSetting(Http2Setting{
2468                            Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 2u}));
2469   EXPECT_CALL(visitor, OnSettingsEnd());
2470   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
2471   EXPECT_CALL(visitor, OnSettingsAck());
2472 
2473   adapter->ProcessBytes(initial_frames);
2474 
2475   const std::vector<Header> headers =
2476       ToHeaders({{":method", "GET"},
2477                  {":scheme", "http"},
2478                  {":authority", "example.com"},
2479                  {":path", "/example/request"}});
2480   std::vector<int32_t> stream_ids;
2481   // Start two, which hits the limit.
2482   int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
2483   stream_ids.push_back(stream_id);
2484   stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
2485   stream_ids.push_back(stream_id);
2486   // Start two more, which must be queued.
2487   stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
2488   stream_ids.push_back(stream_id);
2489   stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
2490   stream_ids.push_back(stream_id);
2491 
2492   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
2493   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
2494   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[0], _, 0x5));
2495   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[0], _, 0x5, 0));
2496   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[1], _, 0x5));
2497   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[1], _, 0x5, 0));
2498 
2499   adapter->Send();
2500 
2501   const std::string update_streams =
2502       TestFrameSequence().Settings({{MAX_CONCURRENT_STREAMS, 5}}).Serialize();
2503 
2504   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
2505   EXPECT_CALL(visitor, OnSettingsStart());
2506   EXPECT_CALL(visitor, OnSetting(Http2Setting{
2507                            Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 5u}));
2508   EXPECT_CALL(visitor, OnSettingsEnd());
2509 
2510   adapter->ProcessBytes(update_streams);
2511 
2512   stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
2513   stream_ids.push_back(stream_id);
2514 
2515   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
2516   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
2517   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[2], _, 0x5));
2518   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[2], _, 0x5, 0));
2519   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[3], _, 0x5));
2520   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[3], _, 0x5, 0));
2521   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[4], _, 0x5));
2522   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[4], _, 0x5, 0));
2523   // Header frames should all have been sent in order, regardless of any
2524   // queuing.
2525 
2526   adapter->Send();
2527 }
2528 
TEST(NgHttp2AdapterTest,ClientAcceptsHeadResponseWithContentLength)2529 TEST(NgHttp2AdapterTest, ClientAcceptsHeadResponseWithContentLength) {
2530   DataSavingVisitor visitor;
2531   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2532 
2533   const std::vector<Header> headers = ToHeaders({{":method", "HEAD"},
2534                                                  {":scheme", "http"},
2535                                                  {":authority", "example.com"},
2536                                                  {":path", "/"}});
2537   const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
2538 
2539   testing::InSequence s;
2540 
2541   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
2542   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
2543 
2544   adapter->Send();
2545 
2546   const std::string initial_frames =
2547       TestFrameSequence()
2548           .ServerPreface()
2549           .Headers(stream_id, {{":status", "200"}, {"content-length", "101"}},
2550                    /*fin=*/true)
2551           .Serialize();
2552 
2553   EXPECT_CALL(visitor, OnFrameHeader(0, _, SETTINGS, 0x0));
2554   EXPECT_CALL(visitor, OnSettingsStart());
2555   EXPECT_CALL(visitor, OnSettingsEnd());
2556   EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 5));
2557   EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
2558   EXPECT_CALL(visitor, OnHeaderForStream).Times(2);
2559   EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
2560   EXPECT_CALL(visitor, OnEndStream(stream_id));
2561   EXPECT_CALL(visitor,
2562               OnCloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR));
2563 
2564   adapter->ProcessBytes(initial_frames);
2565 
2566   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
2567   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
2568 
2569   adapter->Send();
2570 }
2571 
TEST(NgHttp2AdapterTest,SubmitMetadata)2572 TEST(NgHttp2AdapterTest, SubmitMetadata) {
2573   DataSavingVisitor visitor;
2574   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2575 
2576   auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
2577       {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
2578   adapter->SubmitMetadata(1, 16384u, std::move(source));
2579   EXPECT_TRUE(adapter->want_write());
2580 
2581   EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
2582   EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
2583 
2584   int result = adapter->Send();
2585   EXPECT_EQ(0, result);
2586   absl::string_view serialized = visitor.data();
2587   EXPECT_THAT(serialized,
2588               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
2589   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
2590   EXPECT_THAT(serialized,
2591               EqualsFrames({static_cast<SpdyFrameType>(kMetadataFrameType)}));
2592   EXPECT_FALSE(adapter->want_write());
2593 }
2594 
TEST(NgHttp2AdapterTest,SubmitMetadataMultipleFrames)2595 TEST(NgHttp2AdapterTest, SubmitMetadataMultipleFrames) {
2596   DataSavingVisitor visitor;
2597   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2598 
2599   const auto kLargeValue = std::string(63 * 1024, 'a');
2600   auto source = std::make_unique<TestMetadataSource>(
2601       ToHeaderBlock(ToHeaders({{"large-value", kLargeValue}})));
2602   adapter->SubmitMetadata(1, 16384u, std::move(source));
2603   EXPECT_TRUE(adapter->want_write());
2604 
2605   testing::InSequence seq;
2606   EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
2607   EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
2608   EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
2609   EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
2610   EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
2611   EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
2612   EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
2613   EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
2614 
2615   int result = adapter->Send();
2616   EXPECT_EQ(0, result);
2617   absl::string_view serialized = visitor.data();
2618   EXPECT_THAT(serialized,
2619               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
2620   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
2621   EXPECT_THAT(serialized,
2622               EqualsFrames({static_cast<SpdyFrameType>(kMetadataFrameType),
2623                             static_cast<SpdyFrameType>(kMetadataFrameType),
2624                             static_cast<SpdyFrameType>(kMetadataFrameType),
2625                             static_cast<SpdyFrameType>(kMetadataFrameType)}));
2626   EXPECT_FALSE(adapter->want_write());
2627 }
2628 
TEST(NgHttp2AdapterTest,SubmitConnectionMetadata)2629 TEST(NgHttp2AdapterTest, SubmitConnectionMetadata) {
2630   DataSavingVisitor visitor;
2631   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2632 
2633   auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
2634       {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
2635   adapter->SubmitMetadata(0, 16384u, std::move(source));
2636   EXPECT_TRUE(adapter->want_write());
2637 
2638   EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 0, _, 0x4));
2639   EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 0, _, 0x4, 0));
2640 
2641   int result = adapter->Send();
2642   EXPECT_EQ(0, result);
2643   absl::string_view serialized = visitor.data();
2644   EXPECT_THAT(serialized,
2645               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
2646   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
2647   EXPECT_THAT(serialized,
2648               EqualsFrames({static_cast<SpdyFrameType>(kMetadataFrameType)}));
2649   EXPECT_FALSE(adapter->want_write());
2650 }
2651 
TEST(NgHttp2AdapterTest,ClientSubmitMetadataWithGoaway)2652 TEST(NgHttp2AdapterTest, ClientSubmitMetadataWithGoaway) {
2653   DataSavingVisitor visitor;
2654   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2655 
2656   adapter->SubmitSettings({});
2657 
2658   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, _, _, 0x0));
2659   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, _, _, 0x0, 0));
2660   adapter->Send();
2661 
2662   const std::vector<Header> headers =
2663       ToHeaders({{":method", "GET"},
2664                  {":scheme", "http"},
2665                  {":authority", "example.com"},
2666                  {":path", "/this/is/request/one"}});
2667   const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
2668 
2669   auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
2670       {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
2671   adapter->SubmitMetadata(stream_id, 16384u, std::move(source));
2672   EXPECT_TRUE(adapter->want_write());
2673 
2674   const std::string initial_frames =
2675       TestFrameSequence()
2676           .ServerPreface()
2677           .GoAway(3, Http2ErrorCode::HTTP2_NO_ERROR, "server shutting down")
2678           .Serialize();
2679   testing::InSequence s;
2680 
2681   // Server preface
2682   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
2683   EXPECT_CALL(visitor, OnSettingsStart());
2684   EXPECT_CALL(visitor, OnSettingsEnd());
2685   EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
2686   EXPECT_CALL(visitor, OnGoAway(3, Http2ErrorCode::HTTP2_NO_ERROR, _));
2687 
2688   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
2689   EXPECT_EQ(initial_frames.size(), initial_result);
2690 
2691   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
2692   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
2693   // HEADERS frame is not sent.
2694   EXPECT_CALL(visitor,
2695               OnBeforeFrameSent(kMetadataFrameType, stream_id, _, 0x4));
2696   EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, stream_id, _, 0x4, 0));
2697   EXPECT_CALL(visitor,
2698               OnCloseStream(stream_id, Http2ErrorCode::REFUSED_STREAM));
2699 
2700   int result = adapter->Send();
2701   EXPECT_EQ(0, result);
2702   absl::string_view serialized = visitor.data();
2703   EXPECT_THAT(serialized,
2704               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
2705   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
2706   EXPECT_THAT(serialized,
2707               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
2708                             static_cast<SpdyFrameType>(kMetadataFrameType)}));
2709   EXPECT_FALSE(adapter->want_write());
2710 }
2711 
TEST(NgHttp2AdapterTest,ClientSubmitMetadataWithFailureBefore)2712 TEST(NgHttp2AdapterTest, ClientSubmitMetadataWithFailureBefore) {
2713   DataSavingVisitor visitor;
2714   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2715 
2716   adapter->SubmitSettings({});
2717 
2718   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, _, _, 0x0));
2719   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, _, _, 0x0, 0));
2720   adapter->Send();
2721 
2722   const std::vector<Header> headers =
2723       ToHeaders({{":method", "GET"},
2724                  {":scheme", "http"},
2725                  {":authority", "example.com"},
2726                  {":path", "/this/is/request/one"}});
2727   const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
2728 
2729   auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
2730       {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
2731   adapter->SubmitMetadata(stream_id, 16384u, std::move(source));
2732   EXPECT_TRUE(adapter->want_write());
2733 
2734   const std::string initial_frames =
2735       TestFrameSequence().ServerPreface().Serialize();
2736   testing::InSequence s;
2737 
2738   // Server preface
2739   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
2740   EXPECT_CALL(visitor, OnSettingsStart());
2741   EXPECT_CALL(visitor, OnSettingsEnd());
2742 
2743   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
2744   EXPECT_EQ(initial_frames.size(), initial_result);
2745 
2746   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
2747   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
2748   EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, stream_id, _, 0x4))
2749       .WillOnce(testing::Return(NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE));
2750   EXPECT_CALL(visitor, OnConnectionError(
2751                            Http2VisitorInterface::ConnectionError::kSendError));
2752 
2753   int result = adapter->Send();
2754   EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, result);
2755   absl::string_view serialized = visitor.data();
2756   EXPECT_THAT(serialized,
2757               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
2758   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
2759   EXPECT_THAT(serialized,
2760               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
2761 }
2762 
TEST(NgHttp2AdapterTest,ClientSubmitMetadataWithFailureDuring)2763 TEST(NgHttp2AdapterTest, ClientSubmitMetadataWithFailureDuring) {
2764   DataSavingVisitor visitor;
2765   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2766 
2767   adapter->SubmitSettings({});
2768 
2769   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, _, _, 0x0));
2770   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, _, _, 0x0, 0));
2771   adapter->Send();
2772 
2773   const std::vector<Header> headers =
2774       ToHeaders({{":method", "GET"},
2775                  {":scheme", "http"},
2776                  {":authority", "example.com"},
2777                  {":path", "/this/is/request/one"}});
2778   const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
2779 
2780   auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(
2781       ToHeaders({{"more-than-one-frame", std::string(20000, 'a')}})));
2782   adapter->SubmitMetadata(stream_id, 16384u, std::move(source));
2783   EXPECT_TRUE(adapter->want_write());
2784 
2785   const std::string initial_frames =
2786       TestFrameSequence().ServerPreface().Serialize();
2787   testing::InSequence s;
2788 
2789   // Server preface
2790   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
2791   EXPECT_CALL(visitor, OnSettingsStart());
2792   EXPECT_CALL(visitor, OnSettingsEnd());
2793 
2794   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
2795   EXPECT_EQ(initial_frames.size(), initial_result);
2796 
2797   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
2798   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
2799   EXPECT_CALL(visitor,
2800               OnBeforeFrameSent(kMetadataFrameType, stream_id, _, 0x0));
2801   EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, stream_id, _, 0x0, 0))
2802       .WillOnce(testing::Return(NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE));
2803   EXPECT_CALL(visitor, OnConnectionError(
2804                            Http2VisitorInterface::ConnectionError::kSendError));
2805 
2806   int result = adapter->Send();
2807   EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, result);
2808   absl::string_view serialized = visitor.data();
2809   EXPECT_THAT(serialized,
2810               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
2811   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
2812   EXPECT_THAT(serialized,
2813               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
2814                             static_cast<SpdyFrameType>(kMetadataFrameType)}));
2815 }
2816 
TEST(NgHttp2AdapterTest,ClientSubmitMetadataWithFailureSending)2817 TEST(NgHttp2AdapterTest, ClientSubmitMetadataWithFailureSending) {
2818   DataSavingVisitor visitor;
2819   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2820 
2821   adapter->SubmitSettings({});
2822 
2823   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, _, _, 0x0));
2824   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, _, _, 0x0, 0));
2825   adapter->Send();
2826 
2827   const std::vector<Header> headers =
2828       ToHeaders({{":method", "GET"},
2829                  {":scheme", "http"},
2830                  {":authority", "example.com"},
2831                  {":path", "/this/is/request/one"}});
2832   const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
2833 
2834   auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(
2835       ToHeaders({{"more-than-one-frame", std::string(20000, 'a')}})));
2836   source->InjectFailure();
2837   adapter->SubmitMetadata(stream_id, 16384u, std::move(source));
2838   EXPECT_TRUE(adapter->want_write());
2839 
2840   const std::string initial_frames =
2841       TestFrameSequence().ServerPreface().Serialize();
2842   testing::InSequence s;
2843 
2844   // Server preface
2845   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
2846   EXPECT_CALL(visitor, OnSettingsStart());
2847   EXPECT_CALL(visitor, OnSettingsEnd());
2848 
2849   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
2850   EXPECT_EQ(initial_frames.size(), initial_result);
2851 
2852   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
2853   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
2854   EXPECT_CALL(visitor, OnConnectionError(
2855                            Http2VisitorInterface::ConnectionError::kSendError));
2856 
2857   int result = adapter->Send();
2858   EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, result);
2859   absl::string_view serialized = visitor.data();
2860   EXPECT_THAT(serialized,
2861               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
2862   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
2863   EXPECT_THAT(serialized, EqualsFrames({
2864                               SpdyFrameType::SETTINGS,
2865                               SpdyFrameType::SETTINGS,
2866                           }));
2867 }
2868 
TEST(NgHttp2AdapterTest,ClientObeysMaxConcurrentStreams)2869 TEST(NgHttp2AdapterTest, ClientObeysMaxConcurrentStreams) {
2870   DataSavingVisitor visitor;
2871   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2872   int result = adapter->Send();
2873   EXPECT_EQ(0, result);
2874   // Client preface does not appear to include the mandatory SETTINGS frame.
2875   EXPECT_THAT(visitor.data(),
2876               testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
2877   visitor.Clear();
2878 
2879   const std::string initial_frames =
2880       TestFrameSequence()
2881           .ServerPreface({{MAX_CONCURRENT_STREAMS, 1}})
2882           .Serialize();
2883   testing::InSequence s;
2884 
2885   // Server preface (SETTINGS with MAX_CONCURRENT_STREAMS)
2886   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
2887   EXPECT_CALL(visitor, OnSettingsStart());
2888   EXPECT_CALL(visitor, OnSetting);
2889   EXPECT_CALL(visitor, OnSettingsEnd());
2890 
2891   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
2892   EXPECT_EQ(initial_frames.size(), initial_result);
2893 
2894   EXPECT_TRUE(adapter->want_write());
2895 
2896   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
2897   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
2898 
2899   result = adapter->Send();
2900   EXPECT_EQ(0, result);
2901   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
2902   visitor.Clear();
2903 
2904   EXPECT_FALSE(adapter->want_write());
2905   const absl::string_view kBody = "This is an example request body.";
2906   auto body1 = std::make_unique<TestDataFrameSource>(visitor, true);
2907   body1->AppendPayload(kBody);
2908   body1->EndData();
2909   const int stream_id =
2910       adapter->SubmitRequest(ToHeaders({{":method", "POST"},
2911                                         {":scheme", "http"},
2912                                         {":authority", "example.com"},
2913                                         {":path", "/this/is/request/one"}}),
2914                              std::move(body1), nullptr);
2915   EXPECT_GT(stream_id, 0);
2916   EXPECT_TRUE(adapter->want_write());
2917 
2918   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
2919   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
2920   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
2921 
2922   result = adapter->Send();
2923   EXPECT_EQ(0, result);
2924 
2925   EXPECT_THAT(visitor.data(),
2926               EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
2927   EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
2928   visitor.Clear();
2929   EXPECT_FALSE(adapter->want_write());
2930 
2931   const int next_stream_id =
2932       adapter->SubmitRequest(ToHeaders({{":method", "POST"},
2933                                         {":scheme", "http"},
2934                                         {":authority", "example.com"},
2935                                         {":path", "/this/is/request/two"}}),
2936                              nullptr, nullptr);
2937 
2938   // A new pending stream is created, but because of MAX_CONCURRENT_STREAMS, the
2939   // session should not want to write it at the moment.
2940   EXPECT_GT(next_stream_id, stream_id);
2941   EXPECT_FALSE(adapter->want_write());
2942 
2943   const std::string stream_frames =
2944       TestFrameSequence()
2945           .Headers(stream_id,
2946                    {{":status", "200"},
2947                     {"server", "my-fake-server"},
2948                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
2949                    /*fin=*/false)
2950           .Data(stream_id, "This is the response body.", /*fin=*/true)
2951           .Serialize();
2952 
2953   EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 4));
2954   EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
2955   EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
2956   EXPECT_CALL(visitor,
2957               OnHeaderForStream(stream_id, "server", "my-fake-server"));
2958   EXPECT_CALL(visitor, OnHeaderForStream(stream_id, "date",
2959                                          "Tue, 6 Apr 2021 12:54:01 GMT"));
2960   EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
2961   EXPECT_CALL(visitor, OnFrameHeader(stream_id, 26, DATA, 0x1));
2962   EXPECT_CALL(visitor, OnBeginDataForStream(stream_id, 26));
2963   EXPECT_CALL(visitor,
2964               OnDataForStream(stream_id, "This is the response body."));
2965   EXPECT_CALL(visitor, OnEndStream(stream_id));
2966   EXPECT_CALL(visitor,
2967               OnCloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR));
2968 
2969   // The first stream should close, which should make the session want to write
2970   // the next stream.
2971   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
2972   EXPECT_EQ(stream_frames.size(), stream_result);
2973   EXPECT_TRUE(adapter->want_write());
2974 
2975   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, next_stream_id, _, 0x5));
2976   EXPECT_CALL(visitor, OnFrameSent(HEADERS, next_stream_id, _, 0x5, 0));
2977 
2978   result = adapter->Send();
2979   EXPECT_EQ(0, result);
2980 
2981   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
2982   visitor.Clear();
2983   EXPECT_FALSE(adapter->want_write());
2984 }
2985 
TEST(NgHttp2AdapterTest,ClientReceivesInitialWindowSetting)2986 TEST(NgHttp2AdapterTest, ClientReceivesInitialWindowSetting) {
2987   DataSavingVisitor visitor;
2988   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
2989 
2990   const std::string initial_frames =
2991       TestFrameSequence()
2992           .Settings({{INITIAL_WINDOW_SIZE, 80000u}})
2993           .WindowUpdate(0, 65536)
2994           .Serialize();
2995   // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
2996   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
2997   EXPECT_CALL(visitor, OnSettingsStart());
2998   EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
2999   EXPECT_CALL(visitor, OnSettingsEnd());
3000   EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
3001   EXPECT_CALL(visitor, OnWindowUpdate(0, 65536));
3002 
3003   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
3004   EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
3005 
3006   // Session will want to write a SETTINGS ack.
3007   EXPECT_TRUE(adapter->want_write());
3008 
3009   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
3010   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
3011 
3012   int64_t result = adapter->Send();
3013   EXPECT_EQ(0, result);
3014   absl::string_view serialized = visitor.data();
3015   EXPECT_THAT(serialized,
3016               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
3017   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
3018   EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
3019   visitor.Clear();
3020 
3021   const std::string kLongBody = std::string(81000, 'c');
3022   auto body1 = std::make_unique<TestDataFrameSource>(visitor, true);
3023   body1->AppendPayload(kLongBody);
3024   body1->EndData();
3025   const int stream_id =
3026       adapter->SubmitRequest(ToHeaders({{":method", "POST"},
3027                                         {":scheme", "http"},
3028                                         {":authority", "example.com"},
3029                                         {":path", "/this/is/request/one"}}),
3030                              std::move(body1), nullptr);
3031   EXPECT_GT(stream_id, 0);
3032   EXPECT_TRUE(adapter->want_write());
3033 
3034   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
3035   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
3036   // The client can send more than 4 frames (65536 bytes) of data.
3037   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16384, 0x0, 0)).Times(4);
3038   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 14464, 0x0, 0));
3039 
3040   result = adapter->Send();
3041   EXPECT_EQ(0, result);
3042   EXPECT_THAT(visitor.data(),
3043               EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
3044                             SpdyFrameType::DATA, SpdyFrameType::DATA,
3045                             SpdyFrameType::DATA, SpdyFrameType::DATA}));
3046 }
3047 
TEST(NgHttp2AdapterTest,ClientReceivesInitialWindowSettingAfterStreamStart)3048 TEST(NgHttp2AdapterTest, ClientReceivesInitialWindowSettingAfterStreamStart) {
3049   DataSavingVisitor visitor;
3050   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
3051 
3052   const std::string initial_frames =
3053       TestFrameSequence().ServerPreface().WindowUpdate(0, 65536).Serialize();
3054   // Server preface (empty SETTINGS)
3055   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3056   EXPECT_CALL(visitor, OnSettingsStart());
3057   EXPECT_CALL(visitor, OnSettingsEnd());
3058   EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
3059   EXPECT_CALL(visitor, OnWindowUpdate(0, 65536));
3060 
3061   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
3062   EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
3063 
3064   // Session will want to write a SETTINGS ack.
3065   EXPECT_TRUE(adapter->want_write());
3066 
3067   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
3068   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
3069 
3070   int64_t result = adapter->Send();
3071   EXPECT_EQ(0, result);
3072   visitor.Clear();
3073 
3074   const std::string kLongBody = std::string(81000, 'c');
3075   auto body1 = std::make_unique<TestDataFrameSource>(visitor, true);
3076   body1->AppendPayload(kLongBody);
3077   body1->EndData();
3078   const int stream_id =
3079       adapter->SubmitRequest(ToHeaders({{":method", "POST"},
3080                                         {":scheme", "http"},
3081                                         {":authority", "example.com"},
3082                                         {":path", "/this/is/request/one"}}),
3083                              std::move(body1), nullptr);
3084   EXPECT_GT(stream_id, 0);
3085   EXPECT_TRUE(adapter->want_write());
3086 
3087   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
3088   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
3089   // The client can only send 65535 bytes of data, as the stream window has not
3090   // yet been increased.
3091   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16384, 0x0, 0)).Times(3);
3092   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16383, 0x0, 0));
3093 
3094   result = adapter->Send();
3095   EXPECT_EQ(0, result);
3096   EXPECT_THAT(visitor.data(),
3097               EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
3098                             SpdyFrameType::DATA, SpdyFrameType::DATA,
3099                             SpdyFrameType::DATA}));
3100   visitor.Clear();
3101 
3102   // Can't write any more due to flow control.
3103   EXPECT_FALSE(adapter->want_write());
3104 
3105   const std::string settings_frame =
3106       TestFrameSequence().Settings({{INITIAL_WINDOW_SIZE, 80000u}}).Serialize();
3107   // SETTINGS with INITIAL_STREAM_WINDOW
3108   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
3109   EXPECT_CALL(visitor, OnSettingsStart());
3110   EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
3111   EXPECT_CALL(visitor, OnSettingsEnd());
3112 
3113   const int64_t settings_result = adapter->ProcessBytes(settings_frame);
3114   EXPECT_EQ(settings_frame.size(), static_cast<size_t>(settings_result));
3115 
3116   EXPECT_TRUE(adapter->want_write());
3117 
3118   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
3119   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
3120   // The client can write more after receiving the INITIAL_WINDOW_SIZE setting.
3121   EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 14465, 0x0, 0));
3122 
3123   result = adapter->Send();
3124   EXPECT_EQ(0, result);
3125   EXPECT_THAT(visitor.data(),
3126               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::DATA}));
3127 }
3128 
TEST(NgHttp2AdapterTest,InvalidInitialWindowSetting)3129 TEST(NgHttp2AdapterTest, InvalidInitialWindowSetting) {
3130   DataSavingVisitor visitor;
3131   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
3132 
3133   const uint32_t kTooLargeInitialWindow = 1u << 31;
3134   const std::string initial_frames =
3135       TestFrameSequence()
3136           .Settings({{INITIAL_WINDOW_SIZE, kTooLargeInitialWindow}})
3137           .Serialize();
3138   // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
3139   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
3140   EXPECT_CALL(visitor,
3141               OnInvalidFrame(
3142                   0, Http2VisitorInterface::InvalidFrameError::kFlowControl));
3143 
3144   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
3145   EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
3146 
3147   // Session will want to write a GOAWAY.
3148   EXPECT_TRUE(adapter->want_write());
3149 
3150   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
3151   EXPECT_CALL(
3152       visitor,
3153       OnFrameSent(GOAWAY, 0, _, 0x0,
3154                   static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
3155 
3156   int64_t result = adapter->Send();
3157   EXPECT_EQ(0, result);
3158   absl::string_view serialized = visitor.data();
3159   EXPECT_THAT(serialized,
3160               testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
3161   serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
3162   EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::GOAWAY}));
3163   visitor.Clear();
3164 }
3165 
TEST(NgHttp2AdapterTest,InitialWindowSettingCausesOverflow)3166 TEST(NgHttp2AdapterTest, InitialWindowSettingCausesOverflow) {
3167   DataSavingVisitor visitor;
3168   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
3169 
3170   testing::InSequence s;
3171 
3172   const std::vector<Header> headers =
3173       ToHeaders({{":method", "GET"},
3174                  {":scheme", "http"},
3175                  {":authority", "example.com"},
3176                  {":path", "/this/is/request/one"}});
3177   const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
3178   ASSERT_GT(stream_id, 0);
3179   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
3180   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
3181   int64_t write_result = adapter->Send();
3182   EXPECT_EQ(0, write_result);
3183   absl::string_view data = visitor.data();
3184   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
3185   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
3186   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
3187   visitor.Clear();
3188 
3189   const uint32_t kLargeInitialWindow = (1u << 31) - 1;
3190   const std::string frames =
3191       TestFrameSequence()
3192           .ServerPreface()
3193           .Headers(stream_id, {{":status", "200"}}, /*fin=*/false)
3194           .WindowUpdate(stream_id, 65536u)
3195           .Settings({{INITIAL_WINDOW_SIZE, kLargeInitialWindow}})
3196           .Serialize();
3197 
3198   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3199   EXPECT_CALL(visitor, OnSettingsStart());
3200   EXPECT_CALL(visitor, OnSettingsEnd());
3201 
3202   EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 0x4));
3203   EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
3204   EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
3205   EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
3206 
3207   EXPECT_CALL(visitor, OnFrameHeader(stream_id, 4, WINDOW_UPDATE, 0x0));
3208   EXPECT_CALL(visitor, OnWindowUpdate(stream_id, 65536));
3209 
3210   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
3211   EXPECT_CALL(visitor, OnSettingsStart());
3212   EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE,
3213                                               kLargeInitialWindow}));
3214   EXPECT_CALL(visitor, OnSettingsEnd());
3215 
3216   const int64_t read_result = adapter->ProcessBytes(frames);
3217   EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
3218   EXPECT_TRUE(adapter->want_write());
3219 
3220   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
3221   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
3222   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
3223   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
3224 
3225   // The stream window update plus the SETTINGS frame with INITIAL_WINDOW_SIZE
3226   // pushes the stream's flow control window outside of the acceptable range.
3227   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id, 4, 0x0));
3228   EXPECT_CALL(
3229       visitor,
3230       OnFrameSent(RST_STREAM, stream_id, 4, 0x0,
3231                   static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
3232   EXPECT_CALL(visitor,
3233               OnCloseStream(stream_id, Http2ErrorCode::FLOW_CONTROL_ERROR));
3234 
3235   int result = adapter->Send();
3236   EXPECT_EQ(0, result);
3237   EXPECT_THAT(visitor.data(),
3238               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
3239                             SpdyFrameType::RST_STREAM}));
3240 }
3241 
TEST(NgHttp2AdapterTest,ClientForbidsPushPromise)3242 TEST(NgHttp2AdapterTest, ClientForbidsPushPromise) {
3243   DataSavingVisitor visitor;
3244   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
3245   adapter->SubmitSettings({{ENABLE_PUSH, 0}});
3246 
3247   testing::InSequence s;
3248 
3249   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
3250   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
3251 
3252   int write_result = adapter->Send();
3253   EXPECT_EQ(0, write_result);
3254   absl::string_view data = visitor.data();
3255   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
3256   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
3257   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
3258 
3259   visitor.Clear();
3260 
3261   const std::vector<Header> headers =
3262       ToHeaders({{":method", "GET"},
3263                  {":scheme", "http"},
3264                  {":authority", "example.com"},
3265                  {":path", "/this/is/request/one"}});
3266   const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
3267   ASSERT_GT(stream_id, 0);
3268   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
3269   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
3270   write_result = adapter->Send();
3271   EXPECT_EQ(0, write_result);
3272   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
3273   visitor.Clear();
3274 
3275   const std::vector<Header> push_headers =
3276       ToHeaders({{":method", "GET"},
3277                  {":scheme", "http"},
3278                  {":authority", "example.com"},
3279                  {":path", "/this/is/request/push"}});
3280   const std::string frames = TestFrameSequence()
3281                                  .ServerPreface()
3282                                  .SettingsAck()
3283                                  .PushPromise(stream_id, 2, push_headers)
3284                                  .Serialize();
3285 
3286   // Server preface (empty SETTINGS)
3287   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3288   EXPECT_CALL(visitor, OnSettingsStart());
3289   EXPECT_CALL(visitor, OnSettingsEnd());
3290 
3291   // SETTINGS ack (to acknowledge PUSH_ENABLED=0)
3292   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
3293   EXPECT_CALL(visitor, OnSettingsAck);
3294 
3295   // The PUSH_PROMISE is now treated as an invalid frame.
3296   EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, PUSH_PROMISE, _));
3297   EXPECT_CALL(visitor, OnInvalidFrame(stream_id, _));
3298 
3299   const int64_t read_result = adapter->ProcessBytes(frames);
3300   EXPECT_EQ(frames.size(), read_result);
3301 
3302   EXPECT_TRUE(adapter->want_write());
3303 
3304   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
3305   EXPECT_CALL(
3306       visitor,
3307       OnFrameSent(GOAWAY, 0, _, 0x0,
3308                   static_cast<int32_t>(Http2ErrorCode::PROTOCOL_ERROR)));
3309 
3310   write_result = adapter->Send();
3311   EXPECT_EQ(0, write_result);
3312 }
3313 
TEST(NgHttp2AdapterTest,ClientForbidsPushStream)3314 TEST(NgHttp2AdapterTest, ClientForbidsPushStream) {
3315   DataSavingVisitor visitor;
3316   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
3317   adapter->SubmitSettings({{ENABLE_PUSH, 0}});
3318 
3319   testing::InSequence s;
3320 
3321   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
3322   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
3323 
3324   int write_result = adapter->Send();
3325   EXPECT_EQ(0, write_result);
3326   absl::string_view data = visitor.data();
3327   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
3328   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
3329   EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
3330 
3331   visitor.Clear();
3332 
3333   const std::vector<Header> headers =
3334       ToHeaders({{":method", "GET"},
3335                  {":scheme", "http"},
3336                  {":authority", "example.com"},
3337                  {":path", "/this/is/request/one"}});
3338   const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
3339   ASSERT_GT(stream_id, 0);
3340   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
3341   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
3342   write_result = adapter->Send();
3343   EXPECT_EQ(0, write_result);
3344   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
3345   visitor.Clear();
3346 
3347   const std::string frames =
3348       TestFrameSequence()
3349           .ServerPreface()
3350           .SettingsAck()
3351           .Headers(2,
3352                    {{":status", "200"},
3353                     {"server", "my-fake-server"},
3354                     {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
3355                    /*fin=*/true)
3356           .Serialize();
3357 
3358   // Server preface (empty SETTINGS)
3359   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3360   EXPECT_CALL(visitor, OnSettingsStart());
3361   EXPECT_CALL(visitor, OnSettingsEnd());
3362 
3363   // SETTINGS ack (to acknowledge PUSH_ENABLED=0)
3364   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
3365   EXPECT_CALL(visitor, OnSettingsAck);
3366 
3367   // The push HEADERS are invalid.
3368   EXPECT_CALL(visitor, OnFrameHeader(2, _, HEADERS, _));
3369   EXPECT_CALL(visitor, OnInvalidFrame(2, _));
3370 
3371   const int64_t read_result = adapter->ProcessBytes(frames);
3372   EXPECT_EQ(frames.size(), read_result);
3373 
3374   EXPECT_TRUE(adapter->want_write());
3375 
3376   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
3377   EXPECT_CALL(
3378       visitor,
3379       OnFrameSent(GOAWAY, 0, _, 0x0,
3380                   static_cast<int32_t>(Http2ErrorCode::PROTOCOL_ERROR)));
3381 
3382   write_result = adapter->Send();
3383   EXPECT_EQ(0, write_result);
3384 }
3385 
TEST(NgHttp2AdapterTest,FailureSendingConnectionPreface)3386 TEST(NgHttp2AdapterTest, FailureSendingConnectionPreface) {
3387   DataSavingVisitor visitor;
3388   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
3389 
3390   visitor.set_has_write_error();
3391   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
3392 
3393   int result = adapter->Send();
3394   EXPECT_EQ(result, NGHTTP2_ERR_CALLBACK_FAILURE);
3395 }
3396 
TEST(NgHttp2AdapterTest,MaxFrameSizeSettingNotAppliedBeforeAck)3397 TEST(NgHttp2AdapterTest, MaxFrameSizeSettingNotAppliedBeforeAck) {
3398   DataSavingVisitor visitor;
3399   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
3400 
3401   const uint32_t large_frame_size = kDefaultFramePayloadSizeLimit + 42;
3402   adapter->SubmitSettings({{MAX_FRAME_SIZE, large_frame_size}});
3403   const int32_t stream_id =
3404       adapter->SubmitRequest(ToHeaders({{":method", "GET"},
3405                                         {":scheme", "https"},
3406                                         {":authority", "example.com"},
3407                                         {":path", "/this/is/request/one"}}),
3408                              /*data_source=*/nullptr, /*user_data=*/nullptr);
3409   EXPECT_GT(stream_id, 0);
3410   EXPECT_TRUE(adapter->want_write());
3411 
3412   testing::InSequence s;
3413 
3414   // Client preface (SETTINGS with MAX_FRAME_SIZE) and request HEADERS
3415   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
3416   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
3417   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
3418   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
3419 
3420   int send_result = adapter->Send();
3421   EXPECT_EQ(0, send_result);
3422   absl::string_view data = visitor.data();
3423   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
3424   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
3425   EXPECT_THAT(data,
3426               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
3427   visitor.Clear();
3428 
3429   const std::string server_frames =
3430       TestFrameSequence()
3431           .ServerPreface()
3432           .Headers(1, {{":status", "200"}}, /*fin=*/false)
3433           .Data(1, std::string(large_frame_size, 'a'))
3434           .Serialize();
3435 
3436   // Server preface (empty SETTINGS)
3437   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3438   EXPECT_CALL(visitor, OnSettingsStart());
3439   EXPECT_CALL(visitor, OnSettingsEnd());
3440 
3441   // Response HEADERS. Because the SETTINGS with MAX_FRAME_SIZE was not
3442   // acknowledged, the large DATA is treated as a connection error. Note that
3443   // nghttp2 does not deliver any DATA or connection error events.
3444   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
3445   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
3446   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
3447   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
3448 
3449   const int64_t process_result = adapter->ProcessBytes(server_frames);
3450   EXPECT_EQ(server_frames.size(), static_cast<size_t>(process_result));
3451 
3452   EXPECT_TRUE(adapter->want_write());
3453 
3454   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
3455   EXPECT_CALL(visitor,
3456               OnFrameSent(GOAWAY, 0, _, 0x0,
3457                           static_cast<int>(Http2ErrorCode::FRAME_SIZE_ERROR)));
3458 
3459   send_result = adapter->Send();
3460   EXPECT_EQ(0, send_result);
3461   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
3462 }
3463 
TEST(NgHttp2AdapterTest,MaxFrameSizeSettingAppliedAfterAck)3464 TEST(NgHttp2AdapterTest, MaxFrameSizeSettingAppliedAfterAck) {
3465   DataSavingVisitor visitor;
3466   auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
3467 
3468   const uint32_t large_frame_size = kDefaultFramePayloadSizeLimit + 42;
3469   adapter->SubmitSettings({{MAX_FRAME_SIZE, large_frame_size}});
3470   const int32_t stream_id =
3471       adapter->SubmitRequest(ToHeaders({{":method", "GET"},
3472                                         {":scheme", "https"},
3473                                         {":authority", "example.com"},
3474                                         {":path", "/this/is/request/one"}}),
3475                              /*data_source=*/nullptr, /*user_data=*/nullptr);
3476   EXPECT_GT(stream_id, 0);
3477   EXPECT_TRUE(adapter->want_write());
3478 
3479   testing::InSequence s;
3480 
3481   // Client preface (SETTINGS with MAX_FRAME_SIZE) and request HEADERS
3482   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
3483   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
3484   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
3485   EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
3486 
3487   int send_result = adapter->Send();
3488   EXPECT_EQ(0, send_result);
3489   absl::string_view data = visitor.data();
3490   EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
3491   data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
3492   EXPECT_THAT(data,
3493               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
3494   visitor.Clear();
3495 
3496   const std::string server_frames =
3497       TestFrameSequence()
3498           .ServerPreface()
3499           .SettingsAck()
3500           .Headers(1, {{":status", "200"}}, /*fin=*/false)
3501           .Data(1, std::string(large_frame_size, 'a'))
3502           .Serialize();
3503 
3504   // Server preface (empty SETTINGS) and ack of SETTINGS.
3505   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3506   EXPECT_CALL(visitor, OnSettingsStart());
3507   EXPECT_CALL(visitor, OnSettingsEnd());
3508   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
3509   EXPECT_CALL(visitor, OnSettingsAck());
3510 
3511   // Response HEADERS and DATA. Because the SETTINGS with MAX_FRAME_SIZE was
3512   // acknowledged, the large DATA is accepted without any error.
3513   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
3514   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
3515   EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
3516   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
3517   EXPECT_CALL(visitor, OnFrameHeader(1, large_frame_size, DATA, 0x0));
3518   EXPECT_CALL(visitor, OnBeginDataForStream(1, large_frame_size));
3519   EXPECT_CALL(visitor, OnDataForStream(1, _));
3520 
3521   const int64_t process_result = adapter->ProcessBytes(server_frames);
3522   EXPECT_EQ(server_frames.size(), static_cast<size_t>(process_result));
3523 
3524   // Client ack of SETTINGS.
3525   EXPECT_TRUE(adapter->want_write());
3526   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
3527   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
3528 
3529   send_result = adapter->Send();
3530   EXPECT_EQ(0, send_result);
3531   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
3532 }
3533 
TEST(NgHttp2AdapterTest,WindowUpdateRaisesFlowControlWindowLimit)3534 TEST(NgHttp2AdapterTest, WindowUpdateRaisesFlowControlWindowLimit) {
3535   DataSavingVisitor visitor;
3536   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
3537 
3538   const std::string data_chunk(kDefaultFramePayloadSizeLimit, 'a');
3539   const std::string request = TestFrameSequence()
3540                                   .ClientPreface()
3541                                   .Headers(1,
3542                                            {{":method", "GET"},
3543                                             {":scheme", "https"},
3544                                             {":authority", "example.com"},
3545                                             {":path", "/"}},
3546                                            /*fin=*/false)
3547                                   .Serialize();
3548 
3549   // Client preface (empty SETTINGS)
3550   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3551   EXPECT_CALL(visitor, OnSettingsStart());
3552   EXPECT_CALL(visitor, OnSettingsEnd());
3553   // Stream 1
3554   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
3555   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
3556   EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
3557   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
3558 
3559   adapter->ProcessBytes(request);
3560 
3561   // Updates the advertised window for the connection and stream 1.
3562   adapter->SubmitWindowUpdate(0, 2 * kDefaultFramePayloadSizeLimit);
3563   adapter->SubmitWindowUpdate(1, 2 * kDefaultFramePayloadSizeLimit);
3564 
3565   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
3566   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
3567   EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
3568   EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
3569   EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 1, 4, 0x0));
3570   EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 1, 4, 0x0, 0));
3571 
3572   int result = adapter->Send();
3573   EXPECT_EQ(0, result);
3574 
3575   // Verifies the advertised window.
3576   EXPECT_EQ(kInitialFlowControlWindowSize + 2 * kDefaultFramePayloadSizeLimit,
3577             adapter->GetReceiveWindowSize());
3578   EXPECT_EQ(kInitialFlowControlWindowSize + 2 * kDefaultFramePayloadSizeLimit,
3579             adapter->GetStreamReceiveWindowSize(1));
3580 
3581   const std::string request_body = TestFrameSequence()
3582                                        .Data(1, data_chunk)
3583                                        .Data(1, data_chunk)
3584                                        .Data(1, data_chunk)
3585                                        .Data(1, data_chunk)
3586                                        .Data(1, data_chunk)
3587                                        .Serialize();
3588 
3589   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0)).Times(5);
3590   EXPECT_CALL(visitor, OnBeginDataForStream(1, _)).Times(5);
3591   EXPECT_CALL(visitor, OnDataForStream(1, _)).Times(5);
3592 
3593   // DATA frames on stream 1 consume most of the window.
3594   adapter->ProcessBytes(request_body);
3595   EXPECT_EQ(kInitialFlowControlWindowSize - 3 * kDefaultFramePayloadSizeLimit,
3596             adapter->GetReceiveWindowSize());
3597   EXPECT_EQ(kInitialFlowControlWindowSize - 3 * kDefaultFramePayloadSizeLimit,
3598             adapter->GetStreamReceiveWindowSize(1));
3599 
3600   // Marking the data consumed should result in an advertised window larger than
3601   // the initial window.
3602   adapter->MarkDataConsumedForStream(1, 4 * kDefaultFramePayloadSizeLimit);
3603   EXPECT_GT(adapter->GetReceiveWindowSize(), kInitialFlowControlWindowSize);
3604   EXPECT_GT(adapter->GetStreamReceiveWindowSize(1),
3605             kInitialFlowControlWindowSize);
3606 }
3607 
TEST(NgHttp2AdapterTest,ConnectionErrorOnControlFrameSent)3608 TEST(NgHttp2AdapterTest, ConnectionErrorOnControlFrameSent) {
3609   DataSavingVisitor visitor;
3610   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
3611 
3612   const std::string frames =
3613       TestFrameSequence().ClientPreface().Ping(42).Serialize();
3614   testing::InSequence s;
3615 
3616   // Client preface (empty SETTINGS)
3617   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3618   EXPECT_CALL(visitor, OnSettingsStart());
3619   EXPECT_CALL(visitor, OnSettingsEnd());
3620   // PING
3621   EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
3622   EXPECT_CALL(visitor, OnPing(42, false));
3623 
3624   const int64_t read_result = adapter->ProcessBytes(frames);
3625   EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
3626 
3627   EXPECT_TRUE(adapter->want_write());
3628 
3629   // SETTINGS ack
3630   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
3631   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0))
3632       .WillOnce(testing::Return(-902));
3633   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
3634 
3635   int send_result = adapter->Send();
3636   EXPECT_LT(send_result, 0);
3637 
3638   // Apparently nghttp2 retries sending the frames that had failed before.
3639   EXPECT_TRUE(adapter->want_write());
3640 
3641   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
3642   EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
3643   EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
3644   send_result = adapter->Send();
3645   EXPECT_EQ(send_result, 0);
3646 
3647   EXPECT_FALSE(adapter->want_write());
3648 }
3649 
TEST(NgHttp2AdapterTest,ConnectionErrorOnDataFrameSent)3650 TEST(NgHttp2AdapterTest, ConnectionErrorOnDataFrameSent) {
3651   DataSavingVisitor visitor;
3652   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
3653 
3654   const std::string frames = TestFrameSequence()
3655                                  .ClientPreface()
3656                                  .Headers(1,
3657                                           {{":method", "GET"},
3658                                            {":scheme", "https"},
3659                                            {":authority", "example.com"},
3660                                            {":path", "/this/is/request/one"}},
3661                                           /*fin=*/true)
3662                                  .Serialize();
3663   testing::InSequence s;
3664 
3665   // Client preface (empty SETTINGS)
3666   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3667   EXPECT_CALL(visitor, OnSettingsStart());
3668   EXPECT_CALL(visitor, OnSettingsEnd());
3669   // Stream 1
3670   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
3671   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
3672   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
3673   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
3674   EXPECT_CALL(visitor, OnEndStream(1));
3675 
3676   const int64_t read_result = adapter->ProcessBytes(frames);
3677   EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
3678 
3679   auto body = std::make_unique<TestDataFrameSource>(visitor, true);
3680   body->AppendPayload("Here is some data, which will lead to a fatal error");
3681   TestDataFrameSource* body_ptr = body.get();
3682   int submit_result = adapter->SubmitResponse(
3683       1, ToHeaders({{":status", "200"}}), std::move(body));
3684   ASSERT_EQ(0, submit_result);
3685 
3686   EXPECT_TRUE(adapter->want_write());
3687 
3688   // SETTINGS ack
3689   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
3690   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
3691   // Stream 1, with doomed DATA
3692   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
3693   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
3694   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0))
3695       .WillOnce(testing::Return(-902));
3696   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
3697 
3698   int send_result = adapter->Send();
3699   EXPECT_LT(send_result, 0);
3700 
3701   // The test data source got a signal that the first chunk of data was sent
3702   // successfully, so discarded that data internally. However, due to the send
3703   // error, the next Send() from nghttp2 will try to send that exact same data
3704   // again. Without this line appending the exact same data back to the data
3705   // source, the test crashes. It is not clear how the data source would know to
3706   // not discard the data, unless told by the session? This is not intuitive.
3707   body_ptr->AppendPayload(
3708       "Here is some data, which will lead to a fatal error");
3709 
3710   // Apparently nghttp2 retries sending the frames that had failed before.
3711   EXPECT_TRUE(adapter->want_write());
3712   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
3713 
3714   send_result = adapter->Send();
3715   EXPECT_EQ(send_result, 0);
3716 
3717   EXPECT_FALSE(adapter->want_write());
3718 }
3719 
TEST(NgHttp2AdapterTest,ServerConstruction)3720 TEST(NgHttp2AdapterTest, ServerConstruction) {
3721   testing::StrictMock<MockHttp2Visitor> visitor;
3722   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
3723   ASSERT_NE(nullptr, adapter);
3724   EXPECT_TRUE(adapter->want_read());
3725   EXPECT_FALSE(adapter->want_write());
3726   EXPECT_TRUE(adapter->IsServerSession());
3727 }
3728 
TEST(NgHttp2AdapterTest,ServerHandlesFrames)3729 TEST(NgHttp2AdapterTest, ServerHandlesFrames) {
3730   DataSavingVisitor visitor;
3731   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
3732 
3733   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
3734   EXPECT_EQ(0, adapter->GetHpackDecoderDynamicTableSize());
3735 
3736   const std::string frames = TestFrameSequence()
3737                                  .ClientPreface()
3738                                  .Ping(42)
3739                                  .WindowUpdate(0, 1000)
3740                                  .Headers(1,
3741                                           {{":method", "POST"},
3742                                            {":scheme", "https"},
3743                                            {":authority", "example.com"},
3744                                            {":path", "/this/is/request/one"}},
3745                                           /*fin=*/false)
3746                                  .WindowUpdate(1, 2000)
3747                                  .Data(1, "This is the request body.")
3748                                  .Headers(3,
3749                                           {{":method", "GET"},
3750                                            {":scheme", "http"},
3751                                            {":authority", "example.com"},
3752                                            {":path", "/this/is/request/two"}},
3753                                           /*fin=*/true)
3754                                  .RstStream(3, Http2ErrorCode::CANCEL)
3755                                  .Ping(47)
3756                                  .Serialize();
3757   testing::InSequence s;
3758 
3759   const char* kSentinel1 = "arbitrary pointer 1";
3760 
3761   // Client preface (empty SETTINGS)
3762   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3763   EXPECT_CALL(visitor, OnSettingsStart());
3764   EXPECT_CALL(visitor, OnSettingsEnd());
3765 
3766   EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
3767   EXPECT_CALL(visitor, OnPing(42, false));
3768   EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
3769   EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
3770   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
3771   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
3772   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
3773   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
3774   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
3775   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
3776   EXPECT_CALL(visitor, OnEndHeadersForStream(1))
3777       .WillOnce(testing::InvokeWithoutArgs([&adapter, kSentinel1]() {
3778         adapter->SetStreamUserData(1, const_cast<char*>(kSentinel1));
3779         return true;
3780       }));
3781   EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
3782   EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
3783   EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
3784   EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
3785   EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
3786   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
3787   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
3788   EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "GET"));
3789   EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "http"));
3790   EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
3791   EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/two"));
3792   EXPECT_CALL(visitor, OnEndHeadersForStream(3));
3793   EXPECT_CALL(visitor, OnEndStream(3));
3794   EXPECT_CALL(visitor, OnFrameHeader(3, 4, RST_STREAM, 0));
3795   EXPECT_CALL(visitor, OnRstStream(3, Http2ErrorCode::CANCEL));
3796   EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::CANCEL));
3797   EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
3798   EXPECT_CALL(visitor, OnPing(47, false));
3799 
3800   const int64_t result = adapter->ProcessBytes(frames);
3801   EXPECT_EQ(frames.size(), result);
3802 
3803   EXPECT_EQ(kSentinel1, adapter->GetStreamUserData(1));
3804 
3805   EXPECT_GT(kInitialFlowControlWindowSize,
3806             adapter->GetStreamReceiveWindowSize(1));
3807   EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1),
3808             adapter->GetReceiveWindowSize());
3809   // Upper bound should still be the original value.
3810   EXPECT_EQ(kInitialFlowControlWindowSize,
3811             adapter->GetStreamReceiveWindowLimit(1));
3812 
3813   EXPECT_GT(adapter->GetHpackDecoderDynamicTableSize(), 0);
3814 
3815   // Because stream 3 has already been closed, it's not possible to set user
3816   // data.
3817   const char* kSentinel3 = "another arbitrary pointer";
3818   adapter->SetStreamUserData(3, const_cast<char*>(kSentinel3));
3819   EXPECT_EQ(nullptr, adapter->GetStreamUserData(3));
3820 
3821   EXPECT_EQ(3, adapter->GetHighestReceivedStreamId());
3822 
3823   EXPECT_EQ(adapter->GetSendWindowSize(), kInitialFlowControlWindowSize + 1000);
3824 
3825   EXPECT_TRUE(adapter->want_write());
3826 
3827   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
3828   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
3829   EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, 8, 0x1));
3830   EXPECT_CALL(visitor, OnFrameSent(PING, 0, 8, 0x1, 0));
3831   EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, 8, 0x1));
3832   EXPECT_CALL(visitor, OnFrameSent(PING, 0, 8, 0x1, 0));
3833 
3834   int send_result = adapter->Send();
3835   // Some bytes should have been serialized.
3836   EXPECT_EQ(0, send_result);
3837   // SETTINGS ack, two PING acks.
3838   EXPECT_THAT(visitor.data(),
3839               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING,
3840                             SpdyFrameType::PING}));
3841 }
3842 
TEST(NgHttp2AdapterTest,ServerVisitorRejectsHeaders)3843 TEST(NgHttp2AdapterTest, ServerVisitorRejectsHeaders) {
3844   DataSavingVisitor visitor;
3845   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
3846   EXPECT_FALSE(adapter->want_write());
3847 
3848   const std::string frames =
3849       TestFrameSequence()
3850           .ClientPreface()
3851           .Headers(1,
3852                    {{":method", "GET"},
3853                     {":scheme", "https"},
3854                     {":authority", "example.com"},
3855                     {":path", "/this/is/request/one"},
3856                     {"header1", "ok"},
3857                     {"header2", "rejected"},
3858                     {"header3", "not processed"},  // CONTINUATION starts here
3859                     {"header4", "not processed"},
3860                     {"header5", "not processed"},
3861                     {"header6", "not processed"},
3862                     {"header7", "not processed"},
3863                     {"header8", "not processed"}},
3864                    /*fin=*/false, /*add_continuation=*/true)
3865           .Serialize();
3866 
3867   testing::InSequence s;
3868 
3869   // Client preface (empty SETTINGS)
3870   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3871   EXPECT_CALL(visitor, OnSettingsStart());
3872   EXPECT_CALL(visitor, OnSettingsEnd());
3873   // Stream 1
3874   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x0));
3875   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
3876   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
3877   EXPECT_CALL(visitor, OnHeaderForStream(1, "header2", _))
3878       .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
3879   // The CONTINUATION frame header and header fields are not processed.
3880 
3881   int64_t result = adapter->ProcessBytes(frames);
3882   EXPECT_EQ(static_cast<size_t>(result), frames.size());
3883 
3884   EXPECT_TRUE(adapter->want_write());
3885 
3886   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
3887   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
3888   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
3889   EXPECT_CALL(visitor,
3890               OnFrameSent(RST_STREAM, 1, _, 0x0,
3891                           static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
3892   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
3893 
3894   int send_result = adapter->Send();
3895   // Some bytes should have been serialized.
3896   EXPECT_EQ(0, send_result);
3897   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
3898                                             SpdyFrameType::RST_STREAM}));
3899 }
3900 
TEST(OgHttp2AdapterTest,HeaderValuesWithObsTextAllowed)3901 TEST(OgHttp2AdapterTest, HeaderValuesWithObsTextAllowed) {
3902   DataSavingVisitor visitor;
3903   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
3904 
3905   const std::string frames = TestFrameSequence()
3906                                  .ClientPreface()
3907                                  .Headers(1,
3908                                           {{":method", "GET"},
3909                                            {":scheme", "https"},
3910                                            {":authority", "example.com"},
3911                                            {":path", "/"},
3912                                            {"name", "val\xa1ue"}},
3913                                           /*fin=*/true)
3914                                  .Serialize();
3915   testing::InSequence s;
3916 
3917   // Client preface (empty SETTINGS)
3918   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3919   EXPECT_CALL(visitor, OnSettingsStart());
3920   EXPECT_CALL(visitor, OnSettingsEnd());
3921   // Stream 1
3922   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
3923   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
3924   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
3925   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
3926   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
3927   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/"));
3928   EXPECT_CALL(visitor, OnHeaderForStream(1, "name", "val\xa1ue"));
3929   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
3930   EXPECT_CALL(visitor, OnEndStream(1));
3931 
3932   const int64_t result = adapter->ProcessBytes(frames);
3933   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
3934 }
3935 
TEST(NgHttp2AdapterTest,ServerHandlesDataWithPadding)3936 TEST(NgHttp2AdapterTest, ServerHandlesDataWithPadding) {
3937   DataSavingVisitor visitor;
3938   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
3939 
3940   const std::string frames = TestFrameSequence()
3941                                  .ClientPreface()
3942                                  .Headers(1,
3943                                           {{":method", "POST"},
3944                                            {":scheme", "https"},
3945                                            {":authority", "example.com"},
3946                                            {":path", "/this/is/request/one"}},
3947                                           /*fin=*/false)
3948                                  .Data(1, "This is the request body.",
3949                                        /*fin=*/true, /*padding_length=*/39)
3950                                  .Headers(3,
3951                                           {{":method", "GET"},
3952                                            {":scheme", "http"},
3953                                            {":authority", "example.com"},
3954                                            {":path", "/this/is/request/two"}},
3955                                           /*fin=*/true)
3956                                  .Serialize();
3957   testing::InSequence s;
3958 
3959   // Client preface (empty SETTINGS)
3960   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
3961   EXPECT_CALL(visitor, OnSettingsStart());
3962   EXPECT_CALL(visitor, OnSettingsEnd());
3963 
3964   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
3965   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
3966   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
3967   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
3968   EXPECT_CALL(visitor, OnFrameHeader(1, 25 + 39, DATA, 0x9));
3969   EXPECT_CALL(visitor, OnBeginDataForStream(1, 25 + 39));
3970   EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
3971   // Note: nghttp2 passes padding information after the actual data.
3972   EXPECT_CALL(visitor, OnDataPaddingLength(1, 39));
3973   EXPECT_CALL(visitor, OnEndStream(1));
3974   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
3975   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
3976   EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
3977   EXPECT_CALL(visitor, OnEndHeadersForStream(3));
3978   EXPECT_CALL(visitor, OnEndStream(3));
3979 
3980   const int64_t result = adapter->ProcessBytes(frames);
3981   EXPECT_EQ(frames.size(), result);
3982 
3983   EXPECT_TRUE(adapter->want_write());
3984 
3985   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
3986   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
3987 
3988   int send_result = adapter->Send();
3989   EXPECT_EQ(0, send_result);
3990   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
3991 }
3992 
TEST(NgHttp2AdapterTest,ServerHandlesHostHeader)3993 TEST(NgHttp2AdapterTest, ServerHandlesHostHeader) {
3994   DataSavingVisitor visitor;
3995   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
3996 
3997   const std::string frames = TestFrameSequence()
3998                                  .ClientPreface()
3999                                  .Headers(1,
4000                                           {{":method", "POST"},
4001                                            {":scheme", "https"},
4002                                            {":path", "/this/is/request/one"},
4003                                            {"host", "example.com"}},
4004                                           /*fin=*/true)
4005                                  .Headers(3,
4006                                           {{":method", "POST"},
4007                                            {":scheme", "https"},
4008                                            {":authority", "example.com"},
4009                                            {":path", "/this/is/request/one"},
4010                                            {"host", "example.com"}},
4011                                           /*fin=*/true)
4012                                  .Headers(5,
4013                                           {{":method", "POST"},
4014                                            {":scheme", "https"},
4015                                            {":authority", "foo.com"},
4016                                            {":path", "/this/is/request/one"},
4017                                            {"host", "bar.com"}},
4018                                           /*fin=*/true)
4019                                  .Serialize();
4020 
4021   testing::InSequence s;
4022 
4023   // Client preface (empty SETTINGS)
4024   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4025   EXPECT_CALL(visitor, OnSettingsStart());
4026   EXPECT_CALL(visitor, OnSettingsEnd());
4027 
4028   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
4029   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4030   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
4031   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4032   EXPECT_CALL(visitor, OnEndStream(1));
4033 
4034   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
4035   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
4036   EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
4037   EXPECT_CALL(visitor, OnEndHeadersForStream(3));
4038   EXPECT_CALL(visitor, OnEndStream(3));
4039 
4040   EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
4041   EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
4042   EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(5);
4043   EXPECT_CALL(visitor, OnEndHeadersForStream(5));
4044   EXPECT_CALL(visitor, OnEndStream(5));
4045 
4046   const int64_t result = adapter->ProcessBytes(frames);
4047   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4048 
4049   EXPECT_TRUE(adapter->want_write());
4050 
4051   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
4052   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
4053 
4054   int send_result = adapter->Send();
4055   EXPECT_EQ(0, send_result);
4056   visitor.Clear();
4057 }
4058 
4059 // Tests the case where the response body is in the progress of being sent while
4060 // trailers are queued.
TEST(NgHttp2AdapterTest,ServerSubmitsTrailersWhileDataDeferred)4061 TEST(NgHttp2AdapterTest, ServerSubmitsTrailersWhileDataDeferred) {
4062   DataSavingVisitor visitor;
4063   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4064 
4065   const std::string frames = TestFrameSequence()
4066                                  .ClientPreface()
4067                                  .Headers(1,
4068                                           {{":method", "POST"},
4069                                            {":scheme", "https"},
4070                                            {":authority", "example.com"},
4071                                            {":path", "/this/is/request/one"}},
4072                                           /*fin=*/false)
4073                                  .WindowUpdate(1, 2000)
4074                                  .Data(1, "This is the request body.")
4075                                  .WindowUpdate(0, 2000)
4076                                  .Serialize();
4077   testing::InSequence s;
4078 
4079   // Client preface (empty SETTINGS)
4080   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4081   EXPECT_CALL(visitor, OnSettingsStart());
4082   EXPECT_CALL(visitor, OnSettingsEnd());
4083 
4084   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4085   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4086   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
4087   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4088   EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
4089   EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
4090   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
4091   EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
4092   EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
4093   EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
4094   EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
4095 
4096   const int64_t result = adapter->ProcessBytes(frames);
4097   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4098 
4099   EXPECT_TRUE(adapter->want_write());
4100 
4101   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
4102   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
4103 
4104   int send_result = adapter->Send();
4105   EXPECT_EQ(0, send_result);
4106   visitor.Clear();
4107 
4108   const absl::string_view kBody = "This is an example response body.";
4109 
4110   // The body source must indicate that the end of the body is not the end of
4111   // the stream.
4112   auto body1 = std::make_unique<TestDataFrameSource>(visitor, false);
4113   body1->AppendPayload(kBody);
4114   auto* body1_ptr = body1.get();
4115   int submit_result = adapter->SubmitResponse(
4116       1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
4117       std::move(body1));
4118   EXPECT_EQ(submit_result, 0);
4119   EXPECT_TRUE(adapter->want_write());
4120 
4121   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
4122   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
4123   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
4124 
4125   send_result = adapter->Send();
4126   // Some bytes should have been serialized.
4127   EXPECT_EQ(0, send_result);
4128   visitor.Clear();
4129   EXPECT_FALSE(adapter->want_write());
4130 
4131   int trailer_result =
4132       adapter->SubmitTrailer(1, ToHeaders({{"final-status", "a-ok"}}));
4133   ASSERT_EQ(trailer_result, 0);
4134 
4135   // Even though the data source has not finished sending data, nghttp2 will
4136   // write the trailers anyway.
4137   EXPECT_TRUE(adapter->want_write());
4138 
4139   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
4140   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
4141 
4142   send_result = adapter->Send();
4143   EXPECT_EQ(0, send_result);
4144   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
4145   visitor.Clear();
4146 
4147   // Resuming the stream results in the library wanting to write again.
4148   body1_ptr->AppendPayload(kBody);
4149   body1_ptr->EndData();
4150   adapter->ResumeStream(1);
4151   EXPECT_TRUE(adapter->want_write());
4152 
4153   send_result = adapter->Send();
4154   EXPECT_EQ(0, send_result);
4155 
4156   // But no data is written for the stream.
4157   EXPECT_THAT(visitor.data(), testing::IsEmpty());
4158   EXPECT_FALSE(adapter->want_write());
4159 }
4160 
TEST(NgHttp2AdapterTest,ServerSubmitsTrailersWithDataEndStream)4161 TEST(NgHttp2AdapterTest, ServerSubmitsTrailersWithDataEndStream) {
4162   DataSavingVisitor visitor;
4163   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4164 
4165   const std::string frames =
4166       TestFrameSequence()
4167           .ClientPreface()
4168           .Headers(1, {{":method", "GET"},
4169                        {":scheme", "https"},
4170                        {":authority", "example.com"},
4171                        {":path", "/this/is/request/one"}})
4172           .Data(1, "Example data, woohoo.")
4173           .Serialize();
4174 
4175   testing::InSequence s;
4176 
4177   // Client preface (empty SETTINGS)
4178   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4179   EXPECT_CALL(visitor, OnSettingsStart());
4180   EXPECT_CALL(visitor, OnSettingsEnd());
4181   // Stream 1
4182   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, END_HEADERS_FLAG));
4183   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4184   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
4185   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
4186   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
4187   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
4188   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4189   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
4190   EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
4191   EXPECT_CALL(visitor, OnDataForStream(1, _));
4192 
4193   const int64_t result = adapter->ProcessBytes(frames);
4194   EXPECT_EQ(static_cast<size_t>(result), frames.size());
4195 
4196   // Send a body that will end with the END_STREAM flag.
4197   const absl::string_view kBody = "This is an example response body.";
4198   auto body = std::make_unique<TestDataFrameSource>(visitor, /*has_fin=*/true);
4199   body->AppendPayload(kBody);
4200   body->EndData();
4201 
4202   int submit_result = adapter->SubmitResponse(
4203       1, ToHeaders({{":status", "200"}}), std::move(body));
4204   ASSERT_EQ(submit_result, 0);
4205 
4206   const std::vector<Header> trailers =
4207       ToHeaders({{"extra-info", "Trailers are weird but good?"}});
4208   submit_result = adapter->SubmitTrailer(1, trailers);
4209   ASSERT_EQ(submit_result, 0);
4210 
4211   // It looks like nghttp2 drops the response body altogether and goes straight
4212   // to writing the trailers.
4213   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
4214   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
4215   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, END_HEADERS_FLAG));
4216   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, END_HEADERS_FLAG, 0));
4217   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _,
4218                                          END_HEADERS_FLAG | END_STREAM_FLAG));
4219   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _,
4220                                    END_HEADERS_FLAG | END_STREAM_FLAG, 0));
4221 
4222   const int send_result = adapter->Send();
4223   EXPECT_EQ(send_result, 0);
4224   EXPECT_THAT(visitor.data(),
4225               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
4226                             SpdyFrameType::HEADERS}));
4227 }
4228 
TEST(NgHttp2AdapterTest,ServerSubmitsTrailersWithDataEndStreamAndDeferral)4229 TEST(NgHttp2AdapterTest, ServerSubmitsTrailersWithDataEndStreamAndDeferral) {
4230   DataSavingVisitor visitor;
4231   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4232 
4233   const std::string frames =
4234       TestFrameSequence()
4235           .ClientPreface()
4236           .Headers(1, {{":method", "GET"},
4237                        {":scheme", "https"},
4238                        {":authority", "example.com"},
4239                        {":path", "/this/is/request/one"}})
4240           .Data(1, "Example data, woohoo.")
4241           .Serialize();
4242 
4243   testing::InSequence s;
4244 
4245   // Client preface (empty SETTINGS)
4246   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4247   EXPECT_CALL(visitor, OnSettingsStart());
4248   EXPECT_CALL(visitor, OnSettingsEnd());
4249   // Stream 1
4250   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, END_HEADERS_FLAG));
4251   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4252   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
4253   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
4254   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
4255   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
4256   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4257   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
4258   EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
4259   EXPECT_CALL(visitor, OnDataForStream(1, _));
4260 
4261   const int64_t result = adapter->ProcessBytes(frames);
4262   EXPECT_EQ(static_cast<size_t>(result), frames.size());
4263 
4264   // Send a body that will end with the END_STREAM flag. Don't end the body here
4265   // so that more body can be added later.
4266   const absl::string_view kBody = "This is an example response body.";
4267   auto body = std::make_unique<TestDataFrameSource>(visitor, /*has_fin=*/true);
4268   body->AppendPayload(kBody);
4269   TestDataFrameSource& body_ref = *body;
4270 
4271   int submit_result = adapter->SubmitResponse(
4272       1, ToHeaders({{":status", "200"}}), std::move(body));
4273   ASSERT_EQ(submit_result, 0);
4274 
4275   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
4276   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
4277   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, END_HEADERS_FLAG));
4278   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, END_HEADERS_FLAG, 0));
4279   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
4280 
4281   int send_result = adapter->Send();
4282   EXPECT_EQ(0, send_result);
4283   EXPECT_THAT(visitor.data(),
4284               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
4285                             SpdyFrameType::DATA}));
4286   visitor.Clear();
4287 
4288   const std::vector<Header> trailers =
4289       ToHeaders({{"extra-info", "Trailers are weird but good?"}});
4290   submit_result = adapter->SubmitTrailer(1, trailers);
4291   ASSERT_EQ(submit_result, 0);
4292 
4293   // Add more body and signal the end of data. Resuming the stream should allow
4294   // the new body to be sent, though nghttp2 does not send the body.
4295   body_ref.AppendPayload(kBody);
4296   body_ref.EndData();
4297   adapter->ResumeStream(1);
4298 
4299   // For some reason, nghttp2 drops the new body and goes straight to writing
4300   // the trailers.
4301   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _,
4302                                          END_HEADERS_FLAG | END_STREAM_FLAG));
4303   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _,
4304                                    END_HEADERS_FLAG | END_STREAM_FLAG, 0));
4305 
4306   send_result = adapter->Send();
4307   EXPECT_EQ(send_result, 0);
4308   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
4309 }
4310 
TEST(NgHttp2AdapterTest,ClientDisobeysConnectionFlowControl)4311 TEST(NgHttp2AdapterTest, ClientDisobeysConnectionFlowControl) {
4312   DataSavingVisitor visitor;
4313   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4314 
4315   const std::string frames = TestFrameSequence()
4316                                  .ClientPreface()
4317                                  .Headers(1,
4318                                           {{":method", "POST"},
4319                                            {":scheme", "https"},
4320                                            {":authority", "example.com"},
4321                                            {":path", "/this/is/request/one"},
4322                                            {"accept", "some bogus value!"}},
4323                                           /*fin=*/false)
4324                                  // 70000 bytes of data
4325                                  .Data(1, std::string(16384, 'a'))
4326                                  .Data(1, std::string(16384, 'a'))
4327                                  .Data(1, std::string(16384, 'a'))
4328                                  .Data(1, std::string(16384, 'a'))
4329                                  .Data(1, std::string(4464, 'a'))
4330                                  .Serialize();
4331 
4332   testing::InSequence s;
4333   // Client preface (empty SETTINGS)
4334   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4335   EXPECT_CALL(visitor, OnSettingsStart());
4336   EXPECT_CALL(visitor, OnSettingsEnd());
4337 
4338   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4339   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4340   EXPECT_CALL(visitor, OnHeaderForStream).Times(5);
4341   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4342   EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
4343   EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
4344   EXPECT_CALL(visitor, OnDataForStream(1, _));
4345   EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
4346   EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
4347   EXPECT_CALL(visitor, OnDataForStream(1, _));
4348   EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
4349   EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
4350   EXPECT_CALL(visitor, OnDataForStream(1, _));
4351   EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
4352   EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
4353   // No further frame data or headers are delivered.
4354 
4355   const int64_t result = adapter->ProcessBytes(frames);
4356   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4357 
4358   EXPECT_TRUE(adapter->want_write());
4359 
4360   // No SETTINGS ack is written.
4361   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
4362   EXPECT_CALL(
4363       visitor,
4364       OnFrameSent(GOAWAY, 0, _, 0x0,
4365                   static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
4366 
4367   int send_result = adapter->Send();
4368   EXPECT_EQ(0, send_result);
4369   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
4370 }
4371 
TEST(NgHttp2AdapterTest,ClientDisobeysConnectionFlowControlWithOneDataFrame)4372 TEST(NgHttp2AdapterTest, ClientDisobeysConnectionFlowControlWithOneDataFrame) {
4373   DataSavingVisitor visitor;
4374   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4375 
4376   // Allow the client to send a DATA frame that exceeds the connection flow
4377   // control window.
4378   const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
4379   adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
4380 
4381   const std::string initial_frames =
4382       TestFrameSequence()
4383           .ClientPreface()
4384           .Headers(1,
4385                    {{":method", "POST"},
4386                     {":scheme", "https"},
4387                     {":authority", "example.com"},
4388                     {":path", "/this/is/request/one"}},
4389                    /*fin=*/false)
4390           .Serialize();
4391 
4392   testing::InSequence s;
4393 
4394   // Client preface (empty SETTINGS)
4395   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4396   EXPECT_CALL(visitor, OnSettingsStart());
4397   EXPECT_CALL(visitor, OnSettingsEnd());
4398 
4399   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4400   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4401   EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
4402   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4403 
4404   int64_t process_result = adapter->ProcessBytes(initial_frames);
4405   EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
4406 
4407   EXPECT_TRUE(adapter->want_write());
4408 
4409   // Outbound SETTINGS containing MAX_FRAME_SIZE.
4410   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
4411   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
4412 
4413   // Ack of client's initial settings.
4414   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
4415   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
4416 
4417   int send_result = adapter->Send();
4418   EXPECT_EQ(0, send_result);
4419   EXPECT_THAT(visitor.data(),
4420               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
4421   visitor.Clear();
4422 
4423   // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
4424   // overflow the connection-level window. The result should be a GOAWAY.
4425   const std::string overflow_frames =
4426       TestFrameSequence()
4427           .SettingsAck()
4428           .Data(1, std::string(window_overflow_bytes, 'a'))
4429           .Serialize();
4430 
4431   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
4432   EXPECT_CALL(visitor, OnSettingsAck());
4433   EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
4434   EXPECT_CALL(visitor, OnBeginDataForStream(1, window_overflow_bytes));
4435   // No further frame data is delivered.
4436 
4437   process_result = adapter->ProcessBytes(overflow_frames);
4438   EXPECT_EQ(overflow_frames.size(), static_cast<size_t>(process_result));
4439 
4440   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
4441   EXPECT_CALL(
4442       visitor,
4443       OnFrameSent(GOAWAY, 0, _, 0x0,
4444                   static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
4445 
4446   send_result = adapter->Send();
4447   EXPECT_EQ(0, send_result);
4448   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
4449 }
4450 
TEST(NgHttp2AdapterTest,ClientDisobeysConnectionFlowControlAcrossReads)4451 TEST(NgHttp2AdapterTest, ClientDisobeysConnectionFlowControlAcrossReads) {
4452   DataSavingVisitor visitor;
4453   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4454 
4455   // Allow the client to send a DATA frame that exceeds the connection flow
4456   // control window.
4457   const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
4458   adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
4459 
4460   const std::string initial_frames =
4461       TestFrameSequence()
4462           .ClientPreface()
4463           .Headers(1,
4464                    {{":method", "POST"},
4465                     {":scheme", "https"},
4466                     {":authority", "example.com"},
4467                     {":path", "/this/is/request/one"}},
4468                    /*fin=*/false)
4469           .Serialize();
4470 
4471   testing::InSequence s;
4472 
4473   // Client preface (empty SETTINGS)
4474   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4475   EXPECT_CALL(visitor, OnSettingsStart());
4476   EXPECT_CALL(visitor, OnSettingsEnd());
4477 
4478   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4479   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4480   EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
4481   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4482 
4483   int64_t process_result = adapter->ProcessBytes(initial_frames);
4484   EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
4485 
4486   EXPECT_TRUE(adapter->want_write());
4487 
4488   // Outbound SETTINGS containing MAX_FRAME_SIZE.
4489   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
4490   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
4491 
4492   // Ack of client's initial settings.
4493   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
4494   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
4495 
4496   int send_result = adapter->Send();
4497   EXPECT_EQ(0, send_result);
4498   EXPECT_THAT(visitor.data(),
4499               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
4500   visitor.Clear();
4501 
4502   // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
4503   // overflow the connection-level window. The result should be a GOAWAY, but
4504   // because the processing is split across several calls, nghttp2 instead
4505   // delivers the data payloads (which the visitor then consumes). This is a bug
4506   // in nghttp2, which should recognize the flow control error.
4507   const std::string overflow_frames =
4508       TestFrameSequence()
4509           .SettingsAck()
4510           .Data(1, std::string(window_overflow_bytes, 'a'))
4511           .Serialize();
4512 
4513   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
4514   EXPECT_CALL(visitor, OnSettingsAck());
4515   EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
4516   EXPECT_CALL(visitor, OnBeginDataForStream(1, window_overflow_bytes));
4517   // BUG: The visitor should not have received the data.
4518   EXPECT_CALL(visitor, OnDataForStream(1, _))
4519       .WillRepeatedly(
4520           [&adapter](Http2StreamId stream_id, absl::string_view data) {
4521             adapter->MarkDataConsumedForStream(stream_id, data.size());
4522             return true;
4523           });
4524 
4525   const size_t chunk_length = 16384;
4526   ASSERT_GE(overflow_frames.size(), chunk_length);
4527   absl::string_view remaining = overflow_frames;
4528   while (!remaining.empty()) {
4529     absl::string_view chunk = remaining.substr(0, chunk_length);
4530     process_result = adapter->ProcessBytes(chunk);
4531     EXPECT_EQ(chunk.length(), static_cast<size_t>(process_result));
4532 
4533     remaining.remove_prefix(chunk.length());
4534   }
4535 
4536   EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
4537   EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
4538   EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 1, 4, 0x0));
4539   EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 1, 4, 0x0, 0));
4540 
4541   send_result = adapter->Send();
4542   EXPECT_EQ(0, send_result);
4543   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::WINDOW_UPDATE,
4544                                             SpdyFrameType::WINDOW_UPDATE}));
4545 }
4546 
TEST(NgHttp2AdapterTest,ClientDisobeysStreamFlowControl)4547 TEST(NgHttp2AdapterTest, ClientDisobeysStreamFlowControl) {
4548   DataSavingVisitor visitor;
4549   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4550 
4551   const std::string frames = TestFrameSequence()
4552                                  .ClientPreface()
4553                                  .Headers(1,
4554                                           {{":method", "POST"},
4555                                            {":scheme", "https"},
4556                                            {":authority", "example.com"},
4557                                            {":path", "/this/is/request/one"},
4558                                            {"accept", "some bogus value!"}},
4559                                           /*fin=*/false)
4560                                  .Serialize();
4561   const std::string more_frames = TestFrameSequence()
4562                                       // 70000 bytes of data
4563                                       .Data(1, std::string(16384, 'a'))
4564                                       .Data(1, std::string(16384, 'a'))
4565                                       .Data(1, std::string(16384, 'a'))
4566                                       .Data(1, std::string(16384, 'a'))
4567                                       .Data(1, std::string(4464, 'a'))
4568                                       .Serialize();
4569 
4570   testing::InSequence s;
4571   // Client preface (empty SETTINGS)
4572   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4573   EXPECT_CALL(visitor, OnSettingsStart());
4574   EXPECT_CALL(visitor, OnSettingsEnd());
4575 
4576   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4577   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4578   EXPECT_CALL(visitor, OnHeaderForStream).Times(5);
4579   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4580 
4581   int64_t result = adapter->ProcessBytes(frames);
4582   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4583 
4584   adapter->SubmitWindowUpdate(0, 20000);
4585 
4586   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
4587   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
4588   EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
4589   EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
4590 
4591   int send_result = adapter->Send();
4592   EXPECT_EQ(0, send_result);
4593   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
4594                                             SpdyFrameType::WINDOW_UPDATE}));
4595   visitor.Clear();
4596 
4597   EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
4598   EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
4599   EXPECT_CALL(visitor, OnDataForStream(1, _));
4600   EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
4601   EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
4602   EXPECT_CALL(visitor, OnDataForStream(1, _));
4603   EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
4604   EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
4605   EXPECT_CALL(visitor, OnDataForStream(1, _));
4606   EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
4607   EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
4608   EXPECT_CALL(visitor, OnDataForStream(1, _));
4609   // No further frame data or headers for stream 1 are delivered.
4610 
4611   result = adapter->ProcessBytes(more_frames);
4612   EXPECT_EQ(more_frames.size(), static_cast<size_t>(result));
4613 
4614   EXPECT_TRUE(adapter->want_write());
4615   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
4616   EXPECT_CALL(
4617       visitor,
4618       OnFrameSent(RST_STREAM, 1, 4, 0x0,
4619                   static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
4620   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::FLOW_CONTROL_ERROR));
4621 
4622   send_result = adapter->Send();
4623   EXPECT_EQ(0, send_result);
4624   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
4625 }
4626 
TEST(NgHttp2AdapterTest,ServerErrorWhileHandlingHeaders)4627 TEST(NgHttp2AdapterTest, ServerErrorWhileHandlingHeaders) {
4628   DataSavingVisitor visitor;
4629   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4630 
4631   const std::string frames = TestFrameSequence()
4632                                  .ClientPreface()
4633                                  .Headers(1,
4634                                           {{":method", "POST"},
4635                                            {":scheme", "https"},
4636                                            {":authority", "example.com"},
4637                                            {":path", "/this/is/request/one"},
4638                                            {"accept", "some bogus value!"}},
4639                                           /*fin=*/false)
4640                                  .WindowUpdate(1, 2000)
4641                                  .Data(1, "This is the request body.")
4642                                  .WindowUpdate(0, 2000)
4643                                  .Serialize();
4644   testing::InSequence s;
4645 
4646   // Client preface (empty SETTINGS)
4647   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4648   EXPECT_CALL(visitor, OnSettingsStart());
4649   EXPECT_CALL(visitor, OnSettingsEnd());
4650 
4651   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4652   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4653   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
4654   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
4655   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
4656   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
4657   EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
4658       .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
4659   EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
4660   EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
4661   // DATA frame is not delivered to the visitor.
4662   EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
4663   EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
4664 
4665   const int64_t result = adapter->ProcessBytes(frames);
4666   EXPECT_EQ(frames.size(), result);
4667 
4668   EXPECT_TRUE(adapter->want_write());
4669 
4670   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
4671   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
4672   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
4673   EXPECT_CALL(visitor,
4674               OnFrameSent(RST_STREAM, 1, 4, 0x0,
4675                           static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
4676   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
4677 
4678   int send_result = adapter->Send();
4679   // Some bytes should have been serialized.
4680   EXPECT_EQ(0, send_result);
4681   // SETTINGS ack
4682   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
4683                                             SpdyFrameType::RST_STREAM}));
4684 }
4685 
TEST(NgHttp2AdapterTest,ServerErrorWhileHandlingHeadersDropsFrames)4686 TEST(NgHttp2AdapterTest, ServerErrorWhileHandlingHeadersDropsFrames) {
4687   DataSavingVisitor visitor;
4688   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4689 
4690   const std::string frames = TestFrameSequence()
4691                                  .ClientPreface()
4692                                  .Headers(1,
4693                                           {{":method", "POST"},
4694                                            {":scheme", "https"},
4695                                            {":authority", "example.com"},
4696                                            {":path", "/this/is/request/one"},
4697                                            {"accept", "some bogus value!"}},
4698                                           /*fin=*/false)
4699                                  .WindowUpdate(1, 2000)
4700                                  .Data(1, "This is the request body.")
4701                                  .Metadata(1, "This is the request metadata.")
4702                                  .RstStream(1, Http2ErrorCode::CANCEL)
4703                                  .WindowUpdate(0, 2000)
4704                                  .Headers(3,
4705                                           {{":method", "GET"},
4706                                            {":scheme", "https"},
4707                                            {":authority", "example.com"},
4708                                            {":path", "/this/is/request/two"}},
4709                                           /*fin=*/false)
4710                                  .Metadata(3, "This is the request metadata.",
4711                                            /*multiple_frames=*/true)
4712                                  .Serialize();
4713   testing::InSequence s;
4714 
4715   // Client preface (empty SETTINGS)
4716   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4717   EXPECT_CALL(visitor, OnSettingsStart());
4718   EXPECT_CALL(visitor, OnSettingsEnd());
4719 
4720   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4721   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4722   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
4723   EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
4724       .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
4725   // For the RST_STREAM-marked stream, the control frames and METADATA frame but
4726   // not the DATA frame are delivered to the visitor.
4727   EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
4728   EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
4729   EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
4730   EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
4731   EXPECT_CALL(visitor, OnMetadataForStream(1, _));
4732   EXPECT_CALL(visitor, OnMetadataEndForStream(1));
4733   EXPECT_CALL(visitor, OnFrameHeader(1, 4, RST_STREAM, 0));
4734   EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::CANCEL));
4735   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::CANCEL));
4736   EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
4737   EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
4738   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
4739   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
4740   EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
4741   EXPECT_CALL(visitor, OnEndHeadersForStream(3));
4742   EXPECT_CALL(visitor, OnFrameHeader(3, _, kMetadataFrameType, 0));
4743   EXPECT_CALL(visitor, OnBeginMetadataForStream(3, _));
4744   EXPECT_CALL(visitor, OnMetadataForStream(3, "This is the re"))
4745       .WillOnce(testing::DoAll(testing::InvokeWithoutArgs([&adapter]() {
4746                                  adapter->SubmitRst(
4747                                      3, Http2ErrorCode::REFUSED_STREAM);
4748                                }),
4749                                testing::Return(true)));
4750   // The rest of the metadata is still delivered to the visitor.
4751   EXPECT_CALL(visitor, OnFrameHeader(3, _, kMetadataFrameType, 4));
4752   EXPECT_CALL(visitor, OnBeginMetadataForStream(3, _));
4753   EXPECT_CALL(visitor, OnMetadataForStream(3, "quest metadata."));
4754   EXPECT_CALL(visitor, OnMetadataEndForStream(3));
4755 
4756   const int64_t result = adapter->ProcessBytes(frames);
4757   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4758 
4759   EXPECT_TRUE(adapter->want_write());
4760 
4761   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
4762   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
4763   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
4764   EXPECT_CALL(visitor,
4765               OnFrameSent(RST_STREAM, 1, 4, 0x0,
4766                           static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
4767   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, 4, 0x0));
4768   EXPECT_CALL(visitor,
4769               OnFrameSent(RST_STREAM, 3, 4, 0x0,
4770                           static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
4771   EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::REFUSED_STREAM));
4772 
4773   int send_result = adapter->Send();
4774   // Some bytes should have been serialized.
4775   EXPECT_EQ(0, send_result);
4776   EXPECT_THAT(visitor.data(),
4777               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
4778                             SpdyFrameType::RST_STREAM}));
4779 }
4780 
TEST(NgHttp2AdapterTest,ServerConnectionErrorWhileHandlingHeaders)4781 TEST(NgHttp2AdapterTest, ServerConnectionErrorWhileHandlingHeaders) {
4782   DataSavingVisitor visitor;
4783   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4784 
4785   const std::string frames = TestFrameSequence()
4786                                  .ClientPreface()
4787                                  .Headers(1,
4788                                           {{":method", "POST"},
4789                                            {":scheme", "https"},
4790                                            {":authority", "example.com"},
4791                                            {":path", "/this/is/request/one"},
4792                                            {"Accept", "uppercase, oh boy!"}},
4793                                           /*fin=*/false)
4794                                  .WindowUpdate(1, 2000)
4795                                  .Data(1, "This is the request body.")
4796                                  .WindowUpdate(0, 2000)
4797                                  .Serialize();
4798   testing::InSequence s;
4799 
4800   // Client preface (empty SETTINGS)
4801   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4802   EXPECT_CALL(visitor, OnSettingsStart());
4803   EXPECT_CALL(visitor, OnSettingsEnd());
4804 
4805   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4806   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4807   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
4808   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
4809   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
4810   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
4811   EXPECT_CALL(visitor, OnErrorDebug);
4812   EXPECT_CALL(
4813       visitor,
4814       OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader))
4815       .WillOnce(testing::Return(false));
4816   // Translation to nghttp2 treats this error as a general parsing error.
4817   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
4818 
4819   const int64_t result = adapter->ProcessBytes(frames);
4820   EXPECT_EQ(result, NGHTTP2_ERR_CALLBACK_FAILURE);
4821 
4822   EXPECT_TRUE(adapter->want_write());
4823 
4824   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
4825   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
4826   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
4827   EXPECT_CALL(visitor,
4828               OnFrameSent(RST_STREAM, 1, 4, 0x0,
4829                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
4830   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
4831 
4832   int send_result = adapter->Send();
4833   // Some bytes should have been serialized.
4834   EXPECT_EQ(0, send_result);
4835   // SETTINGS ack and RST_STREAM
4836   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
4837                                             SpdyFrameType::RST_STREAM}));
4838 }
4839 
TEST(NgHttp2AdapterTest,ServerErrorAfterHandlingHeaders)4840 TEST(NgHttp2AdapterTest, ServerErrorAfterHandlingHeaders) {
4841   DataSavingVisitor visitor;
4842   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4843 
4844   const std::string frames = TestFrameSequence()
4845                                  .ClientPreface()
4846                                  .Headers(1,
4847                                           {{":method", "POST"},
4848                                            {":scheme", "https"},
4849                                            {":authority", "example.com"},
4850                                            {":path", "/this/is/request/one"}},
4851                                           /*fin=*/false)
4852                                  .WindowUpdate(1, 2000)
4853                                  .Data(1, "This is the request body.")
4854                                  .WindowUpdate(0, 2000)
4855                                  .Serialize();
4856   testing::InSequence s;
4857 
4858   // Client preface (empty SETTINGS)
4859   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4860   EXPECT_CALL(visitor, OnSettingsStart());
4861   EXPECT_CALL(visitor, OnSettingsEnd());
4862 
4863   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4864   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4865   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
4866   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
4867   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
4868   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
4869   EXPECT_CALL(visitor, OnEndHeadersForStream(1))
4870       .WillOnce(testing::Return(false));
4871   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
4872 
4873   const int64_t result = adapter->ProcessBytes(frames);
4874   EXPECT_EQ(-902, result);
4875 
4876   EXPECT_TRUE(adapter->want_write());
4877 
4878   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
4879   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
4880 
4881   int send_result = adapter->Send();
4882   // Some bytes should have been serialized.
4883   EXPECT_EQ(0, send_result);
4884   // SETTINGS ack
4885   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
4886 }
4887 
4888 // Exercises the case when a visitor chooses to reject a frame based solely on
4889 // the frame header, which is a fatal error for the connection.
TEST(NgHttp2AdapterTest,ServerRejectsFrameHeader)4890 TEST(NgHttp2AdapterTest, ServerRejectsFrameHeader) {
4891   DataSavingVisitor visitor;
4892   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4893 
4894   const std::string frames = TestFrameSequence()
4895                                  .ClientPreface()
4896                                  .Ping(64)
4897                                  .Headers(1,
4898                                           {{":method", "POST"},
4899                                            {":scheme", "https"},
4900                                            {":authority", "example.com"},
4901                                            {":path", "/this/is/request/one"}},
4902                                           /*fin=*/false)
4903                                  .WindowUpdate(1, 2000)
4904                                  .Data(1, "This is the request body.")
4905                                  .WindowUpdate(0, 2000)
4906                                  .Serialize();
4907   testing::InSequence s;
4908 
4909   // Client preface (empty SETTINGS)
4910   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4911   EXPECT_CALL(visitor, OnSettingsStart());
4912   EXPECT_CALL(visitor, OnSettingsEnd());
4913 
4914   EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0))
4915       .WillOnce(testing::Return(false));
4916   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
4917 
4918   const int64_t result = adapter->ProcessBytes(frames);
4919   EXPECT_EQ(-902, result);
4920 
4921   EXPECT_TRUE(adapter->want_write());
4922 
4923   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
4924   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
4925 
4926   int send_result = adapter->Send();
4927   // Some bytes should have been serialized.
4928   EXPECT_EQ(0, send_result);
4929   // SETTINGS ack
4930   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
4931 }
4932 
TEST(NgHttp2AdapterTest,ServerRejectsBeginningOfData)4933 TEST(NgHttp2AdapterTest, ServerRejectsBeginningOfData) {
4934   DataSavingVisitor visitor;
4935   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4936 
4937   const std::string frames = TestFrameSequence()
4938                                  .ClientPreface()
4939                                  .Headers(1,
4940                                           {{":method", "POST"},
4941                                            {":scheme", "https"},
4942                                            {":authority", "example.com"},
4943                                            {":path", "/this/is/request/one"}},
4944                                           /*fin=*/false)
4945                                  .Data(1, "This is the request body.")
4946                                  .Headers(3,
4947                                           {{":method", "GET"},
4948                                            {":scheme", "http"},
4949                                            {":authority", "example.com"},
4950                                            {":path", "/this/is/request/two"}},
4951                                           /*fin=*/true)
4952                                  .RstStream(3, Http2ErrorCode::CANCEL)
4953                                  .Ping(47)
4954                                  .Serialize();
4955   testing::InSequence s;
4956 
4957   // Client preface (empty SETTINGS)
4958   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4959   EXPECT_CALL(visitor, OnSettingsStart());
4960   EXPECT_CALL(visitor, OnSettingsEnd());
4961 
4962   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4963   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4964   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
4965   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
4966   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
4967   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
4968   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4969   EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
4970   EXPECT_CALL(visitor, OnBeginDataForStream(1, 25))
4971       .WillOnce(testing::Return(false));
4972   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
4973 
4974   const int64_t result = adapter->ProcessBytes(frames);
4975   EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, result);
4976 
4977   EXPECT_TRUE(adapter->want_write());
4978 
4979   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
4980   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
4981 
4982   int send_result = adapter->Send();
4983   // Some bytes should have been serialized.
4984   EXPECT_EQ(0, send_result);
4985   // SETTINGS ack.
4986   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
4987 }
4988 
TEST(NgHttp2AdapterTest,ServerRejectsStreamData)4989 TEST(NgHttp2AdapterTest, ServerRejectsStreamData) {
4990   DataSavingVisitor visitor;
4991   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
4992 
4993   const std::string frames = TestFrameSequence()
4994                                  .ClientPreface()
4995                                  .Headers(1,
4996                                           {{":method", "POST"},
4997                                            {":scheme", "https"},
4998                                            {":authority", "example.com"},
4999                                            {":path", "/this/is/request/one"}},
5000                                           /*fin=*/false)
5001                                  .Data(1, "This is the request body.")
5002                                  .Headers(3,
5003                                           {{":method", "GET"},
5004                                            {":scheme", "http"},
5005                                            {":authority", "example.com"},
5006                                            {":path", "/this/is/request/two"}},
5007                                           /*fin=*/true)
5008                                  .RstStream(3, Http2ErrorCode::CANCEL)
5009                                  .Ping(47)
5010                                  .Serialize();
5011   testing::InSequence s;
5012 
5013   // Client preface (empty SETTINGS)
5014   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5015   EXPECT_CALL(visitor, OnSettingsStart());
5016   EXPECT_CALL(visitor, OnSettingsEnd());
5017 
5018   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5019   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5020   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
5021   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5022   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5023   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5024   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5025   EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
5026   EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
5027   EXPECT_CALL(visitor, OnDataForStream(1, _)).WillOnce(testing::Return(false));
5028   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
5029 
5030   const int64_t result = adapter->ProcessBytes(frames);
5031   EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, result);
5032 
5033   EXPECT_TRUE(adapter->want_write());
5034 
5035   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
5036   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
5037 
5038   int send_result = adapter->Send();
5039   // Some bytes should have been serialized.
5040   EXPECT_EQ(0, send_result);
5041   // SETTINGS ack.
5042   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
5043 }
5044 
TEST(NgHttp2AdapterTest,ServerReceivesTooLargeHeader)5045 TEST(NgHttp2AdapterTest, ServerReceivesTooLargeHeader) {
5046   DataSavingVisitor visitor;
5047   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5048 
5049   // nghttp2 will accept a maximum of 64kB of huffman encoded data per header
5050   // field.
5051   const std::string too_large_value = std::string(80 * 1024, 'q');
5052   const std::string frames = TestFrameSequence()
5053                                  .ClientPreface()
5054                                  .Headers(1,
5055                                           {{":method", "POST"},
5056                                            {":scheme", "https"},
5057                                            {":authority", "example.com"},
5058                                            {":path", "/this/is/request/one"},
5059                                            {"x-toobig", too_large_value}},
5060                                           /*fin=*/false)
5061                                  .Serialize();
5062   testing::InSequence s;
5063 
5064   // Client preface (empty SETTINGS)
5065   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5066   EXPECT_CALL(visitor, OnSettingsStart());
5067   EXPECT_CALL(visitor, OnSettingsEnd());
5068 
5069   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0));
5070   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5071   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
5072   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5073   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5074   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5075   // Further header processing is skipped, as the header field is too large.
5076 
5077   const int64_t result = adapter->ProcessBytes(frames);
5078   EXPECT_EQ(frames.size(), result);
5079 
5080   EXPECT_TRUE(adapter->want_write());
5081 
5082   // Since nghttp2 opted not to process the header, it generates a GOAWAY with
5083   // error code COMPRESSION_ERROR.
5084   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, 8, 0x0));
5085   EXPECT_CALL(visitor,
5086               OnFrameSent(GOAWAY, 0, 8, 0x0,
5087                           static_cast<int>(Http2ErrorCode::COMPRESSION_ERROR)));
5088 
5089   int send_result = adapter->Send();
5090   // Some bytes should have been serialized.
5091   EXPECT_EQ(0, send_result);
5092   // GOAWAY.
5093   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
5094 }
5095 
TEST(NgHttp2AdapterTest,ServerReceivesInvalidAuthority)5096 TEST(NgHttp2AdapterTest, ServerReceivesInvalidAuthority) {
5097   DataSavingVisitor visitor;
5098   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5099 
5100   const std::string frames = TestFrameSequence()
5101                                  .ClientPreface()
5102                                  .Headers(1,
5103                                           {{":method", "POST"},
5104                                            {":scheme", "https"},
5105                                            {":authority", "ex|ample.com"},
5106                                            {":path", "/this/is/request/one"}},
5107                                           /*fin=*/false)
5108                                  .Serialize();
5109   testing::InSequence s;
5110 
5111   // Client preface (empty SETTINGS)
5112   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5113   EXPECT_CALL(visitor, OnSettingsStart());
5114   EXPECT_CALL(visitor, OnSettingsEnd());
5115 
5116   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5117   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5118   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
5119   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5120   EXPECT_CALL(
5121       visitor,
5122       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
5123                    "stream: 1, name: [:authority], value: [ex|ample.com]"));
5124   EXPECT_CALL(
5125       visitor,
5126       OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
5127 
5128   const int64_t result = adapter->ProcessBytes(frames);
5129   EXPECT_EQ(frames.size(), result);
5130 
5131   EXPECT_TRUE(adapter->want_write());
5132 
5133   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
5134   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0x0));
5135   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
5136   EXPECT_CALL(visitor,
5137               OnFrameSent(RST_STREAM, 1, 4, 0x0,
5138                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
5139   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
5140 
5141   int send_result = adapter->Send();
5142   EXPECT_EQ(0, send_result);
5143   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
5144                                             SpdyFrameType::RST_STREAM}));
5145 }
5146 
TEST(NgHttpAdapterTest,ServerReceivesGoAway)5147 TEST(NgHttpAdapterTest, ServerReceivesGoAway) {
5148   DataSavingVisitor visitor;
5149   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5150 
5151   const std::string frames = TestFrameSequence()
5152                                  .ClientPreface()
5153                                  .Headers(1,
5154                                           {{":method", "GET"},
5155                                            {":scheme", "https"},
5156                                            {":authority", "example.com"},
5157                                            {":path", "/this/is/request/one"}},
5158                                           /*fin=*/true)
5159                                  .GoAway(0, Http2ErrorCode::HTTP2_NO_ERROR, "")
5160                                  .Serialize();
5161   testing::InSequence s;
5162 
5163   // Client preface (empty SETTINGS)
5164   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5165   EXPECT_CALL(visitor, OnSettingsStart());
5166   EXPECT_CALL(visitor, OnSettingsEnd());
5167 
5168   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
5169   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5170   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
5171   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5172   EXPECT_CALL(visitor, OnEndStream(1));
5173   EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0x0));
5174   EXPECT_CALL(visitor, OnGoAway(0, Http2ErrorCode::HTTP2_NO_ERROR, ""));
5175 
5176   const int64_t result = adapter->ProcessBytes(frames);
5177   EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
5178 
5179   // The server should still be able to send a response after receiving a GOAWAY
5180   // with a lower last-stream-ID field, as the stream was client-initiated.
5181   const int submit_result =
5182       adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}),
5183                               /*data_source=*/nullptr);
5184   ASSERT_EQ(0, submit_result);
5185 
5186   EXPECT_TRUE(adapter->want_write());
5187 
5188   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
5189   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0x0));
5190   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
5191   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
5192   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
5193 
5194   int send_result = adapter->Send();
5195   EXPECT_EQ(0, send_result);
5196   EXPECT_THAT(visitor.data(),
5197               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
5198 }
5199 
TEST(NgHttp2AdapterTest,ServerSubmitResponse)5200 TEST(NgHttp2AdapterTest, ServerSubmitResponse) {
5201   DataSavingVisitor visitor;
5202   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5203   EXPECT_FALSE(adapter->want_write());
5204 
5205   const std::string frames = TestFrameSequence()
5206                                  .ClientPreface()
5207                                  .Headers(1,
5208                                           {{":method", "GET"},
5209                                            {":scheme", "https"},
5210                                            {":authority", "example.com"},
5211                                            {":path", "/this/is/request/one"}},
5212                                           /*fin=*/true)
5213                                  .Serialize();
5214   testing::InSequence s;
5215 
5216   const char* kSentinel1 = "arbitrary pointer 1";
5217 
5218   // Client preface (empty SETTINGS)
5219   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5220   EXPECT_CALL(visitor, OnSettingsStart());
5221   EXPECT_CALL(visitor, OnSettingsEnd());
5222   // Stream 1
5223   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
5224   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5225   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
5226   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5227   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5228   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5229   EXPECT_CALL(visitor, OnEndHeadersForStream(1))
5230       .WillOnce(testing::InvokeWithoutArgs([&adapter, kSentinel1]() {
5231         adapter->SetStreamUserData(1, const_cast<char*>(kSentinel1));
5232         return true;
5233       }));
5234   EXPECT_CALL(visitor, OnEndStream(1));
5235 
5236   const int64_t result = adapter->ProcessBytes(frames);
5237   EXPECT_EQ(frames.size(), result);
5238 
5239   EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
5240 
5241   // Server will want to send a SETTINGS ack.
5242   EXPECT_TRUE(adapter->want_write());
5243 
5244   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
5245   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
5246 
5247   int send_result = adapter->Send();
5248   EXPECT_EQ(0, send_result);
5249   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
5250   visitor.Clear();
5251 
5252   EXPECT_EQ(0, adapter->GetHpackEncoderDynamicTableSize());
5253 
5254   EXPECT_FALSE(adapter->want_write());
5255   const absl::string_view kBody = "This is an example response body.";
5256   // A data fin is not sent so that the stream remains open, and the flow
5257   // control state can be verified.
5258   auto body1 = std::make_unique<TestDataFrameSource>(visitor, false);
5259   body1->AppendPayload(kBody);
5260   int submit_result = adapter->SubmitResponse(
5261       1,
5262       ToHeaders({{":status", "404"},
5263                  {"x-comment", "I have no idea what you're talking about."}}),
5264       std::move(body1));
5265   EXPECT_EQ(submit_result, 0);
5266   EXPECT_TRUE(adapter->want_write());
5267 
5268   // Stream user data should have been set successfully after receiving headers.
5269   EXPECT_EQ(kSentinel1, adapter->GetStreamUserData(1));
5270   adapter->SetStreamUserData(1, nullptr);
5271   EXPECT_EQ(nullptr, adapter->GetStreamUserData(1));
5272 
5273   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
5274   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
5275   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
5276 
5277   send_result = adapter->Send();
5278   EXPECT_EQ(0, send_result);
5279 
5280   EXPECT_THAT(visitor.data(),
5281               EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
5282   EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
5283   EXPECT_FALSE(adapter->want_write());
5284 
5285   // Some data was sent, so the remaining send window size should be less than
5286   // the default.
5287   EXPECT_LT(adapter->GetStreamSendWindowSize(1), kInitialFlowControlWindowSize);
5288   EXPECT_GT(adapter->GetStreamSendWindowSize(1), 0);
5289   // Send window for a nonexistent stream is not available.
5290   EXPECT_EQ(adapter->GetStreamSendWindowSize(3), -1);
5291 
5292   EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 0);
5293 }
5294 
TEST(NgHttp2AdapterTest,ServerSubmitResponseWithResetFromClient)5295 TEST(NgHttp2AdapterTest, ServerSubmitResponseWithResetFromClient) {
5296   DataSavingVisitor visitor;
5297   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5298   EXPECT_FALSE(adapter->want_write());
5299 
5300   const std::string frames = TestFrameSequence()
5301                                  .ClientPreface()
5302                                  .Headers(1,
5303                                           {{":method", "GET"},
5304                                            {":scheme", "https"},
5305                                            {":authority", "example.com"},
5306                                            {":path", "/this/is/request/one"}},
5307                                           /*fin=*/true)
5308                                  .Serialize();
5309   testing::InSequence s;
5310 
5311   // Client preface (empty SETTINGS)
5312   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5313   EXPECT_CALL(visitor, OnSettingsStart());
5314   EXPECT_CALL(visitor, OnSettingsEnd());
5315   // Stream 1
5316   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
5317   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5318   EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
5319   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5320   EXPECT_CALL(visitor, OnEndStream(1));
5321 
5322   const int64_t result = adapter->ProcessBytes(frames);
5323   EXPECT_EQ(frames.size(), result);
5324 
5325   EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
5326 
5327   // Server will want to send a SETTINGS ack.
5328   EXPECT_TRUE(adapter->want_write());
5329 
5330   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
5331   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
5332 
5333   int send_result = adapter->Send();
5334   EXPECT_EQ(0, send_result);
5335   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
5336   visitor.Clear();
5337 
5338   EXPECT_FALSE(adapter->want_write());
5339   const absl::string_view kBody = "This is an example response body.";
5340   auto body1 = std::make_unique<TestDataFrameSource>(visitor, true);
5341   body1->AppendPayload(kBody);
5342   int submit_result = adapter->SubmitResponse(
5343       1,
5344       ToHeaders({{":status", "404"},
5345                  {"x-comment", "I have no idea what you're talking about."}}),
5346       std::move(body1));
5347   EXPECT_EQ(submit_result, 0);
5348   EXPECT_TRUE(adapter->want_write());
5349 
5350   // Client resets the stream before the server can send the response.
5351   const std::string reset =
5352       TestFrameSequence().RstStream(1, Http2ErrorCode::CANCEL).Serialize();
5353   EXPECT_CALL(visitor, OnFrameHeader(1, 4, RST_STREAM, 0));
5354   EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::CANCEL));
5355   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::CANCEL));
5356   const int64_t reset_result = adapter->ProcessBytes(reset);
5357   EXPECT_EQ(reset.size(), static_cast<size_t>(reset_result));
5358 
5359   // Outbound HEADERS and DATA are dropped.
5360   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, _)).Times(0);
5361   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, _, _)).Times(0);
5362   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, _, _)).Times(0);
5363 
5364   send_result = adapter->Send();
5365   EXPECT_EQ(0, send_result);
5366 
5367   EXPECT_THAT(visitor.data(), testing::IsEmpty());
5368 }
5369 
5370 // Should also test: client attempts shutdown, server attempts shutdown after an
5371 // explicit GOAWAY.
TEST(NgHttp2AdapterTest,ServerSendsShutdown)5372 TEST(NgHttp2AdapterTest, ServerSendsShutdown) {
5373   DataSavingVisitor visitor;
5374   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5375 
5376   const std::string frames = TestFrameSequence()
5377                                  .ClientPreface()
5378                                  .Headers(1,
5379                                           {{":method", "POST"},
5380                                            {":scheme", "https"},
5381                                            {":authority", "example.com"},
5382                                            {":path", "/this/is/request/one"}},
5383                                           /*fin=*/false)
5384                                  .Serialize();
5385   testing::InSequence s;
5386 
5387   // Client preface (empty SETTINGS)
5388   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5389   EXPECT_CALL(visitor, OnSettingsStart());
5390   EXPECT_CALL(visitor, OnSettingsEnd());
5391 
5392   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5393   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5394   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
5395   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5396   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5397   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5398   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5399 
5400   const int64_t result = adapter->ProcessBytes(frames);
5401   EXPECT_EQ(frames.size(), result);
5402 
5403   adapter->SubmitShutdownNotice();
5404 
5405   EXPECT_TRUE(adapter->want_write());
5406 
5407   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
5408   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
5409   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
5410   EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
5411 
5412   int send_result = adapter->Send();
5413   EXPECT_EQ(0, send_result);
5414   EXPECT_THAT(visitor.data(),
5415               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
5416 }
5417 
TEST(NgHttp2AdapterTest,ServerSendsTrailers)5418 TEST(NgHttp2AdapterTest, ServerSendsTrailers) {
5419   DataSavingVisitor visitor;
5420   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5421   EXPECT_FALSE(adapter->want_write());
5422 
5423   const std::string frames = TestFrameSequence()
5424                                  .ClientPreface()
5425                                  .Headers(1,
5426                                           {{":method", "GET"},
5427                                            {":scheme", "https"},
5428                                            {":authority", "example.com"},
5429                                            {":path", "/this/is/request/one"}},
5430                                           /*fin=*/true)
5431                                  .Serialize();
5432   testing::InSequence s;
5433 
5434   // Client preface (empty SETTINGS)
5435   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5436   EXPECT_CALL(visitor, OnSettingsStart());
5437   EXPECT_CALL(visitor, OnSettingsEnd());
5438   // Stream 1
5439   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
5440   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5441   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
5442   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5443   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5444   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5445   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5446   EXPECT_CALL(visitor, OnEndStream(1));
5447 
5448   const int64_t result = adapter->ProcessBytes(frames);
5449   EXPECT_EQ(frames.size(), result);
5450 
5451   // Server will want to send a SETTINGS ack.
5452   EXPECT_TRUE(adapter->want_write());
5453 
5454   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
5455   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
5456 
5457   int send_result = adapter->Send();
5458   EXPECT_EQ(0, send_result);
5459   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
5460   visitor.Clear();
5461 
5462   EXPECT_FALSE(adapter->want_write());
5463   const absl::string_view kBody = "This is an example response body.";
5464 
5465   // The body source must indicate that the end of the body is not the end of
5466   // the stream.
5467   auto body1 = std::make_unique<TestDataFrameSource>(visitor, false);
5468   body1->AppendPayload(kBody);
5469   body1->EndData();
5470   int submit_result = adapter->SubmitResponse(
5471       1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
5472       std::move(body1));
5473   EXPECT_EQ(submit_result, 0);
5474   EXPECT_TRUE(adapter->want_write());
5475 
5476   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
5477   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
5478   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
5479 
5480   send_result = adapter->Send();
5481   EXPECT_EQ(0, send_result);
5482   EXPECT_THAT(visitor.data(),
5483               EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
5484   EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
5485   visitor.Clear();
5486   EXPECT_FALSE(adapter->want_write());
5487 
5488   // The body source has been exhausted by the call to Send() above.
5489   int trailer_result = adapter->SubmitTrailer(
5490       1, ToHeaders({{"final-status", "a-ok"},
5491                     {"x-comment", "trailers sure are cool"}}));
5492   ASSERT_EQ(trailer_result, 0);
5493   EXPECT_TRUE(adapter->want_write());
5494 
5495   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
5496   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
5497   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
5498 
5499   send_result = adapter->Send();
5500   EXPECT_EQ(0, send_result);
5501   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
5502 }
5503 
TEST(NgHttp2AdapterTest,ClientSendsContinuation)5504 TEST(NgHttp2AdapterTest, ClientSendsContinuation) {
5505   DataSavingVisitor visitor;
5506   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5507   EXPECT_FALSE(adapter->want_write());
5508 
5509   const std::string frames = TestFrameSequence()
5510                                  .ClientPreface()
5511                                  .Headers(1,
5512                                           {{":method", "GET"},
5513                                            {":scheme", "https"},
5514                                            {":authority", "example.com"},
5515                                            {":path", "/this/is/request/one"}},
5516                                           /*fin=*/true,
5517                                           /*add_continuation=*/true)
5518                                  .Serialize();
5519   testing::InSequence s;
5520 
5521   // Client preface (empty SETTINGS)
5522   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5523   EXPECT_CALL(visitor, OnSettingsStart());
5524   EXPECT_CALL(visitor, OnSettingsEnd());
5525   // Stream 1
5526   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 1));
5527   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5528   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
5529   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5530   EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 4));
5531   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5532   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5533   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5534   EXPECT_CALL(visitor, OnEndStream(1));
5535 
5536   const int64_t result = adapter->ProcessBytes(frames);
5537   EXPECT_EQ(frames.size(), result);
5538 }
5539 
TEST(NgHttp2AdapterTest,ClientSendsMetadataWithContinuation)5540 TEST(NgHttp2AdapterTest, ClientSendsMetadataWithContinuation) {
5541   DataSavingVisitor visitor;
5542   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5543   EXPECT_FALSE(adapter->want_write());
5544 
5545   const std::string frames =
5546       TestFrameSequence()
5547           .ClientPreface()
5548           .Metadata(0, "Example connection metadata in multiple frames", true)
5549           .Headers(1,
5550                    {{":method", "GET"},
5551                     {":scheme", "https"},
5552                     {":authority", "example.com"},
5553                     {":path", "/this/is/request/one"}},
5554                    /*fin=*/false,
5555                    /*add_continuation=*/true)
5556           .Metadata(1,
5557                     "Some stream metadata that's also sent in multiple frames",
5558                     true)
5559           .Serialize();
5560   testing::InSequence s;
5561 
5562   // Client preface (empty SETTINGS)
5563   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5564   EXPECT_CALL(visitor, OnSettingsStart());
5565   EXPECT_CALL(visitor, OnSettingsEnd());
5566   // Metadata on stream 0
5567   EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 0));
5568   EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
5569   EXPECT_CALL(visitor, OnMetadataForStream(0, _));
5570   EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
5571   EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
5572   EXPECT_CALL(visitor, OnMetadataForStream(0, _));
5573   EXPECT_CALL(visitor, OnMetadataEndForStream(0));
5574 
5575   // Stream 1
5576   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0));
5577   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5578   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
5579   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5580   EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 4));
5581   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5582   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5583   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5584   // Metadata on stream 1
5585   EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 0));
5586   EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
5587   EXPECT_CALL(visitor, OnMetadataForStream(1, _));
5588   EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
5589   EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
5590   EXPECT_CALL(visitor, OnMetadataForStream(1, _));
5591   EXPECT_CALL(visitor, OnMetadataEndForStream(1));
5592 
5593   const int64_t result = adapter->ProcessBytes(frames);
5594   EXPECT_EQ(frames.size(), result);
5595   EXPECT_EQ("Example connection metadata in multiple frames",
5596             absl::StrJoin(visitor.GetMetadata(0), ""));
5597   EXPECT_EQ("Some stream metadata that's also sent in multiple frames",
5598             absl::StrJoin(visitor.GetMetadata(1), ""));
5599 }
5600 
TEST(NgHttp2AdapterTest,RepeatedHeaderNames)5601 TEST(NgHttp2AdapterTest, RepeatedHeaderNames) {
5602   DataSavingVisitor visitor;
5603   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5604   EXPECT_FALSE(adapter->want_write());
5605 
5606   const std::string frames = TestFrameSequence()
5607                                  .ClientPreface()
5608                                  .Headers(1,
5609                                           {{":method", "GET"},
5610                                            {":scheme", "https"},
5611                                            {":authority", "example.com"},
5612                                            {":path", "/this/is/request/one"},
5613                                            {"accept", "text/plain"},
5614                                            {"accept", "text/html"}},
5615                                           /*fin=*/true)
5616                                  .Serialize();
5617 
5618   testing::InSequence s;
5619 
5620   // Client preface (empty SETTINGS)
5621   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5622   EXPECT_CALL(visitor, OnSettingsStart());
5623   EXPECT_CALL(visitor, OnSettingsEnd());
5624   // Stream 1
5625   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
5626   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5627   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
5628   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5629   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5630   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5631   EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "text/plain"));
5632   EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "text/html"));
5633   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5634   EXPECT_CALL(visitor, OnEndStream(1));
5635 
5636   int64_t result = adapter->ProcessBytes(frames);
5637   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5638 
5639   const std::vector<Header> headers1 = ToHeaders(
5640       {{":status", "200"}, {"content-length", "10"}, {"content-length", "10"}});
5641   auto body1 = std::make_unique<TestDataFrameSource>(visitor, true);
5642   body1->AppendPayload("perfection");
5643   body1->EndData();
5644 
5645   int submit_result = adapter->SubmitResponse(1, headers1, std::move(body1));
5646   ASSERT_EQ(0, submit_result);
5647 
5648   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
5649   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
5650   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
5651   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
5652   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, 10, 0x1, 0));
5653   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
5654 
5655   int send_result = adapter->Send();
5656   EXPECT_EQ(0, send_result);
5657   EXPECT_THAT(visitor.data(),
5658               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
5659                             SpdyFrameType::DATA}));
5660 }
5661 
TEST(NgHttp2AdapterTest,ServerRespondsToRequestWithTrailers)5662 TEST(NgHttp2AdapterTest, ServerRespondsToRequestWithTrailers) {
5663   DataSavingVisitor visitor;
5664   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5665   EXPECT_FALSE(adapter->want_write());
5666 
5667   const std::string frames =
5668       TestFrameSequence()
5669           .ClientPreface()
5670           .Headers(1, {{":method", "GET"},
5671                        {":scheme", "https"},
5672                        {":authority", "example.com"},
5673                        {":path", "/this/is/request/one"}})
5674           .Data(1, "Example data, woohoo.")
5675           .Serialize();
5676 
5677   testing::InSequence s;
5678 
5679   // Client preface (empty SETTINGS)
5680   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5681   EXPECT_CALL(visitor, OnSettingsStart());
5682   EXPECT_CALL(visitor, OnSettingsEnd());
5683   // Stream 1
5684   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5685   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5686   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
5687   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5688   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5689   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5690   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5691   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
5692   EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
5693   EXPECT_CALL(visitor, OnDataForStream(1, _));
5694 
5695   int64_t result = adapter->ProcessBytes(frames);
5696   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5697 
5698   const std::vector<Header> headers1 = ToHeaders({{":status", "200"}});
5699   auto body1 = std::make_unique<TestDataFrameSource>(visitor, true);
5700   TestDataFrameSource* body1_ptr = body1.get();
5701 
5702   int submit_result = adapter->SubmitResponse(1, headers1, std::move(body1));
5703   ASSERT_EQ(0, submit_result);
5704 
5705   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
5706   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
5707   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
5708   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
5709 
5710   int send_result = adapter->Send();
5711   EXPECT_EQ(0, send_result);
5712   EXPECT_THAT(visitor.data(),
5713               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
5714   visitor.Clear();
5715 
5716   const std::string more_frames =
5717       TestFrameSequence()
5718           .Headers(1, {{"extra-info", "Trailers are weird but good?"}},
5719                    /*fin=*/true)
5720           .Serialize();
5721 
5722   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
5723   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5724   EXPECT_CALL(visitor, OnHeaderForStream(1, "extra-info",
5725                                          "Trailers are weird but good?"));
5726   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5727   EXPECT_CALL(visitor, OnEndStream(1));
5728 
5729   result = adapter->ProcessBytes(more_frames);
5730   EXPECT_EQ(more_frames.size(), static_cast<size_t>(result));
5731 
5732   body1_ptr->EndData();
5733   EXPECT_EQ(true, adapter->ResumeStream(1));
5734 
5735   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, 0, 0x1, 0));
5736   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
5737 
5738   send_result = adapter->Send();
5739   EXPECT_EQ(0, send_result);
5740   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
5741 }
5742 
TEST(NgHttp2AdapterTest,ServerSubmitsResponseWithDataSourceError)5743 TEST(NgHttp2AdapterTest, ServerSubmitsResponseWithDataSourceError) {
5744   DataSavingVisitor visitor;
5745   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5746   EXPECT_FALSE(adapter->want_write());
5747 
5748   const std::string frames = TestFrameSequence()
5749                                  .ClientPreface()
5750                                  .Headers(1,
5751                                           {{":method", "GET"},
5752                                            {":scheme", "https"},
5753                                            {":authority", "example.com"},
5754                                            {":path", "/this/is/request/one"}},
5755                                           /*fin=*/true)
5756                                  .Serialize();
5757   testing::InSequence s;
5758 
5759   // Client preface (empty SETTINGS)
5760   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5761   EXPECT_CALL(visitor, OnSettingsStart());
5762   EXPECT_CALL(visitor, OnSettingsEnd());
5763   // Stream 1
5764   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
5765   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5766   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
5767   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5768   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5769   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5770   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5771   EXPECT_CALL(visitor, OnEndStream(1));
5772 
5773   const int64_t result = adapter->ProcessBytes(frames);
5774   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5775 
5776   auto body1 = std::make_unique<TestDataFrameSource>(visitor, false);
5777   body1->SimulateError();
5778   int submit_result = adapter->SubmitResponse(
5779       1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
5780       std::move(body1));
5781   EXPECT_EQ(submit_result, 0);
5782   EXPECT_TRUE(adapter->want_write());
5783 
5784   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
5785   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
5786   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
5787   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
5788   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
5789   EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, _, 0x0, 2));
5790   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
5791 
5792   int send_result = adapter->Send();
5793   EXPECT_EQ(0, send_result);
5794   EXPECT_THAT(visitor.data(),
5795               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
5796                             SpdyFrameType::RST_STREAM}));
5797   visitor.Clear();
5798   EXPECT_FALSE(adapter->want_write());
5799 
5800   int trailer_result =
5801       adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
5802   // The library does not object to the user queuing trailers, even through the
5803   // stream has already been closed.
5804   EXPECT_EQ(trailer_result, 0);
5805 }
5806 
TEST(NgHttp2AdapterTest,CompleteRequestWithServerResponse)5807 TEST(NgHttp2AdapterTest, CompleteRequestWithServerResponse) {
5808   DataSavingVisitor visitor;
5809   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5810   EXPECT_FALSE(adapter->want_write());
5811 
5812   const std::string frames =
5813       TestFrameSequence()
5814           .ClientPreface()
5815           .Headers(1,
5816                    {{":method", "GET"},
5817                     {":scheme", "https"},
5818                     {":authority", "example.com"},
5819                     {":path", "/this/is/request/one"}},
5820                    /*fin=*/false)
5821           .Data(1, "This is the response body.", /*fin=*/true)
5822           .Serialize();
5823   testing::InSequence s;
5824 
5825   // Client preface (empty SETTINGS)
5826   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5827   EXPECT_CALL(visitor, OnSettingsStart());
5828   EXPECT_CALL(visitor, OnSettingsEnd());
5829   // Stream 1
5830   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5831   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5832   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
5833   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5834   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
5835   EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
5836   EXPECT_CALL(visitor, OnDataForStream(1, _));
5837   EXPECT_CALL(visitor, OnEndStream(1));
5838 
5839   const int64_t result = adapter->ProcessBytes(frames);
5840   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5841 
5842   int submit_result =
5843       adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
5844   EXPECT_EQ(submit_result, 0);
5845   EXPECT_TRUE(adapter->want_write());
5846 
5847   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
5848   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
5849   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
5850   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
5851   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
5852 
5853   int send_result = adapter->Send();
5854   EXPECT_EQ(0, send_result);
5855   EXPECT_THAT(visitor.data(),
5856               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
5857   EXPECT_FALSE(adapter->want_write());
5858 }
5859 
TEST(NgHttp2AdapterTest,IncompleteRequestWithServerResponse)5860 TEST(NgHttp2AdapterTest, IncompleteRequestWithServerResponse) {
5861   DataSavingVisitor visitor;
5862   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5863   EXPECT_FALSE(adapter->want_write());
5864 
5865   const std::string frames = TestFrameSequence()
5866                                  .ClientPreface()
5867                                  .Headers(1,
5868                                           {{":method", "GET"},
5869                                            {":scheme", "https"},
5870                                            {":authority", "example.com"},
5871                                            {":path", "/this/is/request/one"}},
5872                                           /*fin=*/false)
5873                                  .Serialize();
5874   testing::InSequence s;
5875 
5876   // Client preface (empty SETTINGS)
5877   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5878   EXPECT_CALL(visitor, OnSettingsStart());
5879   EXPECT_CALL(visitor, OnSettingsEnd());
5880   // Stream 1
5881   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5882   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5883   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
5884   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5885 
5886   const int64_t result = adapter->ProcessBytes(frames);
5887   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5888 
5889   int submit_result =
5890       adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
5891   EXPECT_EQ(submit_result, 0);
5892   EXPECT_TRUE(adapter->want_write());
5893 
5894   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
5895   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
5896   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
5897   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
5898   // BUG: Should send RST_STREAM NO_ERROR as well, but nghttp2 does not.
5899 
5900   int send_result = adapter->Send();
5901   EXPECT_EQ(0, send_result);
5902   EXPECT_THAT(visitor.data(),
5903               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
5904   EXPECT_FALSE(adapter->want_write());
5905 }
5906 
TEST(NgHttp2AdapterTest,ServerHandlesMultipleContentLength)5907 TEST(NgHttp2AdapterTest, ServerHandlesMultipleContentLength) {
5908   DataSavingVisitor visitor;
5909   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5910   EXPECT_FALSE(adapter->want_write());
5911 
5912   const std::string frames = TestFrameSequence()
5913                                  .ClientPreface()
5914                                  .Headers(1,
5915                                           {{":method", "POST"},
5916                                            {":scheme", "https"},
5917                                            {":authority", "example.com"},
5918                                            {":path", "/1"},
5919                                            {"content-length", "7"},
5920                                            {"content-length", "7"}},
5921                                           /*fin=*/false)
5922                                  .Headers(3,
5923                                           {{":method", "POST"},
5924                                            {":scheme", "https"},
5925                                            {":authority", "example.com"},
5926                                            {":path", "/3"},
5927                                            {"content-length", "11"},
5928                                            {"content-length", "13"}},
5929                                           /*fin=*/false)
5930                                  .Serialize();
5931   testing::InSequence s;
5932 
5933   // Client preface (empty SETTINGS)
5934   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5935   EXPECT_CALL(visitor, OnSettingsStart());
5936   EXPECT_CALL(visitor, OnSettingsEnd());
5937   // Stream 1
5938   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5939   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5940   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
5941   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5942   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5943   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/1"));
5944   EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "7"));
5945   // nghttp2 does not like duplicate Content-Length headers.
5946   EXPECT_CALL(
5947       visitor,
5948       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
5949                    "stream: 1, name: [content-length], value: [7]"));
5950   EXPECT_CALL(
5951       visitor,
5952       OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
5953   // Stream 3
5954   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
5955   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
5956   EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "POST"));
5957   EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "https"));
5958   EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
5959   EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/3"));
5960   EXPECT_CALL(visitor, OnHeaderForStream(3, "content-length", "11"));
5961   EXPECT_CALL(
5962       visitor,
5963       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
5964                    "stream: 3, name: [content-length], value: [13]"));
5965   EXPECT_CALL(
5966       visitor,
5967       OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
5968 
5969   const int64_t result = adapter->ProcessBytes(frames);
5970   EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5971 }
5972 
TEST(NgHttp2AdapterTest,ServerSendsInvalidTrailers)5973 TEST(NgHttp2AdapterTest, ServerSendsInvalidTrailers) {
5974   DataSavingVisitor visitor;
5975   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
5976   EXPECT_FALSE(adapter->want_write());
5977 
5978   const std::string frames = TestFrameSequence()
5979                                  .ClientPreface()
5980                                  .Headers(1,
5981                                           {{":method", "GET"},
5982                                            {":scheme", "https"},
5983                                            {":authority", "example.com"},
5984                                            {":path", "/this/is/request/one"}},
5985                                           /*fin=*/true)
5986                                  .Serialize();
5987   testing::InSequence s;
5988 
5989   // Client preface (empty SETTINGS)
5990   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5991   EXPECT_CALL(visitor, OnSettingsStart());
5992   EXPECT_CALL(visitor, OnSettingsEnd());
5993   // Stream 1
5994   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
5995   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5996   EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
5997   EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5998   EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5999   EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
6000   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6001   EXPECT_CALL(visitor, OnEndStream(1));
6002 
6003   const int64_t result = adapter->ProcessBytes(frames);
6004   EXPECT_EQ(frames.size(), result);
6005 
6006   const absl::string_view kBody = "This is an example response body.";
6007 
6008   // The body source must indicate that the end of the body is not the end of
6009   // the stream.
6010   auto body1 = std::make_unique<TestDataFrameSource>(visitor, false);
6011   body1->AppendPayload(kBody);
6012   body1->EndData();
6013   int submit_result = adapter->SubmitResponse(
6014       1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
6015       std::move(body1));
6016   EXPECT_EQ(submit_result, 0);
6017   EXPECT_TRUE(adapter->want_write());
6018 
6019   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
6020   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
6021   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
6022   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
6023   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
6024 
6025   int send_result = adapter->Send();
6026   EXPECT_EQ(0, send_result);
6027   EXPECT_THAT(visitor.data(),
6028               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
6029                             SpdyFrameType::DATA}));
6030   EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
6031   visitor.Clear();
6032   EXPECT_FALSE(adapter->want_write());
6033 
6034   // The body source has been exhausted by the call to Send() above.
6035   int trailer_result =
6036       adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
6037   ASSERT_EQ(trailer_result, 0);
6038   EXPECT_TRUE(adapter->want_write());
6039 
6040   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
6041   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
6042   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
6043 
6044   send_result = adapter->Send();
6045   EXPECT_EQ(0, send_result);
6046   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
6047 }
6048 
TEST(NgHttp2AdapterTest,ServerDropsNewStreamBelowWatermark)6049 TEST(NgHttp2AdapterTest, ServerDropsNewStreamBelowWatermark) {
6050   DataSavingVisitor visitor;
6051   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6052 
6053   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
6054 
6055   const std::string frames = TestFrameSequence()
6056                                  .ClientPreface()
6057                                  .Headers(3,
6058                                           {{":method", "POST"},
6059                                            {":scheme", "https"},
6060                                            {":authority", "example.com"},
6061                                            {":path", "/this/is/request/one"}},
6062                                           /*fin=*/false)
6063                                  .Data(3, "This is the request body.")
6064                                  .Headers(1,
6065                                           {{":method", "GET"},
6066                                            {":scheme", "http"},
6067                                            {":authority", "example.com"},
6068                                            {":path", "/this/is/request/two"}},
6069                                           /*fin=*/true)
6070                                  .Serialize();
6071   testing::InSequence s;
6072 
6073   // Client preface (empty SETTINGS)
6074   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6075   EXPECT_CALL(visitor, OnSettingsStart());
6076   EXPECT_CALL(visitor, OnSettingsEnd());
6077 
6078   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
6079   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
6080   EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "POST"));
6081   EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "https"));
6082   EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
6083   EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/one"));
6084   EXPECT_CALL(visitor, OnEndHeadersForStream(3));
6085   EXPECT_CALL(visitor, OnFrameHeader(3, 25, DATA, 0));
6086   EXPECT_CALL(visitor, OnBeginDataForStream(3, 25));
6087   EXPECT_CALL(visitor, OnDataForStream(3, "This is the request body."));
6088 
6089   // It looks like nghttp2 delivers the under-watermark frame header but
6090   // otherwise silently drops the rest of the frame without error.
6091   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
6092   EXPECT_CALL(visitor, OnInvalidFrame).Times(0);
6093   EXPECT_CALL(visitor, OnConnectionError).Times(0);
6094 
6095   const int64_t result = adapter->ProcessBytes(frames);
6096   EXPECT_EQ(frames.size(), result);
6097 
6098   EXPECT_EQ(3, adapter->GetHighestReceivedStreamId());
6099 
6100   EXPECT_TRUE(adapter->want_write());
6101 
6102   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
6103   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
6104 
6105   int send_result = adapter->Send();
6106   // Some bytes should have been serialized.
6107   EXPECT_EQ(0, send_result);
6108   // SETTINGS ack
6109   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
6110 }
6111 
TEST(NgHttp2AdapterInteractionTest,ClientServerInteractionRepeatedHeaderNames)6112 TEST(NgHttp2AdapterInteractionTest,
6113      ClientServerInteractionRepeatedHeaderNames) {
6114   DataSavingVisitor client_visitor;
6115   auto client_adapter = NgHttp2Adapter::CreateClientAdapter(client_visitor);
6116 
6117   client_adapter->SubmitSettings({});
6118 
6119   const std::vector<Header> headers1 =
6120       ToHeaders({{":method", "GET"},
6121                  {":scheme", "http"},
6122                  {":authority", "example.com"},
6123                  {":path", "/this/is/request/one"},
6124                  {"accept", "text/plain"},
6125                  {"accept", "text/html"}});
6126 
6127   const int32_t stream_id1 =
6128       client_adapter->SubmitRequest(headers1, nullptr, nullptr);
6129   ASSERT_GT(stream_id1, 0);
6130 
6131   EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6132   EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
6133   EXPECT_CALL(client_visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
6134   EXPECT_CALL(client_visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
6135   int send_result = client_adapter->Send();
6136   EXPECT_EQ(0, send_result);
6137 
6138   DataSavingVisitor server_visitor;
6139   auto server_adapter = NgHttp2Adapter::CreateServerAdapter(server_visitor);
6140 
6141   testing::InSequence s;
6142 
6143   // Client preface (empty SETTINGS)
6144   EXPECT_CALL(server_visitor, OnFrameHeader(0, _, SETTINGS, 0));
6145   EXPECT_CALL(server_visitor, OnSettingsStart());
6146   EXPECT_CALL(server_visitor, OnSetting(_)).Times(testing::AnyNumber());
6147   EXPECT_CALL(server_visitor, OnSettingsEnd());
6148   // Stream 1
6149   EXPECT_CALL(server_visitor, OnFrameHeader(1, _, HEADERS, 5));
6150   EXPECT_CALL(server_visitor, OnBeginHeadersForStream(1));
6151   EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":method", "GET"));
6152   EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":scheme", "http"));
6153   EXPECT_CALL(server_visitor,
6154               OnHeaderForStream(1, ":authority", "example.com"));
6155   EXPECT_CALL(server_visitor,
6156               OnHeaderForStream(1, ":path", "/this/is/request/one"));
6157   EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/plain"));
6158   EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/html"));
6159   EXPECT_CALL(server_visitor, OnEndHeadersForStream(1));
6160   EXPECT_CALL(server_visitor, OnEndStream(1));
6161 
6162   int64_t result = server_adapter->ProcessBytes(client_visitor.data());
6163   EXPECT_EQ(client_visitor.data().size(), static_cast<size_t>(result));
6164 }
6165 
TEST(NgHttp2AdapterInteractionTest,ClientServerInteractionWithCookies)6166 TEST(NgHttp2AdapterInteractionTest, ClientServerInteractionWithCookies) {
6167   DataSavingVisitor client_visitor;
6168   auto client_adapter = NgHttp2Adapter::CreateClientAdapter(client_visitor);
6169 
6170   client_adapter->SubmitSettings({});
6171 
6172   const std::vector<Header> headers1 =
6173       ToHeaders({{":method", "GET"},
6174                  {":scheme", "http"},
6175                  {":authority", "example.com"},
6176                  {":path", "/this/is/request/one"},
6177                  {"cookie", "a; b=2; c"},
6178                  {"cookie", "d=e, f, g; h"}});
6179 
6180   const int32_t stream_id1 =
6181       client_adapter->SubmitRequest(headers1, nullptr, nullptr);
6182   ASSERT_GT(stream_id1, 0);
6183 
6184   EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6185   EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
6186   EXPECT_CALL(client_visitor,
6187               OnBeforeFrameSent(HEADERS, stream_id1, _,
6188                                 END_STREAM_FLAG | END_HEADERS_FLAG));
6189   EXPECT_CALL(client_visitor,
6190               OnFrameSent(HEADERS, stream_id1, _,
6191                           END_STREAM_FLAG | END_HEADERS_FLAG, 0));
6192   int send_result = client_adapter->Send();
6193   EXPECT_EQ(0, send_result);
6194 
6195   DataSavingVisitor server_visitor;
6196   auto server_adapter = NgHttp2Adapter::CreateServerAdapter(server_visitor);
6197 
6198   testing::InSequence s;
6199 
6200   // Client preface (empty SETTINGS)
6201   EXPECT_CALL(server_visitor, OnFrameHeader(0, _, SETTINGS, 0));
6202   EXPECT_CALL(server_visitor, OnSettingsStart());
6203   EXPECT_CALL(server_visitor, OnSetting).Times(testing::AnyNumber());
6204   EXPECT_CALL(server_visitor, OnSettingsEnd());
6205   // Stream 1
6206   EXPECT_CALL(server_visitor, OnFrameHeader(1, _, HEADERS, 5));
6207   EXPECT_CALL(server_visitor, OnBeginHeadersForStream(1));
6208   EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":method", "GET"));
6209   EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":scheme", "http"));
6210   EXPECT_CALL(server_visitor,
6211               OnHeaderForStream(1, ":authority", "example.com"));
6212   EXPECT_CALL(server_visitor,
6213               OnHeaderForStream(1, ":path", "/this/is/request/one"));
6214   // Cookie values are preserved verbatim.
6215   EXPECT_CALL(server_visitor, OnHeaderForStream(1, "cookie", "a; b=2; c"));
6216   EXPECT_CALL(server_visitor, OnHeaderForStream(1, "cookie", "d=e, f, g; h"));
6217   EXPECT_CALL(server_visitor, OnEndHeadersForStream(1));
6218   EXPECT_CALL(server_visitor, OnEndStream(1));
6219 
6220   int64_t result = server_adapter->ProcessBytes(client_visitor.data());
6221   EXPECT_EQ(client_visitor.data().size(), static_cast<size_t>(result));
6222 }
6223 
TEST(NgHttp2AdapterTest,ServerForbidsWindowUpdateOnIdleStream)6224 TEST(NgHttp2AdapterTest, ServerForbidsWindowUpdateOnIdleStream) {
6225   DataSavingVisitor visitor;
6226   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6227 
6228   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
6229 
6230   const std::string frames =
6231       TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
6232 
6233   testing::InSequence s;
6234 
6235   // Client preface (empty SETTINGS)
6236   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6237   EXPECT_CALL(visitor, OnSettingsStart());
6238   EXPECT_CALL(visitor, OnSettingsEnd());
6239 
6240   EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
6241   EXPECT_CALL(visitor, OnInvalidFrame(1, _));
6242 
6243   const int64_t result = adapter->ProcessBytes(frames);
6244   EXPECT_EQ(frames.size(), result);
6245 
6246   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
6247 
6248   EXPECT_TRUE(adapter->want_write());
6249 
6250   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6251   EXPECT_CALL(visitor,
6252               OnFrameSent(GOAWAY, 0, _, 0x0,
6253                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6254 
6255   int send_result = adapter->Send();
6256   // Some bytes should have been serialized.
6257   EXPECT_EQ(0, send_result);
6258   // The GOAWAY apparently causes the SETTINGS ack to be dropped.
6259   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
6260 }
6261 
TEST(NgHttp2AdapterTest,ServerForbidsDataOnIdleStream)6262 TEST(NgHttp2AdapterTest, ServerForbidsDataOnIdleStream) {
6263   DataSavingVisitor visitor;
6264   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6265 
6266   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
6267 
6268   const std::string frames = TestFrameSequence()
6269                                  .ClientPreface()
6270                                  .Data(1, "Sorry, out of order")
6271                                  .Serialize();
6272 
6273   testing::InSequence s;
6274 
6275   // Client preface (empty SETTINGS)
6276   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6277   EXPECT_CALL(visitor, OnSettingsStart());
6278   EXPECT_CALL(visitor, OnSettingsEnd());
6279 
6280   const int64_t result = adapter->ProcessBytes(frames);
6281   EXPECT_EQ(frames.size(), result);
6282 
6283   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
6284 
6285   EXPECT_TRUE(adapter->want_write());
6286 
6287   // In this case, nghttp2 goes straight to GOAWAY and does not invoke the
6288   // invalid frame callback.
6289   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6290   EXPECT_CALL(visitor,
6291               OnFrameSent(GOAWAY, 0, _, 0x0,
6292                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6293 
6294   int send_result = adapter->Send();
6295   // Some bytes should have been serialized.
6296   EXPECT_EQ(0, send_result);
6297   // The GOAWAY apparently causes the SETTINGS ack to be dropped.
6298   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
6299 }
6300 
TEST(NgHttp2AdapterTest,ServerForbidsRstStreamOnIdleStream)6301 TEST(NgHttp2AdapterTest, ServerForbidsRstStreamOnIdleStream) {
6302   DataSavingVisitor visitor;
6303   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6304 
6305   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
6306 
6307   const std::string frames =
6308       TestFrameSequence()
6309           .ClientPreface()
6310           .RstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM)
6311           .Serialize();
6312 
6313   testing::InSequence s;
6314 
6315   // Client preface (empty SETTINGS)
6316   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6317   EXPECT_CALL(visitor, OnSettingsStart());
6318   EXPECT_CALL(visitor, OnSettingsEnd());
6319 
6320   EXPECT_CALL(visitor, OnFrameHeader(1, _, RST_STREAM, 0));
6321   EXPECT_CALL(visitor, OnInvalidFrame(1, _));
6322 
6323   const int64_t result = adapter->ProcessBytes(frames);
6324   EXPECT_EQ(frames.size(), result);
6325 
6326   EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
6327 
6328   EXPECT_TRUE(adapter->want_write());
6329 
6330   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6331   EXPECT_CALL(visitor,
6332               OnFrameSent(GOAWAY, 0, _, 0x0,
6333                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6334 
6335   int send_result = adapter->Send();
6336   // Some bytes should have been serialized.
6337   EXPECT_EQ(0, send_result);
6338   // The GOAWAY apparently causes the SETTINGS ack to be dropped.
6339   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
6340 }
6341 
TEST(NgHttp2AdapterTest,ServerForbidsNewStreamAboveStreamLimit)6342 TEST(NgHttp2AdapterTest, ServerForbidsNewStreamAboveStreamLimit) {
6343   DataSavingVisitor visitor;
6344   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6345   adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
6346 
6347   const std::string initial_frames =
6348       TestFrameSequence().ClientPreface().Serialize();
6349 
6350   testing::InSequence s;
6351 
6352   // Client preface (empty SETTINGS)
6353   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6354   EXPECT_CALL(visitor, OnSettingsStart());
6355   EXPECT_CALL(visitor, OnSettingsEnd());
6356 
6357   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
6358   EXPECT_EQ(initial_frames.size(), initial_result);
6359 
6360   EXPECT_TRUE(adapter->want_write());
6361 
6362   // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
6363   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
6364   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
6365   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
6366   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
6367 
6368   int send_result = adapter->Send();
6369   EXPECT_EQ(0, send_result);
6370   EXPECT_THAT(visitor.data(),
6371               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
6372   visitor.Clear();
6373 
6374   // Let the client send a SETTINGS ack and then attempt to open more than the
6375   // advertised number of streams. The overflow stream should be rejected.
6376   const std::string stream_frames =
6377       TestFrameSequence()
6378           .SettingsAck()
6379           .Headers(1,
6380                    {{":method", "GET"},
6381                     {":scheme", "https"},
6382                     {":authority", "example.com"},
6383                     {":path", "/this/is/request/one"}},
6384                    /*fin=*/true)
6385           .Headers(3,
6386                    {{":method", "GET"},
6387                     {":scheme", "http"},
6388                     {":authority", "example.com"},
6389                     {":path", "/this/is/request/two"}},
6390                    /*fin=*/true)
6391           .Serialize();
6392 
6393   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
6394   EXPECT_CALL(visitor, OnSettingsAck());
6395   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
6396   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6397   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
6398   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6399   EXPECT_CALL(visitor, OnEndStream(1));
6400   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
6401   EXPECT_CALL(
6402       visitor,
6403       OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kProtocol));
6404 
6405   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
6406   EXPECT_EQ(stream_frames.size(), stream_result);
6407 
6408   // The server should send a GOAWAY for this error, even though
6409   // OnInvalidFrame() returns true.
6410   EXPECT_TRUE(adapter->want_write());
6411   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6412   EXPECT_CALL(visitor,
6413               OnFrameSent(GOAWAY, 0, _, 0x0,
6414                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6415 
6416   send_result = adapter->Send();
6417   EXPECT_EQ(0, send_result);
6418   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
6419 }
6420 
TEST(NgHttp2AdapterTest,ServerRstStreamsNewStreamAboveStreamLimitBeforeAck)6421 TEST(NgHttp2AdapterTest, ServerRstStreamsNewStreamAboveStreamLimitBeforeAck) {
6422   DataSavingVisitor visitor;
6423   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6424   adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
6425 
6426   const std::string initial_frames =
6427       TestFrameSequence().ClientPreface().Serialize();
6428 
6429   testing::InSequence s;
6430 
6431   // Client preface (empty SETTINGS)
6432   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6433   EXPECT_CALL(visitor, OnSettingsStart());
6434   EXPECT_CALL(visitor, OnSettingsEnd());
6435 
6436   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
6437   EXPECT_EQ(initial_frames.size(), initial_result);
6438 
6439   EXPECT_TRUE(adapter->want_write());
6440 
6441   // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
6442   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
6443   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
6444   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
6445   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
6446 
6447   int send_result = adapter->Send();
6448   EXPECT_EQ(0, send_result);
6449   EXPECT_THAT(visitor.data(),
6450               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
6451   visitor.Clear();
6452 
6453   // Let the client avoid sending a SETTINGS ack and attempt to open more than
6454   // the advertised number of streams. The server should still reject the
6455   // overflow stream, albeit with RST_STREAM REFUSED_STREAM instead of GOAWAY.
6456   const std::string stream_frames =
6457       TestFrameSequence()
6458           .Headers(1,
6459                    {{":method", "GET"},
6460                     {":scheme", "https"},
6461                     {":authority", "example.com"},
6462                     {":path", "/this/is/request/one"}},
6463                    /*fin=*/true)
6464           .Headers(3,
6465                    {{":method", "GET"},
6466                     {":scheme", "http"},
6467                     {":authority", "example.com"},
6468                     {":path", "/this/is/request/two"}},
6469                    /*fin=*/true)
6470           .Serialize();
6471 
6472   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
6473   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6474   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
6475   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6476   EXPECT_CALL(visitor, OnEndStream(1));
6477   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
6478   EXPECT_CALL(visitor,
6479               OnInvalidFrame(
6480                   3, Http2VisitorInterface::InvalidFrameError::kRefusedStream));
6481 
6482   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
6483   EXPECT_EQ(stream_result, stream_frames.size());
6484 
6485   // The server sends a RST_STREAM for the offending stream.
6486   EXPECT_TRUE(adapter->want_write());
6487   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
6488   EXPECT_CALL(visitor,
6489               OnFrameSent(RST_STREAM, 3, _, 0x0,
6490                           static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
6491 
6492   send_result = adapter->Send();
6493   EXPECT_EQ(0, send_result);
6494   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
6495 }
6496 
TEST(NgHttp2AdapterTest,AutomaticSettingsAndPingAcks)6497 TEST(NgHttp2AdapterTest, AutomaticSettingsAndPingAcks) {
6498   DataSavingVisitor visitor;
6499   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6500   const std::string frames =
6501       TestFrameSequence().ClientPreface().Ping(42).Serialize();
6502   testing::InSequence s;
6503 
6504   // Client preface (empty SETTINGS)
6505   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6506   EXPECT_CALL(visitor, OnSettingsStart());
6507   EXPECT_CALL(visitor, OnSettingsEnd());
6508   // PING
6509   EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
6510   EXPECT_CALL(visitor, OnPing(42, false));
6511 
6512   const int64_t read_result = adapter->ProcessBytes(frames);
6513   EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
6514 
6515   EXPECT_TRUE(adapter->want_write());
6516 
6517   // Server preface does not appear to include the mandatory SETTINGS frame.
6518   // SETTINGS ack
6519   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
6520   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
6521   // PING ack
6522   EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
6523   EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
6524 
6525   int send_result = adapter->Send();
6526   EXPECT_EQ(0, send_result);
6527   EXPECT_THAT(visitor.data(),
6528               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
6529 }
6530 
TEST(NgHttp2AdapterTest,AutomaticPingAcksDisabled)6531 TEST(NgHttp2AdapterTest, AutomaticPingAcksDisabled) {
6532   DataSavingVisitor visitor;
6533   nghttp2_option* options;
6534   nghttp2_option_new(&options);
6535   nghttp2_option_set_no_auto_ping_ack(options, 1);
6536   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor, options);
6537   nghttp2_option_del(options);
6538 
6539   const std::string frames =
6540       TestFrameSequence().ClientPreface().Ping(42).Serialize();
6541   testing::InSequence s;
6542 
6543   // Client preface (empty SETTINGS)
6544   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6545   EXPECT_CALL(visitor, OnSettingsStart());
6546   EXPECT_CALL(visitor, OnSettingsEnd());
6547   // PING
6548   EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
6549   EXPECT_CALL(visitor, OnPing(42, false));
6550 
6551   const int64_t read_result = adapter->ProcessBytes(frames);
6552   EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
6553 
6554   EXPECT_TRUE(adapter->want_write());
6555 
6556   // Server preface does not appear to include the mandatory SETTINGS frame.
6557   // SETTINGS ack
6558   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
6559   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
6560   // No PING ack expected because automatic PING acks are disabled.
6561 
6562   int send_result = adapter->Send();
6563   EXPECT_EQ(0, send_result);
6564   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
6565 }
6566 
TEST(NgHttp2AdapterTest,InvalidMaxFrameSizeSetting)6567 TEST(NgHttp2AdapterTest, InvalidMaxFrameSizeSetting) {
6568   DataSavingVisitor visitor;
6569   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6570 
6571   const std::string frames =
6572       TestFrameSequence().ClientPreface({{MAX_FRAME_SIZE, 3u}}).Serialize();
6573   testing::InSequence s;
6574 
6575   // Client preface
6576   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
6577   EXPECT_CALL(
6578       visitor,
6579       OnInvalidFrame(0, Http2VisitorInterface::InvalidFrameError::kProtocol));
6580 
6581   const int64_t read_result = adapter->ProcessBytes(frames);
6582   EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
6583 
6584   EXPECT_TRUE(adapter->want_write());
6585 
6586   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6587   EXPECT_CALL(visitor,
6588               OnFrameSent(GOAWAY, 0, _, 0x0,
6589                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6590 
6591   int send_result = adapter->Send();
6592   EXPECT_EQ(0, send_result);
6593   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
6594 }
6595 
TEST(OgHttp2AdapterTest,InvalidPushSetting)6596 TEST(OgHttp2AdapterTest, InvalidPushSetting) {
6597   DataSavingVisitor visitor;
6598   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6599 
6600   const std::string frames =
6601       TestFrameSequence().ClientPreface({{ENABLE_PUSH, 3u}}).Serialize();
6602   testing::InSequence s;
6603 
6604   // Client preface
6605   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
6606   EXPECT_CALL(visitor, OnInvalidFrame(0, _));
6607 
6608   const int64_t read_result = adapter->ProcessBytes(frames);
6609   EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
6610 
6611   EXPECT_TRUE(adapter->want_write());
6612 
6613   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6614   EXPECT_CALL(visitor,
6615               OnFrameSent(GOAWAY, 0, _, 0x0,
6616                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6617 
6618   int send_result = adapter->Send();
6619   EXPECT_EQ(0, send_result);
6620   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
6621 }
6622 
TEST(NgHttp2AdapterTest,InvalidConnectProtocolSetting)6623 TEST(NgHttp2AdapterTest, InvalidConnectProtocolSetting) {
6624   DataSavingVisitor visitor;
6625   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6626 
6627   const std::string frames = TestFrameSequence()
6628                                  .ClientPreface({{ENABLE_CONNECT_PROTOCOL, 3u}})
6629                                  .Serialize();
6630   testing::InSequence s;
6631 
6632   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
6633   EXPECT_CALL(
6634       visitor,
6635       OnInvalidFrame(0, Http2VisitorInterface::InvalidFrameError::kProtocol));
6636 
6637   int64_t read_result = adapter->ProcessBytes(frames);
6638   EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
6639 
6640   EXPECT_TRUE(adapter->want_write());
6641 
6642   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6643   EXPECT_CALL(visitor,
6644               OnFrameSent(GOAWAY, 0, _, 0x0,
6645                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6646 
6647   int send_result = adapter->Send();
6648   EXPECT_EQ(0, send_result);
6649   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
6650 
6651   auto adapter2 = NgHttp2Adapter::CreateServerAdapter(visitor);
6652   const std::string frames2 = TestFrameSequence()
6653                                   .ClientPreface({{ENABLE_CONNECT_PROTOCOL, 1}})
6654                                   .Settings({{ENABLE_CONNECT_PROTOCOL, 0}})
6655                                   .Serialize();
6656 
6657   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
6658   EXPECT_CALL(visitor, OnSettingsStart());
6659   EXPECT_CALL(visitor, OnSetting(Http2Setting{ENABLE_CONNECT_PROTOCOL, 1u}));
6660   EXPECT_CALL(visitor, OnSettingsEnd());
6661   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
6662   EXPECT_CALL(visitor, OnSettingsStart());
6663   // Surprisingly, nghttp2 allows this behavior, which is prohibited in RFC
6664   // 8441.
6665   EXPECT_CALL(visitor, OnSetting(Http2Setting{ENABLE_CONNECT_PROTOCOL, 0u}));
6666   EXPECT_CALL(visitor, OnSettingsEnd());
6667 
6668   read_result = adapter2->ProcessBytes(frames2);
6669   EXPECT_EQ(static_cast<size_t>(read_result), frames2.size());
6670 
6671   EXPECT_TRUE(adapter2->want_write());
6672 
6673   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
6674   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
6675   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
6676   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
6677   adapter2->Send();
6678 }
6679 
TEST(NgHttp2AdapterTest,ServerForbidsProtocolPseudoheaderBeforeAck)6680 TEST(NgHttp2AdapterTest, ServerForbidsProtocolPseudoheaderBeforeAck) {
6681   DataSavingVisitor visitor;
6682   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6683 
6684   const std::string initial_frames =
6685       TestFrameSequence().ClientPreface().Serialize();
6686 
6687   testing::InSequence s;
6688 
6689   // Client preface (empty SETTINGS)
6690   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6691   EXPECT_CALL(visitor, OnSettingsStart());
6692   EXPECT_CALL(visitor, OnSettingsEnd());
6693 
6694   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
6695   EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
6696 
6697   // The client attempts to send a CONNECT request with the `:protocol`
6698   // pseudoheader before receiving the server's SETTINGS frame.
6699   const std::string stream1_frames =
6700       TestFrameSequence()
6701           .Headers(1,
6702                    {{":method", "CONNECT"},
6703                     {":scheme", "https"},
6704                     {":authority", "example.com"},
6705                     {":path", "/this/is/request/one"},
6706                     {":protocol", "websocket"}},
6707                    /*fin=*/true)
6708           .Serialize();
6709 
6710   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
6711   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6712   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
6713   EXPECT_CALL(
6714       visitor,
6715       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
6716                    "stream: 1, name: [:protocol], value: [websocket]"));
6717   EXPECT_CALL(
6718       visitor,
6719       OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
6720 
6721   int64_t stream_result = adapter->ProcessBytes(stream1_frames);
6722   EXPECT_EQ(static_cast<size_t>(stream_result), stream1_frames.size());
6723 
6724   // Server sends a SETTINGS ack and initial SETTINGS (with
6725   // ENABLE_CONNECT_PROTOCOL).
6726   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
6727   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
6728   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
6729   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
6730 
6731   // The server sends a RST_STREAM for the offending stream.
6732   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
6733   EXPECT_CALL(visitor,
6734               OnFrameSent(RST_STREAM, 1, _, 0x0,
6735                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6736   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
6737 
6738   adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
6739   int send_result = adapter->Send();
6740   EXPECT_EQ(0, send_result);
6741   EXPECT_THAT(visitor.data(),
6742               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
6743                             SpdyFrameType::RST_STREAM}));
6744   visitor.Clear();
6745 
6746   // The client attempts to send a CONNECT request with the `:protocol`
6747   // pseudoheader before acking the server's SETTINGS frame.
6748   const std::string stream3_frames =
6749       TestFrameSequence()
6750           .Headers(3,
6751                    {{":method", "CONNECT"},
6752                     {":scheme", "https"},
6753                     {":authority", "example.com"},
6754                     {":path", "/this/is/request/two"},
6755                     {":protocol", "websocket"}},
6756                    /*fin=*/true)
6757           .Serialize();
6758 
6759   // Surprisingly, nghttp2 is okay with this.
6760   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
6761   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
6762   EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
6763   EXPECT_CALL(visitor, OnEndHeadersForStream(3));
6764   EXPECT_CALL(visitor, OnEndStream(3));
6765 
6766   stream_result = adapter->ProcessBytes(stream3_frames);
6767   EXPECT_EQ(static_cast<size_t>(stream_result), stream3_frames.size());
6768 
6769   EXPECT_FALSE(adapter->want_write());
6770 }
6771 
TEST(NgHttp2AdapterTest,ServerAllowsProtocolPseudoheaderAfterAck)6772 TEST(NgHttp2AdapterTest, ServerAllowsProtocolPseudoheaderAfterAck) {
6773   DataSavingVisitor visitor;
6774   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6775   adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
6776 
6777   const std::string initial_frames =
6778       TestFrameSequence().ClientPreface().Serialize();
6779 
6780   testing::InSequence s;
6781 
6782   // Client preface (empty SETTINGS)
6783   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6784   EXPECT_CALL(visitor, OnSettingsStart());
6785   EXPECT_CALL(visitor, OnSettingsEnd());
6786 
6787   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
6788   EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
6789 
6790   // Server initial SETTINGS (with ENABLE_CONNECT_PROTOCOL) and SETTINGS ack.
6791   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
6792   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
6793   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
6794   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
6795 
6796   int send_result = adapter->Send();
6797   EXPECT_EQ(0, send_result);
6798   visitor.Clear();
6799 
6800   // The client attempts to send a CONNECT request with the `:protocol`
6801   // pseudoheader after acking the server's SETTINGS frame.
6802   const std::string stream_frames =
6803       TestFrameSequence()
6804           .SettingsAck()
6805           .Headers(1,
6806                    {{":method", "CONNECT"},
6807                     {":scheme", "https"},
6808                     {":authority", "example.com"},
6809                     {":path", "/this/is/request/one"},
6810                     {":protocol", "websocket"}},
6811                    /*fin=*/true)
6812           .Serialize();
6813 
6814   EXPECT_CALL(visitor, OnFrameHeader(0, _, SETTINGS, 0x1));
6815   EXPECT_CALL(visitor, OnSettingsAck());
6816   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
6817   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6818   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
6819   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6820   EXPECT_CALL(visitor, OnEndStream(1));
6821 
6822   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
6823   EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
6824 
6825   EXPECT_FALSE(adapter->want_write());
6826 }
6827 
TEST(NgHttp2AdapterTest,SkipsSendingFramesForRejectedStream)6828 TEST(NgHttp2AdapterTest, SkipsSendingFramesForRejectedStream) {
6829   DataSavingVisitor visitor;
6830   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6831 
6832   const std::string initial_frames =
6833       TestFrameSequence()
6834           .ClientPreface()
6835           .Headers(1,
6836                    {{":method", "GET"},
6837                     {":scheme", "http"},
6838                     {":authority", "example.com"},
6839                     {":path", "/this/is/request/one"}},
6840                    /*fin=*/true)
6841           .Serialize();
6842 
6843   testing::InSequence s;
6844 
6845   // Client preface (empty SETTINGS)
6846   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6847   EXPECT_CALL(visitor, OnSettingsStart());
6848   EXPECT_CALL(visitor, OnSettingsEnd());
6849   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
6850   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6851   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
6852   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6853   EXPECT_CALL(visitor, OnEndStream(1));
6854 
6855   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
6856   EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
6857 
6858   auto body = std::make_unique<TestDataFrameSource>(visitor, true);
6859   body->AppendPayload("Here is some data, which will be completely ignored!");
6860 
6861   int submit_result = adapter->SubmitResponse(
6862       1, ToHeaders({{":status", "200"}}), std::move(body));
6863   ASSERT_EQ(0, submit_result);
6864 
6865   auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
6866       {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
6867   adapter->SubmitMetadata(1, 16384u, std::move(source));
6868 
6869   adapter->SubmitWindowUpdate(1, 1024);
6870   adapter->SubmitRst(1, Http2ErrorCode::INTERNAL_ERROR);
6871 
6872   // Server initial SETTINGS and SETTINGS ack.
6873   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
6874   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
6875 
6876   // nghttp2 apparently allows extension frames to be sent on reset streams.
6877   EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
6878   EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
6879 
6880   // The server sends a RST_STREAM for the offending stream.
6881   // The response HEADERS, DATA and WINDOW_UPDATE are all ignored.
6882   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
6883   EXPECT_CALL(visitor,
6884               OnFrameSent(RST_STREAM, 1, _, 0x0,
6885                           static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
6886   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
6887 
6888   int send_result = adapter->Send();
6889   EXPECT_EQ(0, send_result);
6890   EXPECT_THAT(visitor.data(),
6891               EqualsFrames({SpdyFrameType::SETTINGS,
6892                             static_cast<SpdyFrameType>(kMetadataFrameType),
6893                             SpdyFrameType::RST_STREAM}));
6894 }
6895 
TEST(NgHttp2AdapterTest,ServerQueuesMetadataWithStreamReset)6896 TEST(NgHttp2AdapterTest, ServerQueuesMetadataWithStreamReset) {
6897   DataSavingVisitor visitor;
6898   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6899 
6900   const std::string initial_frames =
6901       TestFrameSequence()
6902           .ClientPreface()
6903           .Headers(1,
6904                    {{":method", "GET"},
6905                     {":scheme", "http"},
6906                     {":authority", "example.com"},
6907                     {":path", "/this/is/request/one"}},
6908                    /*fin=*/false)
6909           .Serialize();
6910 
6911   testing::InSequence s;
6912 
6913   // Client preface (empty SETTINGS)
6914   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6915   EXPECT_CALL(visitor, OnSettingsStart());
6916   EXPECT_CALL(visitor, OnSettingsEnd());
6917   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x4));
6918   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6919   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
6920   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6921 
6922   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
6923   EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
6924 
6925   auto body = std::make_unique<TestDataFrameSource>(visitor, true);
6926   body->AppendPayload("Here is some data, which will be completely ignored!");
6927 
6928   int submit_result = adapter->SubmitResponse(
6929       1, ToHeaders({{":status", "200"}}), std::move(body));
6930   ASSERT_EQ(0, submit_result);
6931 
6932   auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
6933       {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
6934   adapter->SubmitMetadata(1, 16384u, std::move(source));
6935   adapter->SubmitWindowUpdate(1, 1024);
6936 
6937   const std::string reset_frame =
6938       TestFrameSequence().RstStream(1, Http2ErrorCode::CANCEL).Serialize();
6939 
6940   EXPECT_CALL(visitor, OnFrameHeader(1, _, RST_STREAM, 0x0));
6941   EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::CANCEL));
6942   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::CANCEL));
6943   adapter->ProcessBytes(reset_frame);
6944 
6945   source = std::make_unique<TestMetadataSource>(
6946       ToHeaderBlock(ToHeaders({{"really-important", "information!"}})));
6947   adapter->SubmitMetadata(1, 16384u, std::move(source));
6948 
6949   EXPECT_EQ(1, adapter->stream_metadata_size());
6950   EXPECT_EQ(2, adapter->pending_metadata_count(1));
6951 
6952   // Server initial SETTINGS and SETTINGS ack.
6953   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
6954   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
6955 
6956   // nghttp2 apparently allows extension frames to be sent on reset streams.
6957   // The response HEADERS, DATA and WINDOW_UPDATE are all discarded.
6958   EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
6959   EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
6960   EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
6961   EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
6962 
6963   int send_result = adapter->Send();
6964   EXPECT_EQ(0, send_result);
6965   EXPECT_THAT(visitor.data(),
6966               EqualsFrames({SpdyFrameType::SETTINGS,
6967                             static_cast<SpdyFrameType>(kMetadataFrameType),
6968                             static_cast<SpdyFrameType>(kMetadataFrameType)}));
6969 
6970   EXPECT_EQ(0, adapter->stream_metadata_size());
6971   EXPECT_EQ(0, adapter->pending_metadata_count(1));
6972 }
6973 
TEST(NgHttp2AdapterTest,ServerStartsShutdown)6974 TEST(NgHttp2AdapterTest, ServerStartsShutdown) {
6975   DataSavingVisitor visitor;
6976   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6977 
6978   EXPECT_FALSE(adapter->want_write());
6979 
6980   adapter->SubmitShutdownNotice();
6981   EXPECT_TRUE(adapter->want_write());
6982 
6983   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6984   EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
6985 
6986   int result = adapter->Send();
6987   EXPECT_EQ(0, result);
6988   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
6989 }
6990 
TEST(NgHttp2AdapterTest,ServerStartsShutdownAfterGoaway)6991 TEST(NgHttp2AdapterTest, ServerStartsShutdownAfterGoaway) {
6992   DataSavingVisitor visitor;
6993   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
6994 
6995   EXPECT_FALSE(adapter->want_write());
6996 
6997   adapter->SubmitGoAway(1, Http2ErrorCode::HTTP2_NO_ERROR,
6998                         "and don't come back!");
6999   EXPECT_TRUE(adapter->want_write());
7000 
7001   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
7002   EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
7003 
7004   int result = adapter->Send();
7005   EXPECT_EQ(0, result);
7006   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
7007 
7008   // No-op, since a GOAWAY has previously been enqueued.
7009   adapter->SubmitShutdownNotice();
7010   EXPECT_FALSE(adapter->want_write());
7011 }
7012 
7013 // Verifies that a connection-level processing error results in repeatedly
7014 // returning a positive value for ProcessBytes() to mark all data as consumed.
TEST(NgHttp2AdapterTest,ConnectionErrorWithBlackholeSinkingData)7015 TEST(NgHttp2AdapterTest, ConnectionErrorWithBlackholeSinkingData) {
7016   DataSavingVisitor visitor;
7017   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
7018 
7019   const std::string frames =
7020       TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
7021 
7022   testing::InSequence s;
7023 
7024   // Client preface (empty SETTINGS)
7025   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7026   EXPECT_CALL(visitor, OnSettingsStart());
7027   EXPECT_CALL(visitor, OnSettingsEnd());
7028 
7029   EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
7030   EXPECT_CALL(visitor, OnInvalidFrame(1, _));
7031 
7032   const int64_t result = adapter->ProcessBytes(frames);
7033   EXPECT_EQ(static_cast<size_t>(result), frames.size());
7034 
7035   // Ask the connection to process more bytes. Because the option is enabled,
7036   // the data should be marked as consumed.
7037   const std::string next_frame = TestFrameSequence().Ping(42).Serialize();
7038   const int64_t next_result = adapter->ProcessBytes(next_frame);
7039   EXPECT_EQ(static_cast<size_t>(next_result), next_frame.size());
7040 }
7041 
TEST(NgHttp2AdapterTest,ServerDoesNotSendFramesAfterImmediateGoAway)7042 TEST(NgHttp2AdapterTest, ServerDoesNotSendFramesAfterImmediateGoAway) {
7043   DataSavingVisitor visitor;
7044   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
7045 
7046   // Submit a custom initial SETTINGS frame with one setting.
7047   adapter->SubmitSettings({{HEADER_TABLE_SIZE, 100u}});
7048 
7049   const std::string frames = TestFrameSequence()
7050                                  .ClientPreface()
7051                                  .Headers(1,
7052                                           {{":method", "GET"},
7053                                            {":scheme", "https"},
7054                                            {":authority", "example.com"},
7055                                            {":path", "/this/is/request/one"}},
7056                                           /*fin=*/true)
7057                                  .Serialize();
7058   testing::InSequence s;
7059 
7060   // Client preface (empty SETTINGS)
7061   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7062   EXPECT_CALL(visitor, OnSettingsStart());
7063   EXPECT_CALL(visitor, OnSettingsEnd());
7064   // Stream 1
7065   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
7066   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7067   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7068   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7069   EXPECT_CALL(visitor, OnEndStream(1));
7070 
7071   const int64_t read_result = adapter->ProcessBytes(frames);
7072   EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
7073 
7074   // Submit a response for the stream.
7075   auto body = std::make_unique<TestDataFrameSource>(visitor, true);
7076   body->AppendPayload("This data is doomed to never be written.");
7077   int submit_result = adapter->SubmitResponse(
7078       1, ToHeaders({{":status", "200"}}), std::move(body));
7079   ASSERT_EQ(0, submit_result);
7080 
7081   // Submit a WINDOW_UPDATE frame.
7082   adapter->SubmitWindowUpdate(kConnectionStreamId, 42);
7083 
7084   // Submit another SETTINGS frame.
7085   adapter->SubmitSettings({});
7086 
7087   // Submit some metadata.
7088   auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
7089       {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
7090   adapter->SubmitMetadata(1, 16384u, std::move(source));
7091 
7092   EXPECT_TRUE(adapter->want_write());
7093 
7094   // Trigger a connection error. Only the response headers will be written.
7095   const std::string connection_error_frames =
7096       TestFrameSequence().WindowUpdate(3, 42).Serialize();
7097 
7098   EXPECT_CALL(visitor, OnFrameHeader(3, 4, WINDOW_UPDATE, 0));
7099   EXPECT_CALL(visitor, OnInvalidFrame(3, _));
7100 
7101   const int64_t result = adapter->ProcessBytes(connection_error_frames);
7102   EXPECT_EQ(static_cast<size_t>(result), connection_error_frames.size());
7103 
7104   EXPECT_TRUE(adapter->want_write());
7105 
7106   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
7107   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
7108   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x0));
7109   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x0, 0));
7110   EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
7111   EXPECT_CALL(visitor,
7112               OnFrameSent(GOAWAY, 0, _, 0x0,
7113                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7114 
7115   int send_result = adapter->Send();
7116   // Some bytes should have been serialized.
7117   EXPECT_EQ(0, send_result);
7118   // The GOAWAY apparently causes the other frames to be dropped except for the
7119   // non-ack SETTINGS frames; nghttp2 sends non-ack SETTINGS frames because they
7120   // could be the initial SETTINGS frame. However, nghttp2 still allows sending
7121   // multiple non-ack SETTINGS, which feels non-ideal.
7122   EXPECT_THAT(visitor.data(),
7123               EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
7124                             SpdyFrameType::GOAWAY}));
7125   visitor.Clear();
7126 
7127   // Try to submit more frames for writing. They should not be written.
7128   adapter->SubmitPing(42);
7129   EXPECT_FALSE(adapter->want_write());
7130   send_result = adapter->Send();
7131   EXPECT_EQ(0, send_result);
7132   EXPECT_THAT(visitor.data(), testing::IsEmpty());
7133 }
7134 
TEST(NgHttp2AdapterTest,ServerHandlesContentLength)7135 TEST(NgHttp2AdapterTest, ServerHandlesContentLength) {
7136   DataSavingVisitor visitor;
7137   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
7138 
7139   testing::InSequence s;
7140 
7141   const std::string stream_frames =
7142       TestFrameSequence()
7143           .ClientPreface()
7144           .Headers(1, {{":method", "GET"},
7145                        {":scheme", "https"},
7146                        {":authority", "example.com"},
7147                        {":path", "/this/is/request/one"},
7148                        {"content-length", "2"}})
7149           .Data(1, "hi", /*fin=*/true)
7150           .Headers(3,
7151                    {{":method", "GET"},
7152                     {":scheme", "https"},
7153                     {":authority", "example.com"},
7154                     {":path", "/this/is/request/two"},
7155                     {"content-length", "nan"}},
7156                    /*fin=*/true)
7157           .Serialize();
7158 
7159   // Client preface (empty SETTINGS)
7160   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7161   EXPECT_CALL(visitor, OnSettingsStart());
7162   EXPECT_CALL(visitor, OnSettingsEnd());
7163 
7164   // Stream 1: content-length is correct
7165   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
7166   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7167   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
7168   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7169   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
7170   EXPECT_CALL(visitor, OnBeginDataForStream(1, 2));
7171   EXPECT_CALL(visitor, OnDataForStream(1, "hi"));
7172   EXPECT_CALL(visitor, OnEndStream(1));
7173 
7174   // Stream 3: content-length is not a number
7175   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
7176   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
7177   EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
7178   EXPECT_CALL(
7179       visitor,
7180       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
7181                    "stream: 3, name: [content-length], value: [nan]"));
7182   EXPECT_CALL(
7183       visitor,
7184       OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7185 
7186   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7187   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7188 
7189   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
7190   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
7191   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
7192   EXPECT_CALL(visitor,
7193               OnFrameSent(RST_STREAM, 3, _, 0x0,
7194                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7195   EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
7196 
7197   EXPECT_TRUE(adapter->want_write());
7198   int result = adapter->Send();
7199   EXPECT_EQ(0, result);
7200   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
7201                                             SpdyFrameType::RST_STREAM}));
7202 }
7203 
TEST(NgHttp2AdapterTest,ServerHandlesContentLengthMismatch)7204 TEST(NgHttp2AdapterTest, ServerHandlesContentLengthMismatch) {
7205   DataSavingVisitor visitor;
7206   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
7207 
7208   testing::InSequence s;
7209 
7210   const std::string stream_frames =
7211       TestFrameSequence()
7212           .ClientPreface()
7213           .Headers(1, {{":method", "GET"},
7214                        {":scheme", "https"},
7215                        {":authority", "example.com"},
7216                        {":path", "/this/is/request/two"},
7217                        {"content-length", "2"}})
7218           .Data(1, "h", /*fin=*/true)
7219           .Headers(3, {{":method", "GET"},
7220                        {":scheme", "https"},
7221                        {":authority", "example.com"},
7222                        {":path", "/this/is/request/three"},
7223                        {"content-length", "2"}})
7224           .Data(3, "howdy", /*fin=*/true)
7225           .Headers(5,
7226                    {{":method", "GET"},
7227                     {":scheme", "https"},
7228                     {":authority", "example.com"},
7229                     {":path", "/this/is/request/four"},
7230                     {"content-length", "2"}},
7231                    /*fin=*/true)
7232           .Headers(7,
7233                    {{":method", "GET"},
7234                     {":scheme", "https"},
7235                     {":authority", "example.com"},
7236                     {":path", "/this/is/request/four"},
7237                     {"content-length", "2"}},
7238                    /*fin=*/false)
7239           .Data(7, "h", /*fin=*/false)
7240           .Headers(7, {{"extra-info", "Trailers with content-length mismatch"}},
7241                    /*fin=*/true)
7242           .Serialize();
7243 
7244   // Client preface (empty SETTINGS)
7245   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7246   EXPECT_CALL(visitor, OnSettingsStart());
7247   EXPECT_CALL(visitor, OnSettingsEnd());
7248 
7249   // Stream 1: content-length is larger than actual data
7250   // All data is delivered to the visitor, but OnInvalidFrame() is not.
7251   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
7252   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7253   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
7254   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7255   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
7256   EXPECT_CALL(visitor, OnBeginDataForStream(1, 1));
7257   EXPECT_CALL(visitor, OnDataForStream(1, "h"));
7258 
7259   // Stream 3: content-length is smaller than actual data
7260   // The beginning of data is delivered to the visitor, but not the actual data,
7261   // and neither is OnInvalidFrame().
7262   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
7263   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
7264   EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
7265   EXPECT_CALL(visitor, OnEndHeadersForStream(3));
7266   EXPECT_CALL(visitor, OnFrameHeader(3, _, DATA, 1));
7267   EXPECT_CALL(visitor, OnBeginDataForStream(3, 5));
7268 
7269   // Stream 5: content-length is invalid and HEADERS ends the stream
7270   // When the stream ends with HEADERS, nghttp2 invokes OnInvalidFrame().
7271   EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
7272   EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
7273   EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(5);
7274   EXPECT_CALL(visitor,
7275               OnInvalidFrame(
7276                   5, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
7277 
7278   // Stream 7: content-length is invalid and trailers end the stream
7279   // When the stream ends with trailers, nghttp2 invokes OnInvalidFrame().
7280   EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 4));
7281   EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
7282   EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(5);
7283   EXPECT_CALL(visitor, OnEndHeadersForStream(7));
7284   EXPECT_CALL(visitor, OnFrameHeader(7, _, DATA, 0));
7285   EXPECT_CALL(visitor, OnBeginDataForStream(7, 1));
7286   EXPECT_CALL(visitor, OnDataForStream(7, "h"));
7287   EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
7288   EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
7289   EXPECT_CALL(visitor, OnHeaderForStream(7, _, _));
7290   EXPECT_CALL(visitor,
7291               OnInvalidFrame(
7292                   7, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
7293 
7294   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7295   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7296 
7297   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
7298   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
7299   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
7300   EXPECT_CALL(visitor,
7301               OnFrameSent(RST_STREAM, 1, _, 0x0,
7302                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7303   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
7304   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
7305   EXPECT_CALL(visitor,
7306               OnFrameSent(RST_STREAM, 3, _, 0x0,
7307                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7308   EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
7309   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
7310   EXPECT_CALL(visitor,
7311               OnFrameSent(RST_STREAM, 5, _, 0x0,
7312                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7313   EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::PROTOCOL_ERROR));
7314   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
7315   EXPECT_CALL(visitor,
7316               OnFrameSent(RST_STREAM, 7, _, 0x0,
7317                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7318   EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::PROTOCOL_ERROR));
7319 
7320   EXPECT_TRUE(adapter->want_write());
7321   int result = adapter->Send();
7322   EXPECT_EQ(0, result);
7323   EXPECT_THAT(
7324       visitor.data(),
7325       EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
7326                     SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
7327                     SpdyFrameType::RST_STREAM}));
7328 }
7329 
TEST(NgHttp2AdapterTest,ServerHandlesAsteriskPathForOptions)7330 TEST(NgHttp2AdapterTest, ServerHandlesAsteriskPathForOptions) {
7331   DataSavingVisitor visitor;
7332   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
7333 
7334   testing::InSequence s;
7335 
7336   const std::string stream_frames = TestFrameSequence()
7337                                         .ClientPreface()
7338                                         .Headers(1,
7339                                                  {{":scheme", "https"},
7340                                                   {":authority", "example.com"},
7341                                                   {":path", "*"},
7342                                                   {":method", "OPTIONS"}},
7343                                                  /*fin=*/true)
7344                                         .Serialize();
7345 
7346   // Client preface (empty SETTINGS)
7347   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7348   EXPECT_CALL(visitor, OnSettingsStart());
7349   EXPECT_CALL(visitor, OnSettingsEnd());
7350 
7351   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
7352   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7353   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7354   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7355   EXPECT_CALL(visitor, OnEndStream(1));
7356 
7357   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7358   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7359 
7360   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
7361   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
7362 
7363   EXPECT_TRUE(adapter->want_write());
7364   int result = adapter->Send();
7365   EXPECT_EQ(0, result);
7366   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
7367 }
7368 
TEST(NgHttp2AdapterTest,ServerHandlesInvalidPath)7369 TEST(NgHttp2AdapterTest, ServerHandlesInvalidPath) {
7370   DataSavingVisitor visitor;
7371   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
7372 
7373   testing::InSequence s;
7374 
7375   const std::string stream_frames =
7376       TestFrameSequence()
7377           .ClientPreface()
7378           .Headers(1,
7379                    {{":scheme", "https"},
7380                     {":authority", "example.com"},
7381                     {":path", "*"},
7382                     {":method", "GET"}},
7383                    /*fin=*/true)
7384           .Headers(3,
7385                    {{":scheme", "https"},
7386                     {":authority", "example.com"},
7387                     {":path", "other/non/slash/starter"},
7388                     {":method", "GET"}},
7389                    /*fin=*/true)
7390           .Headers(5,
7391                    {{":scheme", "https"},
7392                     {":authority", "example.com"},
7393                     {":path", ""},
7394                     {":method", "GET"}},
7395                    /*fin=*/true)
7396           .Serialize();
7397 
7398   // Client preface (empty SETTINGS)
7399   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7400   EXPECT_CALL(visitor, OnSettingsStart());
7401   EXPECT_CALL(visitor, OnSettingsEnd());
7402 
7403   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
7404   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7405   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7406   EXPECT_CALL(visitor,
7407               OnInvalidFrame(
7408                   1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
7409 
7410   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
7411   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
7412   EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
7413   EXPECT_CALL(visitor,
7414               OnInvalidFrame(
7415                   3, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
7416 
7417   EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
7418   EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
7419   EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(2);
7420   EXPECT_CALL(
7421       visitor,
7422       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
7423                    "stream: 5, name: [:path], value: []"));
7424   EXPECT_CALL(
7425       visitor,
7426       OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7427 
7428   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7429   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7430 
7431   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
7432   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
7433   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
7434   EXPECT_CALL(visitor,
7435               OnFrameSent(RST_STREAM, 1, _, 0x0,
7436                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7437   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
7438   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
7439   EXPECT_CALL(visitor,
7440               OnFrameSent(RST_STREAM, 3, _, 0x0,
7441                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7442   EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
7443   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
7444   EXPECT_CALL(visitor,
7445               OnFrameSent(RST_STREAM, 5, _, 0x0,
7446                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7447   EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::PROTOCOL_ERROR));
7448 
7449   EXPECT_TRUE(adapter->want_write());
7450   int result = adapter->Send();
7451   EXPECT_EQ(0, result);
7452   EXPECT_THAT(
7453       visitor.data(),
7454       EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
7455                     SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
7456 }
7457 
TEST(NgHttp2AdapterTest,ServerHandlesTeHeader)7458 TEST(NgHttp2AdapterTest, ServerHandlesTeHeader) {
7459   DataSavingVisitor visitor;
7460   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
7461 
7462   testing::InSequence s;
7463 
7464   const std::string stream_frames = TestFrameSequence()
7465                                         .ClientPreface()
7466                                         .Headers(1,
7467                                                  {{":scheme", "https"},
7468                                                   {":authority", "example.com"},
7469                                                   {":path", "/"},
7470                                                   {":method", "GET"},
7471                                                   {"te", "trailers"}},
7472                                                  /*fin=*/true)
7473                                         .Headers(3,
7474                                                  {{":scheme", "https"},
7475                                                   {":authority", "example.com"},
7476                                                   {":path", "/"},
7477                                                   {":method", "GET"},
7478                                                   {"te", "trailers, deflate"}},
7479                                                  /*fin=*/true)
7480                                         .Serialize();
7481 
7482   // Client preface (empty SETTINGS)
7483   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7484   EXPECT_CALL(visitor, OnSettingsStart());
7485   EXPECT_CALL(visitor, OnSettingsEnd());
7486 
7487   // Stream 1: TE: trailers should be allowed.
7488   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
7489   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7490   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
7491   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7492   EXPECT_CALL(visitor, OnEndStream(1));
7493 
7494   // Stream 3: TE: <non-trailers> should be rejected.
7495   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
7496   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
7497   EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
7498   EXPECT_CALL(
7499       visitor,
7500       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
7501                    "stream: 3, name: [te], value: [trailers, deflate]"));
7502   EXPECT_CALL(
7503       visitor,
7504       OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7505 
7506   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7507   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7508 
7509   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
7510   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
7511   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
7512   EXPECT_CALL(visitor,
7513               OnFrameSent(RST_STREAM, 3, _, 0x0,
7514                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7515   EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
7516 
7517   EXPECT_TRUE(adapter->want_write());
7518   int result = adapter->Send();
7519   EXPECT_EQ(0, result);
7520   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
7521                                             SpdyFrameType::RST_STREAM}));
7522 }
7523 
TEST(NgHttp2AdapterTest,ServerHandlesConnectionSpecificHeaders)7524 TEST(NgHttp2AdapterTest, ServerHandlesConnectionSpecificHeaders) {
7525   DataSavingVisitor visitor;
7526   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
7527 
7528   testing::InSequence s;
7529 
7530   const std::string stream_frames =
7531       TestFrameSequence()
7532           .ClientPreface()
7533           .Headers(1,
7534                    {{":scheme", "https"},
7535                     {":authority", "example.com"},
7536                     {":path", "/"},
7537                     {":method", "GET"},
7538                     {"connection", "keep-alive"}},
7539                    /*fin=*/true)
7540           .Headers(3,
7541                    {{":scheme", "https"},
7542                     {":authority", "example.com"},
7543                     {":path", "/"},
7544                     {":method", "GET"},
7545                     {"proxy-connection", "keep-alive"}},
7546                    /*fin=*/true)
7547           .Headers(5,
7548                    {{":scheme", "https"},
7549                     {":authority", "example.com"},
7550                     {":path", "/"},
7551                     {":method", "GET"},
7552                     {"keep-alive", "timeout=42"}},
7553                    /*fin=*/true)
7554           .Headers(7,
7555                    {{":scheme", "https"},
7556                     {":authority", "example.com"},
7557                     {":path", "/"},
7558                     {":method", "GET"},
7559                     {"transfer-encoding", "chunked"}},
7560                    /*fin=*/true)
7561           .Headers(9,
7562                    {{":scheme", "https"},
7563                     {":authority", "example.com"},
7564                     {":path", "/"},
7565                     {":method", "GET"},
7566                     {"upgrade", "h2c"}},
7567                    /*fin=*/true)
7568           .Serialize();
7569 
7570   // Client preface (empty SETTINGS)
7571   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7572   EXPECT_CALL(visitor, OnSettingsStart());
7573   EXPECT_CALL(visitor, OnSettingsEnd());
7574 
7575   // All streams contain a connection-specific header and should be rejected.
7576   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
7577   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7578   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7579   EXPECT_CALL(
7580       visitor,
7581       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
7582                    "stream: 1, name: [connection], value: [keep-alive]"));
7583   EXPECT_CALL(
7584       visitor,
7585       OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7586   EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
7587   EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
7588   EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
7589   EXPECT_CALL(
7590       visitor,
7591       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
7592                    "stream: 3, name: [proxy-connection], value: [keep-alive]"));
7593   EXPECT_CALL(
7594       visitor,
7595       OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7596   EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
7597   EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
7598   EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(4);
7599   EXPECT_CALL(
7600       visitor,
7601       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
7602                    "stream: 5, name: [keep-alive], value: [timeout=42]"));
7603   EXPECT_CALL(
7604       visitor,
7605       OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7606   EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
7607   EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
7608   EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(4);
7609   EXPECT_CALL(
7610       visitor,
7611       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
7612                    "stream: 7, name: [transfer-encoding], value: [chunked]"));
7613   EXPECT_CALL(
7614       visitor,
7615       OnInvalidFrame(7, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7616   EXPECT_CALL(visitor, OnFrameHeader(9, _, HEADERS, 5));
7617   EXPECT_CALL(visitor, OnBeginHeadersForStream(9));
7618   EXPECT_CALL(visitor, OnHeaderForStream(9, _, _)).Times(4);
7619   EXPECT_CALL(
7620       visitor,
7621       OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
7622                    "stream: 9, name: [upgrade], value: [h2c]"));
7623   EXPECT_CALL(
7624       visitor,
7625       OnInvalidFrame(9, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7626 
7627   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7628   EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7629 
7630   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
7631   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
7632   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
7633   EXPECT_CALL(visitor,
7634               OnFrameSent(RST_STREAM, 1, _, 0x0,
7635                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7636   EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
7637   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
7638   EXPECT_CALL(visitor,
7639               OnFrameSent(RST_STREAM, 3, _, 0x0,
7640                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7641   EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
7642   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
7643   EXPECT_CALL(visitor,
7644               OnFrameSent(RST_STREAM, 5, _, 0x0,
7645                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7646   EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::PROTOCOL_ERROR));
7647   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
7648   EXPECT_CALL(visitor,
7649               OnFrameSent(RST_STREAM, 7, _, 0x0,
7650                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7651   EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::PROTOCOL_ERROR));
7652   EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 9, _, 0x0));
7653   EXPECT_CALL(visitor,
7654               OnFrameSent(RST_STREAM, 9, _, 0x0,
7655                           static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7656   EXPECT_CALL(visitor, OnCloseStream(9, Http2ErrorCode::PROTOCOL_ERROR));
7657 
7658   EXPECT_TRUE(adapter->want_write());
7659   int result = adapter->Send();
7660   EXPECT_EQ(0, result);
7661   EXPECT_THAT(
7662       visitor.data(),
7663       EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
7664                     SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
7665                     SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
7666 }
7667 
TEST(OgHttp2AdapterTest,ServerConsumesDataWithPadding)7668 TEST(OgHttp2AdapterTest, ServerConsumesDataWithPadding) {
7669   DataSavingVisitor visitor;
7670   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
7671 
7672   TestFrameSequence seq = std::move(TestFrameSequence().ClientPreface().Headers(
7673       1,
7674       {{":method", "POST"},
7675        {":scheme", "https"},
7676        {":authority", "example.com"},
7677        {":path", "/this/is/request/one"}},
7678       /*fin=*/false));
7679   // Generates a bunch of DATA frames, with the bulk of the payloads consisting
7680   // of padding.
7681   size_t total_size = 0;
7682   while (total_size < 62 * 1024) {
7683     seq.Data(1, "a", /*fin=*/false, /*padding=*/254);
7684     total_size += 255;
7685   }
7686   const std::string frames = seq.Serialize();
7687 
7688   // Client preface (empty SETTINGS)
7689   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7690   EXPECT_CALL(visitor, OnSettingsStart());
7691   EXPECT_CALL(visitor, OnSettingsEnd());
7692 
7693   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
7694   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7695   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7696   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7697   EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0x8))
7698       .Times(testing::AtLeast(1));
7699   EXPECT_CALL(visitor, OnBeginDataForStream(1, _)).Times(testing::AtLeast(1));
7700   EXPECT_CALL(visitor, OnDataForStream(1, "a")).Times(testing::AtLeast(1));
7701   EXPECT_CALL(visitor, OnDataPaddingLength(1, _)).Times(testing::AtLeast(1));
7702 
7703   const int64_t result = adapter->ProcessBytes(frames);
7704   EXPECT_EQ(result, frames.size());
7705 
7706   EXPECT_TRUE(adapter->want_write());
7707 
7708   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
7709   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
7710   // Since most of the flow control window consumed is padding, the adapter
7711   // generates window updates.
7712   EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 1, _, 0x0)).Times(1);
7713   EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 1, _, 0x0, 0)).Times(1);
7714   EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, _, 0x0)).Times(1);
7715   EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, _, 0x0, 0)).Times(1);
7716 
7717   const int send_result = adapter->Send();
7718   EXPECT_EQ(0, send_result);
7719   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
7720                                             SpdyFrameType::WINDOW_UPDATE,
7721                                             SpdyFrameType::WINDOW_UPDATE}));
7722 }
7723 
TEST(NgHttp2AdapterTest,NegativeFlowControlStreamResumption)7724 TEST(NgHttp2AdapterTest, NegativeFlowControlStreamResumption) {
7725   DataSavingVisitor visitor;
7726   auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
7727 
7728   const std::string frames =
7729       TestFrameSequence()
7730           .ClientPreface({{INITIAL_WINDOW_SIZE, 128u * 1024u}})
7731           .WindowUpdate(0, 1 << 20)
7732           .Headers(1,
7733                    {{":method", "GET"},
7734                     {":scheme", "https"},
7735                     {":authority", "example.com"},
7736                     {":path", "/this/is/request/one"}},
7737                    /*fin=*/true)
7738           .Serialize();
7739   testing::InSequence s;
7740 
7741   // Client preface (empty SETTINGS)
7742   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
7743   EXPECT_CALL(visitor, OnSettingsStart());
7744   EXPECT_CALL(visitor,
7745               OnSetting(Http2Setting{Http2KnownSettingsId::INITIAL_WINDOW_SIZE,
7746                                      128u * 1024u}));
7747   EXPECT_CALL(visitor, OnSettingsEnd());
7748 
7749   EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
7750   EXPECT_CALL(visitor, OnWindowUpdate(0, 1 << 20));
7751 
7752   // Stream 1
7753   EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
7754   EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7755   EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7756   EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7757   EXPECT_CALL(visitor, OnEndStream(1));
7758 
7759   const int64_t read_result = adapter->ProcessBytes(frames);
7760   EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
7761 
7762   // Submit a response for the stream.
7763   auto body = std::make_unique<TestDataFrameSource>(visitor, true);
7764   TestDataFrameSource& body_ref = *body;
7765   body_ref.AppendPayload(std::string(70000, 'a'));
7766   int submit_result = adapter->SubmitResponse(
7767       1, ToHeaders({{":status", "200"}}), std::move(body));
7768   ASSERT_EQ(0, submit_result);
7769 
7770   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
7771   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
7772   EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
7773   EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
7774   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0)).Times(5);
7775 
7776   adapter->Send();
7777   EXPECT_FALSE(adapter->want_write());
7778 
7779   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
7780   EXPECT_CALL(visitor, OnSettingsStart());
7781   EXPECT_CALL(visitor,
7782               OnSetting(Http2Setting{Http2KnownSettingsId::INITIAL_WINDOW_SIZE,
7783                                      64u * 1024u}));
7784   EXPECT_CALL(visitor, OnSettingsEnd());
7785 
7786   // Processing these SETTINGS will cause stream 1's send window to become
7787   // negative.
7788   adapter->ProcessBytes(TestFrameSequence()
7789                             .Settings({{INITIAL_WINDOW_SIZE, 64u * 1024u}})
7790                             .Serialize());
7791   EXPECT_TRUE(adapter->want_write());
7792   // nghttp2 does not expose the fact that the send window size is negative.
7793   EXPECT_EQ(adapter->GetStreamSendWindowSize(1), 0);
7794 
7795   body_ref.AppendPayload("Stream should be resumed.");
7796   adapter->ResumeStream(1);
7797 
7798   EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
7799   EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
7800   adapter->Send();
7801   EXPECT_FALSE(adapter->want_write());
7802 
7803   // Upon receiving the WINDOW_UPDATE, stream 1 should be ready to write.
7804   EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
7805   EXPECT_CALL(visitor, OnWindowUpdate(1, 10000));
7806   adapter->ProcessBytes(TestFrameSequence().WindowUpdate(1, 10000).Serialize());
7807   EXPECT_TRUE(adapter->want_write());
7808   EXPECT_GT(adapter->GetStreamSendWindowSize(1), 0);
7809 
7810   EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
7811   adapter->Send();
7812 }
7813 
7814 }  // namespace
7815 }  // namespace test
7816 }  // namespace adapter
7817 }  // namespace http2
7818