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