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,ServerSubmitsResponseWithDataSourceError)4473 TEST(OgHttp2AdapterTest, ServerSubmitsResponseWithDataSourceError) {
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 = TestFrameSequence()
4481 .ClientPreface()
4482 .Headers(1,
4483 {{":method", "GET"},
4484 {":scheme", "https"},
4485 {":authority", "example.com"},
4486 {":path", "/this/is/request/one"}},
4487 /*fin=*/true)
4488 .Serialize();
4489 testing::InSequence s;
4490
4491 // Client preface (empty SETTINGS)
4492 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4493 EXPECT_CALL(visitor, OnSettingsStart());
4494 EXPECT_CALL(visitor, OnSettingsEnd());
4495 // Stream 1
4496 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
4497 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4498 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
4499 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
4500 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
4501 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
4502 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4503 EXPECT_CALL(visitor, OnEndStream(1));
4504
4505 const int64_t result = adapter->ProcessBytes(frames);
4506 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4507
4508 auto body1 = std::make_unique<TestDataFrameSource>(visitor, false);
4509 body1->SimulateError();
4510 int submit_result = adapter->SubmitResponse(
4511 1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
4512 std::move(body1));
4513 EXPECT_EQ(submit_result, 0);
4514 EXPECT_TRUE(adapter->want_write());
4515
4516 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
4517 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
4518 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
4519 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
4520 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
4521 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
4522 // TODO(birenroy): Send RST_STREAM INTERNAL_ERROR to the client as well.
4523 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
4524
4525 int send_result = adapter->Send();
4526 EXPECT_EQ(0, send_result);
4527 EXPECT_THAT(visitor.data(),
4528 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
4529 SpdyFrameType::HEADERS}));
4530 visitor.Clear();
4531 EXPECT_FALSE(adapter->want_write());
4532
4533 // Since the stream has been closed, it is not possible to submit trailers for
4534 // the stream.
4535 int trailer_result =
4536 adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
4537 ASSERT_LT(trailer_result, 0);
4538 EXPECT_FALSE(adapter->want_write());
4539 }
4540
TEST(OgHttp2AdapterTest,CompleteRequestWithServerResponse)4541 TEST(OgHttp2AdapterTest, CompleteRequestWithServerResponse) {
4542 DataSavingVisitor visitor;
4543 OgHttp2Adapter::Options options;
4544 options.perspective = Perspective::kServer;
4545 auto adapter = OgHttp2Adapter::Create(visitor, options);
4546 EXPECT_FALSE(adapter->want_write());
4547
4548 const std::string frames =
4549 TestFrameSequence()
4550 .ClientPreface()
4551 .Headers(1,
4552 {{":method", "GET"},
4553 {":scheme", "https"},
4554 {":authority", "example.com"},
4555 {":path", "/this/is/request/one"}},
4556 /*fin=*/false)
4557 .Data(1, "This is the response body.", /*fin=*/true)
4558 .Serialize();
4559 testing::InSequence s;
4560
4561 // Client preface (empty SETTINGS)
4562 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4563 EXPECT_CALL(visitor, OnSettingsStart());
4564 EXPECT_CALL(visitor, OnSettingsEnd());
4565 // Stream 1
4566 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4567 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4568 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
4569 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4570 EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
4571 EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
4572 EXPECT_CALL(visitor, OnDataForStream(1, _));
4573 EXPECT_CALL(visitor, OnEndStream(1));
4574
4575 const int64_t result = adapter->ProcessBytes(frames);
4576 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4577
4578 int submit_result =
4579 adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
4580 EXPECT_EQ(submit_result, 0);
4581 EXPECT_TRUE(adapter->want_write());
4582
4583 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
4584 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
4585 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
4586 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
4587 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _,
4588 END_STREAM_FLAG | END_HEADERS_FLAG));
4589 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _,
4590 END_STREAM_FLAG | END_HEADERS_FLAG, 0));
4591 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
4592
4593 int send_result = adapter->Send();
4594 EXPECT_EQ(0, send_result);
4595 EXPECT_THAT(visitor.data(),
4596 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
4597 SpdyFrameType::HEADERS}));
4598 EXPECT_FALSE(adapter->want_write());
4599 }
4600
TEST(OgHttp2AdapterTest,IncompleteRequestWithServerResponse)4601 TEST(OgHttp2AdapterTest, IncompleteRequestWithServerResponse) {
4602 DataSavingVisitor visitor;
4603 OgHttp2Adapter::Options options;
4604 options.perspective = Perspective::kServer;
4605 auto adapter = OgHttp2Adapter::Create(visitor, options);
4606 EXPECT_FALSE(adapter->want_write());
4607
4608 const std::string frames = TestFrameSequence()
4609 .ClientPreface()
4610 .Headers(1,
4611 {{":method", "GET"},
4612 {":scheme", "https"},
4613 {":authority", "example.com"},
4614 {":path", "/this/is/request/one"}},
4615 /*fin=*/false)
4616 .Serialize();
4617 testing::InSequence s;
4618
4619 // Client preface (empty SETTINGS)
4620 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4621 EXPECT_CALL(visitor, OnSettingsStart());
4622 EXPECT_CALL(visitor, OnSettingsEnd());
4623 // Stream 1
4624 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4625 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4626 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
4627 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4628
4629 const int64_t result = adapter->ProcessBytes(frames);
4630 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4631
4632 int submit_result =
4633 adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
4634 EXPECT_EQ(submit_result, 0);
4635 EXPECT_TRUE(adapter->want_write());
4636
4637 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
4638 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
4639 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
4640 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
4641 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _,
4642 END_STREAM_FLAG | END_HEADERS_FLAG));
4643 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _,
4644 END_STREAM_FLAG | END_HEADERS_FLAG, 0));
4645 // RST_STREAM NO_ERROR option is disabled.
4646
4647 int send_result = adapter->Send();
4648 EXPECT_EQ(0, send_result);
4649 EXPECT_THAT(visitor.data(),
4650 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
4651 SpdyFrameType::HEADERS}));
4652 EXPECT_FALSE(adapter->want_write());
4653 }
4654
TEST(OgHttp2AdapterTest,IncompleteRequestWithServerResponseRstStreamEnabled)4655 TEST(OgHttp2AdapterTest, IncompleteRequestWithServerResponseRstStreamEnabled) {
4656 DataSavingVisitor visitor;
4657 OgHttp2Adapter::Options options;
4658 options.perspective = Perspective::kServer;
4659 options.rst_stream_no_error_when_incomplete = true;
4660 auto adapter = OgHttp2Adapter::Create(visitor, options);
4661 EXPECT_FALSE(adapter->want_write());
4662
4663 const std::string frames = TestFrameSequence()
4664 .ClientPreface()
4665 .Headers(1,
4666 {{":method", "GET"},
4667 {":scheme", "https"},
4668 {":authority", "example.com"},
4669 {":path", "/this/is/request/one"}},
4670 /*fin=*/false)
4671 .Serialize();
4672 testing::InSequence s;
4673
4674 // Client preface (empty SETTINGS)
4675 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4676 EXPECT_CALL(visitor, OnSettingsStart());
4677 EXPECT_CALL(visitor, OnSettingsEnd());
4678 // Stream 1
4679 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4680 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4681 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
4682 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4683
4684 const int64_t result = adapter->ProcessBytes(frames);
4685 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4686
4687 int submit_result =
4688 adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
4689 EXPECT_EQ(submit_result, 0);
4690 EXPECT_TRUE(adapter->want_write());
4691
4692 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
4693 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
4694 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
4695 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
4696 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _,
4697 END_STREAM_FLAG | END_HEADERS_FLAG));
4698 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _,
4699 END_STREAM_FLAG | END_HEADERS_FLAG, 0));
4700 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
4701 EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, 4, 0x0, 0));
4702 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
4703
4704 int send_result = adapter->Send();
4705 EXPECT_EQ(0, send_result);
4706 EXPECT_THAT(
4707 visitor.data(),
4708 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
4709 SpdyFrameType::HEADERS, SpdyFrameType::RST_STREAM}));
4710 EXPECT_FALSE(adapter->want_write());
4711 }
4712
TEST(OgHttp2AdapterTest,ServerHandlesMultipleContentLength)4713 TEST(OgHttp2AdapterTest, ServerHandlesMultipleContentLength) {
4714 DataSavingVisitor visitor;
4715 OgHttp2Adapter::Options options;
4716 options.perspective = Perspective::kServer;
4717 auto adapter = OgHttp2Adapter::Create(visitor, options);
4718 EXPECT_FALSE(adapter->want_write());
4719
4720 const std::string frames = TestFrameSequence()
4721 .ClientPreface()
4722 .Headers(1,
4723 {{":method", "POST"},
4724 {":scheme", "https"},
4725 {":authority", "example.com"},
4726 {":path", "/1"},
4727 {"content-length", "7"},
4728 {"content-length", "7"}},
4729 /*fin=*/false)
4730 .Headers(3,
4731 {{":method", "POST"},
4732 {":scheme", "https"},
4733 {":authority", "example.com"},
4734 {":path", "/3"},
4735 {"content-length", "11"},
4736 {"content-length", "13"}},
4737 /*fin=*/false)
4738 .Serialize();
4739 testing::InSequence s;
4740
4741 // Client preface (empty SETTINGS)
4742 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4743 EXPECT_CALL(visitor, OnSettingsStart());
4744 EXPECT_CALL(visitor, OnSettingsEnd());
4745 // Stream 1
4746 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4747 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4748 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
4749 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
4750 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
4751 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/1"));
4752 EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "7"));
4753 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4754 // Stream 3
4755 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
4756 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
4757 EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "POST"));
4758 EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "https"));
4759 EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
4760 EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/3"));
4761 EXPECT_CALL(visitor, OnHeaderForStream(3, "content-length", "11"));
4762 EXPECT_CALL(
4763 visitor,
4764 OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
4765
4766 const int64_t result = adapter->ProcessBytes(frames);
4767 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4768 }
4769
TEST(OgHttp2AdapterTest,ServerSendsInvalidTrailers)4770 TEST(OgHttp2AdapterTest, ServerSendsInvalidTrailers) {
4771 DataSavingVisitor visitor;
4772 OgHttp2Adapter::Options options;
4773 options.perspective = Perspective::kServer;
4774 auto adapter = OgHttp2Adapter::Create(visitor, options);
4775 EXPECT_FALSE(adapter->want_write());
4776
4777 const std::string frames = TestFrameSequence()
4778 .ClientPreface()
4779 .Headers(1,
4780 {{":method", "GET"},
4781 {":scheme", "https"},
4782 {":authority", "example.com"},
4783 {":path", "/this/is/request/one"}},
4784 /*fin=*/true)
4785 .Serialize();
4786 testing::InSequence s;
4787
4788 // Client preface (empty SETTINGS)
4789 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4790 EXPECT_CALL(visitor, OnSettingsStart());
4791 EXPECT_CALL(visitor, OnSettingsEnd());
4792 // Stream 1
4793 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
4794 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4795 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
4796 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
4797 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
4798 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
4799 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4800 EXPECT_CALL(visitor, OnEndStream(1));
4801
4802 const int64_t result = adapter->ProcessBytes(frames);
4803 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4804
4805 const absl::string_view kBody = "This is an example response body.";
4806
4807 // The body source must indicate that the end of the body is not the end of
4808 // the stream.
4809 auto body1 = std::make_unique<TestDataFrameSource>(visitor, false);
4810 body1->AppendPayload(kBody);
4811 body1->EndData();
4812 int submit_result = adapter->SubmitResponse(
4813 1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
4814 std::move(body1));
4815 EXPECT_EQ(submit_result, 0);
4816 EXPECT_TRUE(adapter->want_write());
4817
4818 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
4819 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
4820 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
4821 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
4822 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
4823 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
4824 EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
4825
4826 int send_result = adapter->Send();
4827 EXPECT_EQ(0, send_result);
4828 EXPECT_THAT(visitor.data(),
4829 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
4830 SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
4831 EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
4832 visitor.Clear();
4833 EXPECT_FALSE(adapter->want_write());
4834
4835 // The body source has been exhausted by the call to Send() above.
4836 int trailer_result =
4837 adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
4838 ASSERT_EQ(trailer_result, 0);
4839 EXPECT_TRUE(adapter->want_write());
4840
4841 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _,
4842 END_STREAM_FLAG | END_HEADERS_FLAG));
4843 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _,
4844 END_STREAM_FLAG | END_HEADERS_FLAG, 0));
4845 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
4846
4847 send_result = adapter->Send();
4848 EXPECT_EQ(0, send_result);
4849 EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
4850 }
4851
TEST(OgHttp2AdapterTest,ServerHandlesDataWithPadding)4852 TEST(OgHttp2AdapterTest, ServerHandlesDataWithPadding) {
4853 DataSavingVisitor visitor;
4854 OgHttp2Adapter::Options options;
4855 options.perspective = Perspective::kServer;
4856 auto adapter = OgHttp2Adapter::Create(visitor, options);
4857
4858 const std::string frames = TestFrameSequence()
4859 .ClientPreface()
4860 .Headers(1,
4861 {{":method", "POST"},
4862 {":scheme", "https"},
4863 {":authority", "example.com"},
4864 {":path", "/this/is/request/one"}},
4865 /*fin=*/false)
4866 .Data(1, "This is the request body.",
4867 /*fin=*/true, /*padding_length=*/39)
4868 .Headers(3,
4869 {{":method", "GET"},
4870 {":scheme", "http"},
4871 {":authority", "example.com"},
4872 {":path", "/this/is/request/two"}},
4873 /*fin=*/true)
4874 .Serialize();
4875 testing::InSequence s;
4876
4877 // Client preface (empty SETTINGS)
4878 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4879 EXPECT_CALL(visitor, OnSettingsStart());
4880 EXPECT_CALL(visitor, OnSettingsEnd());
4881
4882 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
4883 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4884 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
4885 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4886 EXPECT_CALL(visitor, OnFrameHeader(1, 25 + 39, DATA, 0x9));
4887 EXPECT_CALL(visitor, OnBeginDataForStream(1, 25 + 39));
4888 // Note: oghttp2 passes padding information before the actual data.
4889 EXPECT_CALL(visitor, OnDataPaddingLength(1, 39));
4890 EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
4891 EXPECT_CALL(visitor, OnEndStream(1));
4892 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
4893 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
4894 EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
4895 EXPECT_CALL(visitor, OnEndHeadersForStream(3));
4896 EXPECT_CALL(visitor, OnEndStream(3));
4897
4898 const int64_t result = adapter->ProcessBytes(frames);
4899 EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
4900
4901 EXPECT_TRUE(adapter->want_write());
4902
4903 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
4904 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
4905 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
4906 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
4907
4908 int send_result = adapter->Send();
4909 EXPECT_EQ(0, send_result);
4910 EXPECT_THAT(visitor.data(),
4911 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
4912 }
4913
TEST(OgHttp2AdapterTest,ServerHandlesHostHeader)4914 TEST(OgHttp2AdapterTest, ServerHandlesHostHeader) {
4915 DataSavingVisitor visitor;
4916 OgHttp2Adapter::Options options;
4917 options.perspective = Perspective::kServer;
4918 auto adapter = OgHttp2Adapter::Create(visitor, options);
4919
4920 const std::string frames = TestFrameSequence()
4921 .ClientPreface()
4922 .Headers(1,
4923 {{":method", "POST"},
4924 {":scheme", "https"},
4925 {":path", "/this/is/request/one"},
4926 {"host", "example.com"}},
4927 /*fin=*/true)
4928 .Headers(3,
4929 {{":method", "POST"},
4930 {":scheme", "https"},
4931 {":authority", "example.com"},
4932 {":path", "/this/is/request/one"},
4933 {"host", "example.com"}},
4934 /*fin=*/true)
4935 .Headers(5,
4936 {{":method", "POST"},
4937 {":scheme", "https"},
4938 {":authority", "foo.com"},
4939 {":path", "/this/is/request/one"},
4940 {"host", "bar.com"}},
4941 /*fin=*/true)
4942 .Serialize();
4943
4944 testing::InSequence s;
4945
4946 // Client preface (empty SETTINGS)
4947 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
4948 EXPECT_CALL(visitor, OnSettingsStart());
4949 EXPECT_CALL(visitor, OnSettingsEnd());
4950
4951 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
4952 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
4953 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
4954 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
4955 EXPECT_CALL(visitor, OnEndStream(1));
4956
4957 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
4958 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
4959 EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
4960 EXPECT_CALL(visitor, OnEndHeadersForStream(3));
4961 EXPECT_CALL(visitor, OnEndStream(3));
4962
4963 EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
4964 EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
4965 EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(4);
4966 EXPECT_CALL(
4967 visitor,
4968 OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
4969
4970 const int64_t result = adapter->ProcessBytes(frames);
4971 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
4972
4973 EXPECT_TRUE(adapter->want_write());
4974
4975 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
4976 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
4977 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
4978 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
4979 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, 4, 0x0));
4980 EXPECT_CALL(visitor,
4981 OnFrameSent(RST_STREAM, 5, 4, 0x0,
4982 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
4983 EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
4984
4985 int send_result = adapter->Send();
4986 EXPECT_EQ(0, send_result);
4987 visitor.Clear();
4988 }
4989
TEST(OgHttp2AdapterTest,ServerHandlesHostHeaderWithLaxValidation)4990 TEST(OgHttp2AdapterTest, ServerHandlesHostHeaderWithLaxValidation) {
4991 DataSavingVisitor visitor;
4992 OgHttp2Adapter::Options options;
4993 options.perspective = Perspective::kServer;
4994 options.allow_different_host_and_authority = true;
4995 auto adapter = OgHttp2Adapter::Create(visitor, options);
4996
4997 const std::string frames = TestFrameSequence()
4998 .ClientPreface()
4999 .Headers(1,
5000 {{":method", "POST"},
5001 {":scheme", "https"},
5002 {":path", "/this/is/request/one"},
5003 {"host", "example.com"}},
5004 /*fin=*/true)
5005 .Headers(3,
5006 {{":method", "POST"},
5007 {":scheme", "https"},
5008 {":authority", "example.com"},
5009 {":path", "/this/is/request/one"},
5010 {"host", "example.com"}},
5011 /*fin=*/true)
5012 .Headers(5,
5013 {{":method", "POST"},
5014 {":scheme", "https"},
5015 {":authority", "foo.com"},
5016 {":path", "/this/is/request/one"},
5017 {"host", "bar.com"}},
5018 /*fin=*/true)
5019 .Serialize();
5020
5021 testing::InSequence s;
5022
5023 // Client preface (empty SETTINGS)
5024 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5025 EXPECT_CALL(visitor, OnSettingsStart());
5026 EXPECT_CALL(visitor, OnSettingsEnd());
5027
5028 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
5029 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5030 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
5031 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5032 EXPECT_CALL(visitor, OnEndStream(1));
5033
5034 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
5035 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
5036 EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
5037 EXPECT_CALL(visitor, OnEndHeadersForStream(3));
5038 EXPECT_CALL(visitor, OnEndStream(3));
5039
5040 EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
5041 EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
5042 EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(5);
5043 // No error, because the option is set to allow different host and authority
5044 // values.
5045 EXPECT_CALL(visitor, OnEndHeadersForStream(5));
5046 EXPECT_CALL(visitor, OnEndStream(5));
5047
5048 const int64_t result = adapter->ProcessBytes(frames);
5049 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5050
5051 EXPECT_TRUE(adapter->want_write());
5052
5053 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
5054 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
5055 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
5056 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
5057
5058 int send_result = adapter->Send();
5059 EXPECT_EQ(0, send_result);
5060 visitor.Clear();
5061 }
5062
5063 // Tests the case where the response body is in the progress of being sent while
5064 // trailers are queued.
TEST(OgHttp2AdapterTest,ServerSubmitsTrailersWhileDataDeferred)5065 TEST(OgHttp2AdapterTest, ServerSubmitsTrailersWhileDataDeferred) {
5066 DataSavingVisitor visitor;
5067 for (const bool queue_trailers : {true, false}) {
5068 OgHttp2Adapter::Options options;
5069 options.perspective = Perspective::kServer;
5070 options.trailers_require_end_data = queue_trailers;
5071 auto adapter = OgHttp2Adapter::Create(visitor, options);
5072
5073 const std::string frames = TestFrameSequence()
5074 .ClientPreface()
5075 .Headers(1,
5076 {{":method", "POST"},
5077 {":scheme", "https"},
5078 {":authority", "example.com"},
5079 {":path", "/this/is/request/one"}},
5080 /*fin=*/false)
5081 .WindowUpdate(1, 2000)
5082 .Data(1, "This is the request body.")
5083 .WindowUpdate(0, 2000)
5084 .Serialize();
5085 testing::InSequence s;
5086
5087 // Client preface (empty SETTINGS)
5088 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5089 EXPECT_CALL(visitor, OnSettingsStart());
5090 EXPECT_CALL(visitor, OnSettingsEnd());
5091
5092 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5093 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5094 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
5095 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5096 EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
5097 EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
5098 EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
5099 EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
5100 EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
5101 EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
5102 EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
5103
5104 const int64_t result = adapter->ProcessBytes(frames);
5105 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5106
5107 EXPECT_TRUE(adapter->want_write());
5108
5109 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
5110 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
5111 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
5112 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
5113
5114 int send_result = adapter->Send();
5115 EXPECT_EQ(0, send_result);
5116 visitor.Clear();
5117
5118 const absl::string_view kBody = "This is an example response body.";
5119
5120 // The body source must indicate that the end of the body is not the end of
5121 // the stream.
5122 auto body1 = std::make_unique<TestDataFrameSource>(visitor, false);
5123 body1->AppendPayload(kBody);
5124 auto* body1_ptr = body1.get();
5125 int submit_result = adapter->SubmitResponse(
5126 1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
5127 std::move(body1));
5128 EXPECT_EQ(submit_result, 0);
5129 EXPECT_TRUE(adapter->want_write());
5130
5131 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
5132 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
5133 EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
5134
5135 send_result = adapter->Send();
5136 EXPECT_EQ(0, send_result);
5137 visitor.Clear();
5138 EXPECT_FALSE(adapter->want_write());
5139
5140 int trailer_result =
5141 adapter->SubmitTrailer(1, ToHeaders({{"final-status", "a-ok"}}));
5142 ASSERT_EQ(trailer_result, 0);
5143 if (queue_trailers) {
5144 // Even though there are new trailers to write, the data source has not
5145 // finished writing data and is blocked.
5146 EXPECT_FALSE(adapter->want_write());
5147
5148 body1_ptr->EndData();
5149 adapter->ResumeStream(1);
5150 EXPECT_TRUE(adapter->want_write());
5151
5152 EXPECT_CALL(
5153 visitor,
5154 OnBeforeFrameSent(HEADERS, 1, _, END_STREAM_FLAG | END_HEADERS_FLAG));
5155 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _,
5156 END_STREAM_FLAG | END_HEADERS_FLAG, 0));
5157
5158 send_result = adapter->Send();
5159 EXPECT_EQ(0, send_result);
5160 } else {
5161 // Even though the data source has not finished sending data, the library
5162 // will write the trailers anyway.
5163 EXPECT_TRUE(adapter->want_write());
5164
5165 EXPECT_CALL(
5166 visitor,
5167 OnBeforeFrameSent(HEADERS, 1, _, END_STREAM_FLAG | END_HEADERS_FLAG));
5168 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _,
5169 END_STREAM_FLAG | END_HEADERS_FLAG, 0));
5170
5171 send_result = adapter->Send();
5172 EXPECT_EQ(0, send_result);
5173 EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
5174 }
5175 }
5176 }
5177
TEST(OgHttp2AdapterTest,ServerSubmitsTrailersWithDataEndStream)5178 TEST(OgHttp2AdapterTest, ServerSubmitsTrailersWithDataEndStream) {
5179 DataSavingVisitor visitor;
5180 OgHttp2Adapter::Options options;
5181 options.perspective = Perspective::kServer;
5182 auto adapter = OgHttp2Adapter::Create(visitor, options);
5183
5184 const std::string frames =
5185 TestFrameSequence()
5186 .ClientPreface()
5187 .Headers(1, {{":method", "GET"},
5188 {":scheme", "https"},
5189 {":authority", "example.com"},
5190 {":path", "/this/is/request/one"}})
5191 .Data(1, "Example data, woohoo.")
5192 .Serialize();
5193
5194 testing::InSequence s;
5195
5196 // Client preface (empty SETTINGS)
5197 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5198 EXPECT_CALL(visitor, OnSettingsStart());
5199 EXPECT_CALL(visitor, OnSettingsEnd());
5200 // Stream 1
5201 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, END_HEADERS_FLAG));
5202 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5203 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
5204 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5205 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5206 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5207 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5208 EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
5209 EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
5210 EXPECT_CALL(visitor, OnDataForStream(1, _));
5211
5212 const int64_t result = adapter->ProcessBytes(frames);
5213 EXPECT_EQ(static_cast<size_t>(result), frames.size());
5214
5215 // Send a body that will end with the END_STREAM flag.
5216 const absl::string_view kBody = "This is an example response body.";
5217 auto body = std::make_unique<TestDataFrameSource>(visitor, /*has_fin=*/true);
5218 body->AppendPayload(kBody);
5219 body->EndData();
5220
5221 int submit_result = adapter->SubmitResponse(
5222 1, ToHeaders({{":status", "200"}}), std::move(body));
5223 ASSERT_EQ(submit_result, 0);
5224
5225 const std::vector<Header> trailers =
5226 ToHeaders({{"extra-info", "Trailers are weird but good?"}});
5227 submit_result = adapter->SubmitTrailer(1, trailers);
5228 ASSERT_EQ(submit_result, 0);
5229
5230 // The data should be sent, but because it has END_STREAM, it would not be
5231 // correct to send trailers afterward. The stream should be closed.
5232 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
5233 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
5234 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
5235 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
5236 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, END_HEADERS_FLAG));
5237 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, END_HEADERS_FLAG, 0));
5238 EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, END_STREAM_FLAG, 0));
5239 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
5240
5241 const int send_result = adapter->Send();
5242 EXPECT_EQ(send_result, 0);
5243 EXPECT_THAT(visitor.data(),
5244 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
5245 SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
5246 }
5247
TEST(OgHttp2AdapterTest,ServerSubmitsTrailersWithDataEndStreamAndDeferral)5248 TEST(OgHttp2AdapterTest, ServerSubmitsTrailersWithDataEndStreamAndDeferral) {
5249 DataSavingVisitor visitor;
5250 OgHttp2Adapter::Options options;
5251 options.perspective = Perspective::kServer;
5252 auto adapter = OgHttp2Adapter::Create(visitor, options);
5253
5254 const std::string frames =
5255 TestFrameSequence()
5256 .ClientPreface()
5257 .Headers(1, {{":method", "GET"},
5258 {":scheme", "https"},
5259 {":authority", "example.com"},
5260 {":path", "/this/is/request/one"}})
5261 .Data(1, "Example data, woohoo.")
5262 .Serialize();
5263
5264 testing::InSequence s;
5265
5266 // Client preface (empty SETTINGS)
5267 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5268 EXPECT_CALL(visitor, OnSettingsStart());
5269 EXPECT_CALL(visitor, OnSettingsEnd());
5270 // Stream 1
5271 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, END_HEADERS_FLAG));
5272 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5273 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
5274 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5275 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5276 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5277 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5278 EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
5279 EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
5280 EXPECT_CALL(visitor, OnDataForStream(1, _));
5281
5282 const int64_t result = adapter->ProcessBytes(frames);
5283 EXPECT_EQ(static_cast<size_t>(result), frames.size());
5284
5285 // Send a body that will end with the END_STREAM flag. Don't end the body here
5286 // so that more body can be added later.
5287 const absl::string_view kBody = "This is an example response body.";
5288 auto body = std::make_unique<TestDataFrameSource>(visitor, /*has_fin=*/true);
5289 body->AppendPayload(kBody);
5290 TestDataFrameSource& body_ref = *body;
5291
5292 int submit_result = adapter->SubmitResponse(
5293 1, ToHeaders({{":status", "200"}}), std::move(body));
5294 ASSERT_EQ(submit_result, 0);
5295
5296 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
5297 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
5298 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
5299 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
5300 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, END_HEADERS_FLAG));
5301 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, END_HEADERS_FLAG, 0));
5302 EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
5303
5304 int send_result = adapter->Send();
5305 EXPECT_EQ(send_result, 0);
5306 EXPECT_THAT(visitor.data(),
5307 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
5308 SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
5309 visitor.Clear();
5310
5311 const std::vector<Header> trailers =
5312 ToHeaders({{"extra-info", "Trailers are weird but good?"}});
5313 submit_result = adapter->SubmitTrailer(1, trailers);
5314 ASSERT_EQ(submit_result, 0);
5315
5316 // Add more body and signal the end of data. Resuming the stream should allow
5317 // the new body to be sent.
5318 body_ref.AppendPayload(kBody);
5319 body_ref.EndData();
5320 adapter->ResumeStream(1);
5321
5322 // The new body should be sent, but because it has END_STREAM, it would not be
5323 // correct to send trailers afterward. The stream should be closed.
5324 EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, END_STREAM_FLAG, 0));
5325 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
5326
5327 send_result = adapter->Send();
5328 EXPECT_EQ(send_result, 0);
5329 EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
5330 }
5331
TEST(OgHttp2AdapterTest,ClientDisobeysConnectionFlowControl)5332 TEST(OgHttp2AdapterTest, ClientDisobeysConnectionFlowControl) {
5333 DataSavingVisitor visitor;
5334 OgHttp2Adapter::Options options;
5335 options.perspective = Perspective::kServer;
5336 auto adapter = OgHttp2Adapter::Create(visitor, options);
5337
5338 const std::string frames = TestFrameSequence()
5339 .ClientPreface()
5340 .Headers(1,
5341 {{":method", "POST"},
5342 {":scheme", "https"},
5343 {":authority", "example.com"},
5344 {":path", "/this/is/request/one"},
5345 {"accept", "some bogus value!"}},
5346 /*fin=*/false)
5347 // 70000 bytes of data
5348 .Data(1, std::string(16384, 'a'))
5349 .Data(1, std::string(16384, 'a'))
5350 .Data(1, std::string(16384, 'a'))
5351 .Data(1, std::string(16384, 'a'))
5352 .Data(1, std::string(4464, 'a'))
5353 .Serialize();
5354
5355 testing::InSequence s;
5356 // Client preface (empty SETTINGS)
5357 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5358 EXPECT_CALL(visitor, OnSettingsStart());
5359 EXPECT_CALL(visitor, OnSettingsEnd());
5360
5361 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5362 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5363 EXPECT_CALL(visitor, OnHeaderForStream).Times(5);
5364 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5365 EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
5366 EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
5367 EXPECT_CALL(visitor, OnDataForStream(1, _));
5368 EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
5369 EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
5370 EXPECT_CALL(visitor, OnDataForStream(1, _));
5371 EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
5372 EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
5373 EXPECT_CALL(visitor, OnDataForStream(1, _));
5374 EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
5375 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
5376 // No further frame data or headers are delivered.
5377
5378 const int64_t result = adapter->ProcessBytes(frames);
5379 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5380
5381 EXPECT_TRUE(adapter->want_write());
5382
5383 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
5384 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
5385 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
5386 EXPECT_CALL(
5387 visitor,
5388 OnFrameSent(GOAWAY, 0, _, 0x0,
5389 static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
5390
5391 int send_result = adapter->Send();
5392 EXPECT_EQ(0, send_result);
5393 EXPECT_THAT(visitor.data(),
5394 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
5395 }
5396
TEST(OgHttp2AdapterTest,ClientDisobeysConnectionFlowControlWithOneDataFrame)5397 TEST(OgHttp2AdapterTest, ClientDisobeysConnectionFlowControlWithOneDataFrame) {
5398 DataSavingVisitor visitor;
5399 OgHttp2Adapter::Options options;
5400 options.perspective = Perspective::kServer;
5401 auto adapter = OgHttp2Adapter::Create(visitor, options);
5402
5403 // Allow the client to send a DATA frame that exceeds the connection flow
5404 // control window.
5405 const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
5406 adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
5407
5408 const std::string initial_frames =
5409 TestFrameSequence()
5410 .ClientPreface()
5411 .Headers(1,
5412 {{":method", "POST"},
5413 {":scheme", "https"},
5414 {":authority", "example.com"},
5415 {":path", "/this/is/request/one"}},
5416 /*fin=*/false)
5417 .Serialize();
5418
5419 testing::InSequence s;
5420
5421 // Client preface (empty SETTINGS)
5422 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5423 EXPECT_CALL(visitor, OnSettingsStart());
5424 EXPECT_CALL(visitor, OnSettingsEnd());
5425
5426 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5427 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5428 EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
5429 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5430
5431 int64_t process_result = adapter->ProcessBytes(initial_frames);
5432 EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
5433
5434 EXPECT_TRUE(adapter->want_write());
5435
5436 // Outbound SETTINGS containing MAX_FRAME_SIZE.
5437 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
5438 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
5439
5440 // Ack of client's initial settings.
5441 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
5442 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
5443
5444 int send_result = adapter->Send();
5445 EXPECT_EQ(0, send_result);
5446 EXPECT_THAT(visitor.data(),
5447 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
5448 visitor.Clear();
5449
5450 // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
5451 // overflow the connection-level window. The result should be a GOAWAY.
5452 const std::string overflow_frames =
5453 TestFrameSequence()
5454 .SettingsAck()
5455 .Data(1, std::string(window_overflow_bytes, 'a'))
5456 .Serialize();
5457
5458 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, ACK_FLAG));
5459 EXPECT_CALL(visitor, OnSettingsAck());
5460 EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
5461 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
5462 // No further frame data is delivered.
5463
5464 process_result = adapter->ProcessBytes(overflow_frames);
5465 EXPECT_EQ(overflow_frames.size(), static_cast<size_t>(process_result));
5466
5467 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
5468 EXPECT_CALL(
5469 visitor,
5470 OnFrameSent(GOAWAY, 0, _, 0x0,
5471 static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
5472
5473 send_result = adapter->Send();
5474 EXPECT_EQ(0, send_result);
5475 EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
5476 }
5477
TEST(OgHttp2AdapterTest,ClientDisobeysConnectionFlowControlAcrossReads)5478 TEST(OgHttp2AdapterTest, ClientDisobeysConnectionFlowControlAcrossReads) {
5479 DataSavingVisitor visitor;
5480 OgHttp2Adapter::Options options;
5481 options.perspective = Perspective::kServer;
5482 auto adapter = OgHttp2Adapter::Create(visitor, options);
5483
5484 // Allow the client to send a DATA frame that exceeds the connection flow
5485 // control window.
5486 const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
5487 adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
5488
5489 const std::string initial_frames =
5490 TestFrameSequence()
5491 .ClientPreface()
5492 .Headers(1,
5493 {{":method", "POST"},
5494 {":scheme", "https"},
5495 {":authority", "example.com"},
5496 {":path", "/this/is/request/one"}},
5497 /*fin=*/false)
5498 .Serialize();
5499
5500 testing::InSequence s;
5501
5502 // Client preface (empty SETTINGS)
5503 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5504 EXPECT_CALL(visitor, OnSettingsStart());
5505 EXPECT_CALL(visitor, OnSettingsEnd());
5506
5507 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5508 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5509 EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
5510 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5511
5512 int64_t process_result = adapter->ProcessBytes(initial_frames);
5513 EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
5514
5515 EXPECT_TRUE(adapter->want_write());
5516
5517 // Outbound SETTINGS containing MAX_FRAME_SIZE.
5518 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
5519 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
5520
5521 // Ack of client's initial settings.
5522 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
5523 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
5524
5525 int send_result = adapter->Send();
5526 EXPECT_EQ(0, send_result);
5527 EXPECT_THAT(visitor.data(),
5528 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
5529 visitor.Clear();
5530
5531 // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
5532 // overflow the connection-level window. The result should be a GOAWAY.
5533 const std::string overflow_frames =
5534 TestFrameSequence()
5535 .SettingsAck()
5536 .Data(1, std::string(window_overflow_bytes, 'a'))
5537 .Serialize();
5538
5539 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, ACK_FLAG));
5540 EXPECT_CALL(visitor, OnSettingsAck());
5541 EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
5542 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
5543
5544 const size_t chunk_length = 16384;
5545 ASSERT_GE(overflow_frames.size(), chunk_length);
5546 process_result =
5547 adapter->ProcessBytes(overflow_frames.substr(0, chunk_length));
5548 EXPECT_EQ(chunk_length, static_cast<size_t>(process_result));
5549
5550 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
5551 EXPECT_CALL(
5552 visitor,
5553 OnFrameSent(GOAWAY, 0, _, 0x0,
5554 static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
5555
5556 send_result = adapter->Send();
5557 EXPECT_EQ(0, send_result);
5558 EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
5559 }
5560
TEST(OgHttp2AdapterTest,ClientDisobeysStreamFlowControl)5561 TEST(OgHttp2AdapterTest, ClientDisobeysStreamFlowControl) {
5562 DataSavingVisitor visitor;
5563 OgHttp2Adapter::Options options;
5564 options.perspective = Perspective::kServer;
5565 auto adapter = OgHttp2Adapter::Create(visitor, options);
5566
5567 const std::string frames = TestFrameSequence()
5568 .ClientPreface()
5569 .Headers(1,
5570 {{":method", "POST"},
5571 {":scheme", "https"},
5572 {":authority", "example.com"},
5573 {":path", "/this/is/request/one"},
5574 {"accept", "some bogus value!"}},
5575 /*fin=*/false)
5576 .Serialize();
5577 const std::string more_frames = TestFrameSequence()
5578 // 70000 bytes of data
5579 .Data(1, std::string(16384, 'a'))
5580 .Data(1, std::string(16384, 'a'))
5581 .Data(1, std::string(16384, 'a'))
5582 .Data(1, std::string(16384, 'a'))
5583 .Data(1, std::string(4464, 'a'))
5584 .Serialize();
5585
5586 testing::InSequence s;
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(5);
5595 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
5596
5597 int64_t result = adapter->ProcessBytes(frames);
5598 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5599
5600 adapter->SubmitWindowUpdate(0, 20000);
5601
5602 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
5603 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
5604 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
5605 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
5606 EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
5607 EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
5608
5609 int send_result = adapter->Send();
5610 EXPECT_EQ(0, send_result);
5611 EXPECT_THAT(visitor.data(),
5612 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
5613 SpdyFrameType::WINDOW_UPDATE}));
5614 visitor.Clear();
5615
5616 EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
5617 EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
5618 EXPECT_CALL(visitor, OnDataForStream(1, _));
5619 EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
5620 EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
5621 EXPECT_CALL(visitor, OnDataForStream(1, _));
5622 EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
5623 EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
5624 EXPECT_CALL(visitor, OnDataForStream(1, _));
5625 EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
5626 // No further frame data or headers are delivered.
5627
5628 result = adapter->ProcessBytes(more_frames);
5629 EXPECT_EQ(more_frames.size(), static_cast<size_t>(result));
5630
5631 EXPECT_TRUE(adapter->want_write());
5632 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
5633 EXPECT_CALL(
5634 visitor,
5635 OnFrameSent(RST_STREAM, 1, 4, 0x0,
5636 static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
5637 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
5638
5639 send_result = adapter->Send();
5640 EXPECT_EQ(0, send_result);
5641 EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
5642 }
5643
TEST(OgHttp2AdapterTest,ServerErrorWhileHandlingHeaders)5644 TEST(OgHttp2AdapterTest, ServerErrorWhileHandlingHeaders) {
5645 DataSavingVisitor visitor;
5646 OgHttp2Adapter::Options options;
5647 options.perspective = Perspective::kServer;
5648 auto adapter = OgHttp2Adapter::Create(visitor, options);
5649
5650 const std::string frames = TestFrameSequence()
5651 .ClientPreface()
5652 .Headers(1,
5653 {{":method", "POST"},
5654 {":scheme", "https"},
5655 {":authority", "example.com"},
5656 {":path", "/this/is/request/one"},
5657 {"accept", "some bogus value!"}},
5658 /*fin=*/false)
5659 .WindowUpdate(1, 2000)
5660 .Data(1, "This is the request body.")
5661 .WindowUpdate(0, 2000)
5662 .Serialize();
5663 testing::InSequence s;
5664
5665 // Client preface (empty SETTINGS)
5666 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5667 EXPECT_CALL(visitor, OnSettingsStart());
5668 EXPECT_CALL(visitor, OnSettingsEnd());
5669
5670 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5671 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5672 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
5673 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5674 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5675 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5676 EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
5677 .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
5678 // Stream WINDOW_UPDATE and DATA frames are not delivered to the visitor.
5679 EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
5680 EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
5681
5682 const int64_t result = adapter->ProcessBytes(frames);
5683 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5684
5685 EXPECT_TRUE(adapter->want_write());
5686
5687 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
5688 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
5689 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
5690 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
5691 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
5692 EXPECT_CALL(visitor,
5693 OnFrameSent(RST_STREAM, 1, 4, 0x0,
5694 static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
5695 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
5696
5697 int send_result = adapter->Send();
5698 // Some bytes should have been serialized.
5699 EXPECT_EQ(0, send_result);
5700 // SETTINGS ack
5701 EXPECT_THAT(visitor.data(),
5702 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
5703 SpdyFrameType::RST_STREAM}));
5704 }
5705
TEST(OgHttp2AdapterTest,ServerErrorWhileHandlingHeadersDropsFrames)5706 TEST(OgHttp2AdapterTest, ServerErrorWhileHandlingHeadersDropsFrames) {
5707 DataSavingVisitor visitor;
5708 OgHttp2Adapter::Options options;
5709 options.perspective = Perspective::kServer;
5710 auto adapter = OgHttp2Adapter::Create(visitor, options);
5711
5712 const std::string frames = TestFrameSequence()
5713 .ClientPreface()
5714 .Headers(1,
5715 {{":method", "POST"},
5716 {":scheme", "https"},
5717 {":authority", "example.com"},
5718 {":path", "/this/is/request/one"},
5719 {"accept", "some bogus value!"}},
5720 /*fin=*/false)
5721 .WindowUpdate(1, 2000)
5722 .Data(1, "This is the request body.")
5723 .Metadata(1, "This is the request metadata.")
5724 .RstStream(1, Http2ErrorCode::CANCEL)
5725 .WindowUpdate(0, 2000)
5726 .Headers(3,
5727 {{":method", "GET"},
5728 {":scheme", "https"},
5729 {":authority", "example.com"},
5730 {":path", "/this/is/request/two"}},
5731 /*fin=*/false)
5732 .Metadata(3, "This is the request metadata.",
5733 /*multiple_frames=*/true)
5734 .Serialize();
5735 testing::InSequence s;
5736
5737 // Client preface (empty SETTINGS)
5738 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5739 EXPECT_CALL(visitor, OnSettingsStart());
5740 EXPECT_CALL(visitor, OnSettingsEnd());
5741
5742 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5743 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5744 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
5745 EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
5746 .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
5747 // Frames for the RST_STREAM-marked stream are not delivered to the visitor.
5748 // Note: nghttp2 still delivers control frames and metadata for the stream.
5749 EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
5750 EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
5751 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
5752 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
5753 EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
5754 EXPECT_CALL(visitor, OnEndHeadersForStream(3));
5755 EXPECT_CALL(visitor, OnFrameHeader(3, _, kMetadataFrameType, 0));
5756 EXPECT_CALL(visitor, OnBeginMetadataForStream(3, _));
5757 EXPECT_CALL(visitor, OnMetadataForStream(3, "This is the re"))
5758 .WillOnce(testing::DoAll(testing::InvokeWithoutArgs([&adapter]() {
5759 adapter->SubmitRst(
5760 3, Http2ErrorCode::REFUSED_STREAM);
5761 }),
5762 testing::Return(true)));
5763 // The rest of the metadata is not delivered to the visitor.
5764
5765 const int64_t result = adapter->ProcessBytes(frames);
5766 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
5767
5768 EXPECT_TRUE(adapter->want_write());
5769
5770 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
5771 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
5772 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
5773 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
5774 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
5775 EXPECT_CALL(visitor,
5776 OnFrameSent(RST_STREAM, 1, 4, 0x0,
5777 static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
5778 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
5779 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, 4, 0x0));
5780 EXPECT_CALL(visitor,
5781 OnFrameSent(RST_STREAM, 3, 4, 0x0,
5782 static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
5783 EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
5784
5785 int send_result = adapter->Send();
5786 // Some bytes should have been serialized.
5787 EXPECT_EQ(0, send_result);
5788 // SETTINGS ack
5789 EXPECT_THAT(
5790 visitor.data(),
5791 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
5792 SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
5793 }
5794
TEST(OgHttp2AdapterTest,ServerConnectionErrorWhileHandlingHeaders)5795 TEST(OgHttp2AdapterTest, ServerConnectionErrorWhileHandlingHeaders) {
5796 DataSavingVisitor visitor;
5797 OgHttp2Adapter::Options options;
5798 options.perspective = Perspective::kServer;
5799 auto adapter = OgHttp2Adapter::Create(visitor, options);
5800
5801 const std::string frames = TestFrameSequence()
5802 .ClientPreface()
5803 .Headers(1,
5804 {{":method", "POST"},
5805 {":scheme", "https"},
5806 {":authority", "example.com"},
5807 {":path", "/this/is/request/one"},
5808 {"Accept", "uppercase, oh boy!"}},
5809 /*fin=*/false)
5810 .WindowUpdate(1, 2000)
5811 .Data(1, "This is the request body.")
5812 .WindowUpdate(0, 2000)
5813 .Serialize();
5814 testing::InSequence s;
5815
5816 // Client preface (empty SETTINGS)
5817 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5818 EXPECT_CALL(visitor, OnSettingsStart());
5819 EXPECT_CALL(visitor, OnSettingsEnd());
5820
5821 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5822 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5823 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
5824 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5825 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5826 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5827 EXPECT_CALL(
5828 visitor,
5829 OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader))
5830 .WillOnce(testing::Return(false));
5831 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kHeaderError));
5832
5833 const int64_t result = adapter->ProcessBytes(frames);
5834 EXPECT_LT(result, 0);
5835
5836 EXPECT_TRUE(adapter->want_write());
5837
5838 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
5839 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
5840 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
5841 EXPECT_CALL(visitor,
5842 OnFrameSent(RST_STREAM, 1, 4, 0x0,
5843 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
5844 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
5845 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
5846 EXPECT_CALL(visitor,
5847 OnFrameSent(GOAWAY, 0, _, 0x0,
5848 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
5849
5850 int send_result = adapter->Send();
5851 // Some bytes should have been serialized.
5852 EXPECT_EQ(0, send_result);
5853 EXPECT_THAT(visitor.data(),
5854 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
5855 SpdyFrameType::GOAWAY}));
5856 }
5857
TEST(OgHttp2AdapterTest,ServerErrorAfterHandlingHeaders)5858 TEST(OgHttp2AdapterTest, ServerErrorAfterHandlingHeaders) {
5859 DataSavingVisitor visitor;
5860 OgHttp2Adapter::Options options;
5861 options.perspective = Perspective::kServer;
5862 auto adapter = OgHttp2Adapter::Create(visitor, options);
5863
5864 const std::string frames = TestFrameSequence()
5865 .ClientPreface()
5866 .Headers(1,
5867 {{":method", "POST"},
5868 {":scheme", "https"},
5869 {":authority", "example.com"},
5870 {":path", "/this/is/request/one"}},
5871 /*fin=*/false)
5872 .WindowUpdate(1, 2000)
5873 .Data(1, "This is the request body.")
5874 .WindowUpdate(0, 2000)
5875 .Serialize();
5876 testing::InSequence s;
5877
5878 // Client preface (empty SETTINGS)
5879 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5880 EXPECT_CALL(visitor, OnSettingsStart());
5881 EXPECT_CALL(visitor, OnSettingsEnd());
5882
5883 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5884 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5885 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
5886 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5887 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5888 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
5889 EXPECT_CALL(visitor, OnEndHeadersForStream(1))
5890 .WillOnce(testing::Return(false));
5891 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
5892
5893 const int64_t result = adapter->ProcessBytes(frames);
5894 EXPECT_LT(result, 0);
5895
5896 EXPECT_TRUE(adapter->want_write());
5897
5898 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
5899 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
5900 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
5901 EXPECT_CALL(visitor,
5902 OnFrameSent(GOAWAY, 0, _, 0x0,
5903 static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
5904
5905 int send_result = adapter->Send();
5906 // Some bytes should have been serialized.
5907 EXPECT_EQ(0, send_result);
5908 EXPECT_THAT(visitor.data(),
5909 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
5910 }
5911
5912 // Exercises the case when a visitor chooses to reject a frame based solely on
5913 // the frame header, which is a fatal error for the connection.
TEST(OgHttp2AdapterTest,ServerRejectsFrameHeader)5914 TEST(OgHttp2AdapterTest, ServerRejectsFrameHeader) {
5915 DataSavingVisitor visitor;
5916 OgHttp2Adapter::Options options;
5917 options.perspective = Perspective::kServer;
5918 auto adapter = OgHttp2Adapter::Create(visitor, options);
5919
5920 const std::string frames = TestFrameSequence()
5921 .ClientPreface()
5922 .Ping(64)
5923 .Headers(1,
5924 {{":method", "POST"},
5925 {":scheme", "https"},
5926 {":authority", "example.com"},
5927 {":path", "/this/is/request/one"}},
5928 /*fin=*/false)
5929 .WindowUpdate(1, 2000)
5930 .Data(1, "This is the request body.")
5931 .WindowUpdate(0, 2000)
5932 .Serialize();
5933 testing::InSequence s;
5934
5935 // Client preface (empty SETTINGS)
5936 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5937 EXPECT_CALL(visitor, OnSettingsStart());
5938 EXPECT_CALL(visitor, OnSettingsEnd());
5939
5940 EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0))
5941 .WillOnce(testing::Return(false));
5942 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
5943
5944 const int64_t result = adapter->ProcessBytes(frames);
5945 EXPECT_LT(result, 0);
5946
5947 EXPECT_TRUE(adapter->want_write());
5948
5949 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
5950 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
5951 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
5952 EXPECT_CALL(visitor,
5953 OnFrameSent(GOAWAY, 0, _, 0x0,
5954 static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
5955
5956 int send_result = adapter->Send();
5957 // Some bytes should have been serialized.
5958 EXPECT_EQ(0, send_result);
5959 EXPECT_THAT(visitor.data(),
5960 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
5961 }
5962
TEST(OgHttp2AdapterTest,ServerRejectsBeginningOfData)5963 TEST(OgHttp2AdapterTest, ServerRejectsBeginningOfData) {
5964 DataSavingVisitor visitor;
5965 OgHttp2Adapter::Options options;
5966 options.perspective = Perspective::kServer;
5967 auto adapter = OgHttp2Adapter::Create(visitor, options);
5968
5969 const std::string frames = TestFrameSequence()
5970 .ClientPreface()
5971 .Headers(1,
5972 {{":method", "POST"},
5973 {":scheme", "https"},
5974 {":authority", "example.com"},
5975 {":path", "/this/is/request/one"}},
5976 /*fin=*/false)
5977 .Data(1, "This is the request body.")
5978 .Headers(3,
5979 {{":method", "GET"},
5980 {":scheme", "http"},
5981 {":authority", "example.com"},
5982 {":path", "/this/is/request/two"}},
5983 /*fin=*/true)
5984 .RstStream(3, Http2ErrorCode::CANCEL)
5985 .Ping(47)
5986 .Serialize();
5987 testing::InSequence s;
5988
5989 // Client preface (empty SETTINGS)
5990 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
5991 EXPECT_CALL(visitor, OnSettingsStart());
5992 EXPECT_CALL(visitor, OnSettingsEnd());
5993
5994 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
5995 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
5996 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
5997 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
5998 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
5999 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
6000 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6001 EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
6002 EXPECT_CALL(visitor, OnBeginDataForStream(1, 25))
6003 .WillOnce(testing::Return(false));
6004 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
6005
6006 const int64_t result = adapter->ProcessBytes(frames);
6007 EXPECT_LT(result, 0);
6008
6009 EXPECT_TRUE(adapter->want_write());
6010
6011 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6012 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
6013 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6014 EXPECT_CALL(visitor,
6015 OnFrameSent(GOAWAY, 0, _, 0x0,
6016 static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
6017
6018 int send_result = adapter->Send();
6019 // Some bytes should have been serialized.
6020 EXPECT_EQ(0, send_result);
6021 EXPECT_THAT(visitor.data(),
6022 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
6023 }
6024
TEST(OgHttp2AdapterTest,ServerReceivesTooLargeHeader)6025 TEST(OgHttp2AdapterTest, ServerReceivesTooLargeHeader) {
6026 DataSavingVisitor visitor;
6027 OgHttp2Adapter::Options options;
6028 options.perspective = Perspective::kServer;
6029 options.max_header_list_bytes = 64 * 1024;
6030 options.max_header_field_size = 64 * 1024;
6031 auto adapter = OgHttp2Adapter::Create(visitor, options);
6032
6033 // Due to configuration, the library will accept a maximum of 64kB of huffman
6034 // encoded data per header field.
6035 const std::string too_large_value = std::string(80 * 1024, 'q');
6036 const std::string frames = TestFrameSequence()
6037 .ClientPreface()
6038 .Headers(1,
6039 {{":method", "POST"},
6040 {":scheme", "https"},
6041 {":authority", "example.com"},
6042 {":path", "/this/is/request/one"},
6043 {"x-toobig", too_large_value}},
6044 /*fin=*/true)
6045 .Headers(3,
6046 {{":method", "GET"},
6047 {":scheme", "https"},
6048 {":authority", "example.com"},
6049 {":path", "/this/is/request/two"}},
6050 /*fin=*/true)
6051 .Serialize();
6052 testing::InSequence s;
6053
6054 // Client preface (empty SETTINGS)
6055 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6056 EXPECT_CALL(visitor, OnSettingsStart());
6057 EXPECT_CALL(visitor, OnSettingsEnd());
6058
6059 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, END_STREAM_FLAG));
6060 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6061 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
6062 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
6063 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
6064 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
6065 EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 0)).Times(3);
6066 EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, END_HEADERS_FLAG));
6067 // Further header processing is skipped, as the header field is too large.
6068
6069 EXPECT_CALL(visitor,
6070 OnFrameHeader(3, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
6071 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
6072 EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
6073 EXPECT_CALL(visitor, OnEndHeadersForStream(3));
6074 EXPECT_CALL(visitor, OnEndStream(3));
6075
6076 const int64_t result = adapter->ProcessBytes(frames);
6077 EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
6078
6079 EXPECT_TRUE(adapter->want_write());
6080
6081 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6082 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
6083 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK));
6084 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK, 0));
6085 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
6086 EXPECT_CALL(visitor,
6087 OnFrameSent(RST_STREAM, 1, 4, 0x0,
6088 static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
6089 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
6090
6091 int send_result = adapter->Send();
6092 EXPECT_EQ(0, send_result);
6093 EXPECT_THAT(visitor.data(),
6094 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
6095 SpdyFrameType::RST_STREAM}));
6096 }
6097
TEST(OgHttp2AdapterTest,ServerReceivesInvalidAuthority)6098 TEST(OgHttp2AdapterTest, ServerReceivesInvalidAuthority) {
6099 DataSavingVisitor visitor;
6100 OgHttp2Adapter::Options options;
6101 options.perspective = Perspective::kServer;
6102 auto adapter = OgHttp2Adapter::Create(visitor, options);
6103
6104 const std::string frames = TestFrameSequence()
6105 .ClientPreface()
6106 .Headers(1,
6107 {{":method", "POST"},
6108 {":scheme", "https"},
6109 {":authority", "ex|ample.com"},
6110 {":path", "/this/is/request/one"}},
6111 /*fin=*/false)
6112 .Serialize();
6113 testing::InSequence s;
6114
6115 // Client preface (empty SETTINGS)
6116 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6117 EXPECT_CALL(visitor, OnSettingsStart());
6118 EXPECT_CALL(visitor, OnSettingsEnd());
6119
6120 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
6121 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6122 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
6123 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
6124 EXPECT_CALL(
6125 visitor,
6126 OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
6127
6128 const int64_t result = adapter->ProcessBytes(frames);
6129 EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
6130
6131 EXPECT_TRUE(adapter->want_write());
6132
6133 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6134 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0x0));
6135 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
6136 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0x0));
6137 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
6138 EXPECT_CALL(visitor,
6139 OnFrameSent(RST_STREAM, 1, 4, 0x0,
6140 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6141 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
6142
6143 int send_result = adapter->Send();
6144 EXPECT_EQ(0, send_result);
6145 EXPECT_THAT(visitor.data(),
6146 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
6147 SpdyFrameType::RST_STREAM}));
6148 }
6149
TEST(OgHttpAdapterTest,ServerReceivesGoAway)6150 TEST(OgHttpAdapterTest, ServerReceivesGoAway) {
6151 DataSavingVisitor visitor;
6152 OgHttp2Adapter::Options options;
6153 options.perspective = Perspective::kServer;
6154 auto adapter = OgHttp2Adapter::Create(visitor, options);
6155
6156 const std::string frames = TestFrameSequence()
6157 .ClientPreface()
6158 .Headers(1,
6159 {{":method", "GET"},
6160 {":scheme", "https"},
6161 {":authority", "example.com"},
6162 {":path", "/this/is/request/one"}},
6163 /*fin=*/true)
6164 .GoAway(0, Http2ErrorCode::HTTP2_NO_ERROR, "")
6165 .Serialize();
6166 testing::InSequence s;
6167
6168 // Client preface (empty SETTINGS)
6169 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6170 EXPECT_CALL(visitor, OnSettingsStart());
6171 EXPECT_CALL(visitor, OnSettingsEnd());
6172
6173 EXPECT_CALL(visitor,
6174 OnFrameHeader(1, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
6175 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6176 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
6177 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6178 EXPECT_CALL(visitor, OnEndStream(1));
6179 EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0x0));
6180 EXPECT_CALL(visitor, OnGoAway(0, Http2ErrorCode::HTTP2_NO_ERROR, ""));
6181
6182 const int64_t result = adapter->ProcessBytes(frames);
6183 EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
6184
6185 // The server should still be able to send a response after receiving a GOAWAY
6186 // with a lower last-stream-ID field, as the stream was client-initiated.
6187 const int submit_result =
6188 adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}),
6189 /*data_source=*/nullptr);
6190 ASSERT_EQ(0, submit_result);
6191
6192 EXPECT_TRUE(adapter->want_write());
6193
6194 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6195 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0x0));
6196 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
6197 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0x0));
6198 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _,
6199 END_STREAM_FLAG | END_HEADERS_FLAG));
6200 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _,
6201 END_STREAM_FLAG | END_HEADERS_FLAG, 0));
6202 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
6203
6204 int send_result = adapter->Send();
6205 EXPECT_EQ(0, send_result);
6206 EXPECT_THAT(visitor.data(),
6207 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
6208 SpdyFrameType::HEADERS}));
6209 }
6210
TEST(OgHttp2AdapterTest,ServerSubmitResponse)6211 TEST(OgHttp2AdapterTest, ServerSubmitResponse) {
6212 DataSavingVisitor visitor;
6213 OgHttp2Adapter::Options options;
6214 options.perspective = Perspective::kServer;
6215 auto adapter = OgHttp2Adapter::Create(visitor, options);
6216 EXPECT_FALSE(adapter->want_write());
6217
6218 const std::string frames = TestFrameSequence()
6219 .ClientPreface()
6220 .Headers(1,
6221 {{":method", "GET"},
6222 {":scheme", "https"},
6223 {":authority", "example.com"},
6224 {":path", "/this/is/request/one"}},
6225 /*fin=*/true)
6226 .Serialize();
6227 testing::InSequence s;
6228
6229 const char* kSentinel1 = "arbitrary pointer 1";
6230
6231 // Client preface (empty SETTINGS)
6232 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6233 EXPECT_CALL(visitor, OnSettingsStart());
6234 EXPECT_CALL(visitor, OnSettingsEnd());
6235 // Stream 1
6236 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
6237 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6238 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
6239 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
6240 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
6241 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
6242 EXPECT_CALL(visitor, OnEndHeadersForStream(1))
6243 .WillOnce(testing::InvokeWithoutArgs([&adapter, kSentinel1]() {
6244 adapter->SetStreamUserData(1, const_cast<char*>(kSentinel1));
6245 return true;
6246 }));
6247 EXPECT_CALL(visitor, OnEndStream(1));
6248
6249 const int64_t result = adapter->ProcessBytes(frames);
6250 EXPECT_EQ(frames.size(), result);
6251
6252 EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
6253
6254 // Server will want to send a SETTINGS and a SETTINGS ack.
6255 EXPECT_TRUE(adapter->want_write());
6256
6257 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
6258 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
6259 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
6260 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
6261
6262 int send_result = adapter->Send();
6263 EXPECT_EQ(0, send_result);
6264 EXPECT_THAT(visitor.data(),
6265 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
6266 visitor.Clear();
6267
6268 EXPECT_EQ(0, adapter->GetHpackEncoderDynamicTableSize());
6269
6270 EXPECT_FALSE(adapter->want_write());
6271 const absl::string_view kBody = "This is an example response body.";
6272 // A data fin is not sent so that the stream remains open, and the flow
6273 // control state can be verified.
6274 auto body1 = std::make_unique<TestDataFrameSource>(visitor, false);
6275 body1->AppendPayload(kBody);
6276 int submit_result = adapter->SubmitResponse(
6277 1,
6278 ToHeaders({{":status", "404"},
6279 {"x-comment", "I have no idea what you're talking about."}}),
6280 std::move(body1));
6281 EXPECT_EQ(submit_result, 0);
6282 EXPECT_TRUE(adapter->want_write());
6283
6284 // Stream user data should have been set successfully after receiving headers.
6285 EXPECT_EQ(kSentinel1, adapter->GetStreamUserData(1));
6286 adapter->SetStreamUserData(1, nullptr);
6287 EXPECT_EQ(nullptr, adapter->GetStreamUserData(1));
6288
6289 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
6290 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
6291 EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
6292
6293 send_result = adapter->Send();
6294 EXPECT_EQ(0, send_result);
6295
6296 EXPECT_THAT(visitor.data(),
6297 EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
6298 EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
6299 EXPECT_FALSE(adapter->want_write());
6300
6301 // Some data was sent, so the remaining send window size should be less than
6302 // the default.
6303 EXPECT_LT(adapter->GetStreamSendWindowSize(1), kInitialFlowControlWindowSize);
6304 EXPECT_GT(adapter->GetStreamSendWindowSize(1), 0);
6305 // Send window for a nonexistent stream is not available.
6306 EXPECT_EQ(adapter->GetStreamSendWindowSize(3), -1);
6307
6308 EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 0);
6309 }
6310
TEST(OgHttp2AdapterTest,ServerSubmitResponseWithResetFromClient)6311 TEST(OgHttp2AdapterTest, ServerSubmitResponseWithResetFromClient) {
6312 DataSavingVisitor visitor;
6313 OgHttp2Adapter::Options options;
6314 options.perspective = Perspective::kServer;
6315 auto adapter = OgHttp2Adapter::Create(visitor, options);
6316 EXPECT_FALSE(adapter->want_write());
6317
6318 const std::string frames = TestFrameSequence()
6319 .ClientPreface()
6320 .Headers(1,
6321 {{":method", "GET"},
6322 {":scheme", "https"},
6323 {":authority", "example.com"},
6324 {":path", "/this/is/request/one"}},
6325 /*fin=*/true)
6326 .Serialize();
6327 testing::InSequence s;
6328
6329 // Client preface (empty SETTINGS)
6330 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6331 EXPECT_CALL(visitor, OnSettingsStart());
6332 EXPECT_CALL(visitor, OnSettingsEnd());
6333 // Stream 1
6334 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
6335 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6336 EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
6337 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6338 EXPECT_CALL(visitor, OnEndStream(1));
6339
6340 const int64_t result = adapter->ProcessBytes(frames);
6341 EXPECT_EQ(frames.size(), result);
6342
6343 EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
6344
6345 // Server will want to send a SETTINGS and a SETTINGS ack.
6346 EXPECT_TRUE(adapter->want_write());
6347
6348 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
6349 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
6350 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
6351 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
6352
6353 int send_result = adapter->Send();
6354 EXPECT_EQ(0, send_result);
6355 EXPECT_THAT(visitor.data(),
6356 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
6357 visitor.Clear();
6358
6359 EXPECT_FALSE(adapter->want_write());
6360 const absl::string_view kBody = "This is an example response body.";
6361 auto body1 = std::make_unique<TestDataFrameSource>(visitor, true);
6362 body1->AppendPayload(kBody);
6363 int submit_result = adapter->SubmitResponse(
6364 1,
6365 ToHeaders({{":status", "404"},
6366 {"x-comment", "I have no idea what you're talking about."}}),
6367 std::move(body1));
6368 EXPECT_EQ(submit_result, 0);
6369 EXPECT_TRUE(adapter->want_write());
6370
6371 // Client resets the stream before the server can send the response.
6372 const std::string reset =
6373 TestFrameSequence().RstStream(1, Http2ErrorCode::CANCEL).Serialize();
6374 EXPECT_CALL(visitor, OnFrameHeader(1, 4, RST_STREAM, 0));
6375 EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::CANCEL));
6376 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::CANCEL));
6377 const int64_t reset_result = adapter->ProcessBytes(reset);
6378 EXPECT_EQ(reset.size(), static_cast<size_t>(reset_result));
6379
6380 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, _)).Times(0);
6381 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, _, _)).Times(0);
6382 EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, _, _)).Times(0);
6383
6384 send_result = adapter->Send();
6385 EXPECT_EQ(0, send_result);
6386
6387 EXPECT_THAT(visitor.data(), testing::IsEmpty());
6388 }
6389
TEST(OgHttp2AdapterTest,ServerRejectsStreamData)6390 TEST(OgHttp2AdapterTest, ServerRejectsStreamData) {
6391 DataSavingVisitor visitor;
6392 OgHttp2Adapter::Options options;
6393 options.perspective = Perspective::kServer;
6394 auto adapter = OgHttp2Adapter::Create(visitor, options);
6395
6396 const std::string frames = TestFrameSequence()
6397 .ClientPreface()
6398 .Headers(1,
6399 {{":method", "POST"},
6400 {":scheme", "https"},
6401 {":authority", "example.com"},
6402 {":path", "/this/is/request/one"}},
6403 /*fin=*/false)
6404 .Data(1, "This is the request body.")
6405 .Headers(3,
6406 {{":method", "GET"},
6407 {":scheme", "http"},
6408 {":authority", "example.com"},
6409 {":path", "/this/is/request/two"}},
6410 /*fin=*/true)
6411 .RstStream(3, Http2ErrorCode::CANCEL)
6412 .Ping(47)
6413 .Serialize();
6414 testing::InSequence s;
6415
6416 // Client preface (empty SETTINGS)
6417 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6418 EXPECT_CALL(visitor, OnSettingsStart());
6419 EXPECT_CALL(visitor, OnSettingsEnd());
6420
6421 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
6422 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6423 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
6424 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
6425 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
6426 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
6427 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6428 EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
6429 EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
6430 EXPECT_CALL(visitor, OnDataForStream(1, _)).WillOnce(testing::Return(false));
6431 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
6432
6433 const int64_t result = adapter->ProcessBytes(frames);
6434 EXPECT_LT(result, 0);
6435
6436 EXPECT_TRUE(adapter->want_write());
6437
6438 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6439 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
6440 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6441 EXPECT_CALL(visitor,
6442 OnFrameSent(GOAWAY, 0, _, 0x0,
6443 static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
6444
6445 int send_result = adapter->Send();
6446 // Some bytes should have been serialized.
6447 EXPECT_EQ(0, send_result);
6448 EXPECT_THAT(visitor.data(),
6449 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
6450 }
6451
6452 // Exercises a naive mutually recursive test client and server. This test fails
6453 // without recursion guards in OgHttp2Session.
TEST(OgHttp2AdapterInteractionTest,ClientServerInteractionTest)6454 TEST(OgHttp2AdapterInteractionTest, ClientServerInteractionTest) {
6455 testing::NiceMock<MockHttp2Visitor> client_visitor;
6456 OgHttp2Adapter::Options client_options;
6457 client_options.perspective = Perspective::kClient;
6458 auto client_adapter = OgHttp2Adapter::Create(client_visitor, client_options);
6459 testing::NiceMock<MockHttp2Visitor> server_visitor;
6460 OgHttp2Adapter::Options server_options;
6461 server_options.perspective = Perspective::kServer;
6462 auto server_adapter = OgHttp2Adapter::Create(server_visitor, server_options);
6463
6464 // Feeds bytes sent from the client into the server's ProcessBytes.
6465 EXPECT_CALL(client_visitor, OnReadyToSend(_))
6466 .WillRepeatedly(
6467 testing::Invoke(server_adapter.get(), &OgHttp2Adapter::ProcessBytes));
6468 // Feeds bytes sent from the server into the client's ProcessBytes.
6469 EXPECT_CALL(server_visitor, OnReadyToSend(_))
6470 .WillRepeatedly(
6471 testing::Invoke(client_adapter.get(), &OgHttp2Adapter::ProcessBytes));
6472 // Sets up the server to respond automatically to a request from a client.
6473 EXPECT_CALL(server_visitor, OnEndHeadersForStream(_))
6474 .WillRepeatedly([&server_adapter](Http2StreamId stream_id) {
6475 server_adapter->SubmitResponse(
6476 stream_id, ToHeaders({{":status", "200"}}), nullptr);
6477 server_adapter->Send();
6478 return true;
6479 });
6480 // Sets up the client to create a new stream automatically when receiving a
6481 // response.
6482 EXPECT_CALL(client_visitor, OnEndHeadersForStream(_))
6483 .WillRepeatedly([&client_adapter,
6484 &client_visitor](Http2StreamId stream_id) {
6485 if (stream_id < 10) {
6486 const Http2StreamId new_stream_id = stream_id + 2;
6487 auto body =
6488 std::make_unique<TestDataFrameSource>(client_visitor, true);
6489 body->AppendPayload("This is an example request body.");
6490 body->EndData();
6491 const int created_stream_id = client_adapter->SubmitRequest(
6492 ToHeaders({{":method", "GET"},
6493 {":scheme", "http"},
6494 {":authority", "example.com"},
6495 {":path",
6496 absl::StrCat("/this/is/request/", new_stream_id)}}),
6497 std::move(body), nullptr);
6498 EXPECT_EQ(new_stream_id, created_stream_id);
6499 client_adapter->Send();
6500 }
6501 return true;
6502 });
6503
6504 // Submit a request to ensure the first stream is created.
6505 int stream_id = client_adapter->SubmitRequest(
6506 ToHeaders({{":method", "POST"},
6507 {":scheme", "http"},
6508 {":authority", "example.com"},
6509 {":path", "/this/is/request/one"}}),
6510 nullptr, nullptr);
6511 EXPECT_EQ(stream_id, 1);
6512
6513 client_adapter->Send();
6514 }
6515
TEST(OgHttp2AdapterInteractionTest,ClientServerInteractionRepeatedHeaderNames)6516 TEST(OgHttp2AdapterInteractionTest,
6517 ClientServerInteractionRepeatedHeaderNames) {
6518 DataSavingVisitor client_visitor;
6519 OgHttp2Adapter::Options client_options;
6520 client_options.perspective = Perspective::kClient;
6521 auto client_adapter = OgHttp2Adapter::Create(client_visitor, client_options);
6522
6523 const std::vector<Header> headers1 =
6524 ToHeaders({{":method", "GET"},
6525 {":scheme", "http"},
6526 {":authority", "example.com"},
6527 {":path", "/this/is/request/one"},
6528 {"accept", "text/plain"},
6529 {"accept", "text/html"}});
6530
6531 const int32_t stream_id1 =
6532 client_adapter->SubmitRequest(headers1, nullptr, nullptr);
6533 ASSERT_GT(stream_id1, 0);
6534
6535 EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6536 EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
6537 EXPECT_CALL(client_visitor,
6538 OnBeforeFrameSent(HEADERS, stream_id1, _,
6539 END_STREAM_FLAG | END_HEADERS_FLAG));
6540 EXPECT_CALL(client_visitor,
6541 OnFrameSent(HEADERS, stream_id1, _,
6542 END_STREAM_FLAG | END_HEADERS_FLAG, 0));
6543 int send_result = client_adapter->Send();
6544 EXPECT_EQ(0, send_result);
6545
6546 DataSavingVisitor server_visitor;
6547 OgHttp2Adapter::Options server_options;
6548 server_options.perspective = Perspective::kServer;
6549 auto server_adapter = OgHttp2Adapter::Create(server_visitor, server_options);
6550
6551 testing::InSequence s;
6552
6553 // Client preface (empty SETTINGS)
6554 EXPECT_CALL(server_visitor, OnFrameHeader(0, _, SETTINGS, 0));
6555 EXPECT_CALL(server_visitor, OnSettingsStart());
6556 EXPECT_CALL(server_visitor, OnSetting).Times(testing::AnyNumber());
6557 EXPECT_CALL(server_visitor, OnSettingsEnd());
6558 // Stream 1
6559 EXPECT_CALL(server_visitor, OnFrameHeader(1, _, HEADERS, 5));
6560 EXPECT_CALL(server_visitor, OnBeginHeadersForStream(1));
6561 EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":method", "GET"));
6562 EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":scheme", "http"));
6563 EXPECT_CALL(server_visitor,
6564 OnHeaderForStream(1, ":authority", "example.com"));
6565 EXPECT_CALL(server_visitor,
6566 OnHeaderForStream(1, ":path", "/this/is/request/one"));
6567 EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/plain"));
6568 EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/html"));
6569 EXPECT_CALL(server_visitor, OnEndHeadersForStream(1));
6570 EXPECT_CALL(server_visitor, OnEndStream(1));
6571
6572 int64_t result = server_adapter->ProcessBytes(client_visitor.data());
6573 EXPECT_EQ(client_visitor.data().size(), static_cast<size_t>(result));
6574 }
6575
TEST(OgHttp2AdapterTest,ServerForbidsNewStreamBelowWatermark)6576 TEST(OgHttp2AdapterTest, ServerForbidsNewStreamBelowWatermark) {
6577 DataSavingVisitor visitor;
6578 OgHttp2Adapter::Options options;
6579 options.perspective = Perspective::kServer;
6580 auto adapter = OgHttp2Adapter::Create(visitor, options);
6581
6582 EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
6583
6584 const std::string frames = TestFrameSequence()
6585 .ClientPreface()
6586 .Headers(3,
6587 {{":method", "POST"},
6588 {":scheme", "https"},
6589 {":authority", "example.com"},
6590 {":path", "/this/is/request/one"}},
6591 /*fin=*/false)
6592 .Data(3, "This is the request body.")
6593 .Headers(1,
6594 {{":method", "GET"},
6595 {":scheme", "http"},
6596 {":authority", "example.com"},
6597 {":path", "/this/is/request/two"}},
6598 /*fin=*/true)
6599 .Serialize();
6600 testing::InSequence s;
6601
6602 // Client preface (empty SETTINGS)
6603 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6604 EXPECT_CALL(visitor, OnSettingsStart());
6605 EXPECT_CALL(visitor, OnSettingsEnd());
6606
6607 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
6608 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
6609 EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "POST"));
6610 EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "https"));
6611 EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
6612 EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/one"));
6613 EXPECT_CALL(visitor, OnEndHeadersForStream(3));
6614 EXPECT_CALL(visitor, OnFrameHeader(3, 25, DATA, 0));
6615 EXPECT_CALL(visitor, OnBeginDataForStream(3, 25));
6616 EXPECT_CALL(visitor, OnDataForStream(3, "This is the request body."));
6617 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
6618 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kInvalidNewStreamId));
6619
6620 const int64_t result = adapter->ProcessBytes(frames);
6621 EXPECT_EQ(static_cast<size_t>(result), frames.size());
6622
6623 EXPECT_EQ(3, adapter->GetHighestReceivedStreamId());
6624
6625 EXPECT_TRUE(adapter->want_write());
6626
6627 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6628 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
6629 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6630 EXPECT_CALL(visitor,
6631 OnFrameSent(GOAWAY, 0, _, 0x0,
6632 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6633
6634 int send_result = adapter->Send();
6635 // Some bytes should have been serialized.
6636 EXPECT_EQ(0, send_result);
6637 EXPECT_THAT(visitor.data(),
6638 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
6639 }
6640
TEST(OgHttp2AdapterTest,ServerForbidsWindowUpdateOnIdleStream)6641 TEST(OgHttp2AdapterTest, ServerForbidsWindowUpdateOnIdleStream) {
6642 DataSavingVisitor visitor;
6643 OgHttp2Adapter::Options options;
6644 options.perspective = Perspective::kServer;
6645 auto adapter = OgHttp2Adapter::Create(visitor, options);
6646
6647 EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
6648
6649 const std::string frames =
6650 TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
6651
6652 testing::InSequence s;
6653
6654 // Client preface (empty SETTINGS)
6655 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6656 EXPECT_CALL(visitor, OnSettingsStart());
6657 EXPECT_CALL(visitor, OnSettingsEnd());
6658
6659 EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
6660 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
6661
6662 const int64_t result = adapter->ProcessBytes(frames);
6663 EXPECT_EQ(static_cast<size_t>(result), frames.size());
6664
6665 EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
6666
6667 EXPECT_TRUE(adapter->want_write());
6668
6669 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6670 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
6671 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6672 EXPECT_CALL(visitor,
6673 OnFrameSent(GOAWAY, 0, _, 0x0,
6674 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6675
6676 int send_result = adapter->Send();
6677 // Some bytes should have been serialized.
6678 EXPECT_EQ(0, send_result);
6679 EXPECT_THAT(visitor.data(),
6680 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
6681 }
6682
TEST(OgHttp2AdapterTest,ServerForbidsDataOnIdleStream)6683 TEST(OgHttp2AdapterTest, ServerForbidsDataOnIdleStream) {
6684 DataSavingVisitor visitor;
6685 OgHttp2Adapter::Options options;
6686 options.perspective = Perspective::kServer;
6687 auto adapter = OgHttp2Adapter::Create(visitor, options);
6688
6689 EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
6690
6691 const std::string frames = TestFrameSequence()
6692 .ClientPreface()
6693 .Data(1, "Sorry, out of order")
6694 .Serialize();
6695
6696 testing::InSequence s;
6697
6698 // Client preface (empty SETTINGS)
6699 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6700 EXPECT_CALL(visitor, OnSettingsStart());
6701 EXPECT_CALL(visitor, OnSettingsEnd());
6702
6703 EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
6704 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
6705
6706 const int64_t result = adapter->ProcessBytes(frames);
6707 EXPECT_EQ(static_cast<size_t>(result), frames.size());
6708
6709 EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
6710
6711 EXPECT_TRUE(adapter->want_write());
6712
6713 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6714 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
6715 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6716 EXPECT_CALL(visitor,
6717 OnFrameSent(GOAWAY, 0, _, 0x0,
6718 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6719
6720 int send_result = adapter->Send();
6721 // Some bytes should have been serialized.
6722 EXPECT_EQ(0, send_result);
6723 EXPECT_THAT(visitor.data(),
6724 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
6725 }
6726
TEST(OgHttp2AdapterTest,ServerForbidsRstStreamOnIdleStream)6727 TEST(OgHttp2AdapterTest, ServerForbidsRstStreamOnIdleStream) {
6728 DataSavingVisitor visitor;
6729 OgHttp2Adapter::Options options;
6730 options.perspective = Perspective::kServer;
6731 auto adapter = OgHttp2Adapter::Create(visitor, options);
6732
6733 EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
6734
6735 const std::string frames =
6736 TestFrameSequence()
6737 .ClientPreface()
6738 .RstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM)
6739 .Serialize();
6740
6741 testing::InSequence s;
6742
6743 // Client preface (empty SETTINGS)
6744 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6745 EXPECT_CALL(visitor, OnSettingsStart());
6746 EXPECT_CALL(visitor, OnSettingsEnd());
6747
6748 EXPECT_CALL(visitor, OnFrameHeader(1, _, RST_STREAM, 0));
6749 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
6750
6751 const int64_t result = adapter->ProcessBytes(frames);
6752 EXPECT_EQ(static_cast<size_t>(result), frames.size());
6753
6754 EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
6755
6756 EXPECT_TRUE(adapter->want_write());
6757
6758 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
6759 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
6760 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6761 EXPECT_CALL(visitor,
6762 OnFrameSent(GOAWAY, 0, _, 0x0,
6763 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6764
6765 int send_result = adapter->Send();
6766 // Some bytes should have been serialized.
6767 EXPECT_EQ(0, send_result);
6768 EXPECT_THAT(visitor.data(),
6769 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
6770 }
6771
TEST(OgHttp2AdapterTest,ServerForbidsNewStreamAboveStreamLimit)6772 TEST(OgHttp2AdapterTest, ServerForbidsNewStreamAboveStreamLimit) {
6773 DataSavingVisitor visitor;
6774 OgHttp2Adapter::Options options;
6775 options.perspective = Perspective::kServer;
6776 auto adapter = OgHttp2Adapter::Create(visitor, options);
6777 adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
6778
6779 const std::string initial_frames =
6780 TestFrameSequence().ClientPreface().Serialize();
6781
6782 testing::InSequence s;
6783
6784 // Client preface (empty SETTINGS)
6785 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6786 EXPECT_CALL(visitor, OnSettingsStart());
6787 EXPECT_CALL(visitor, OnSettingsEnd());
6788
6789 const int64_t initial_result = adapter->ProcessBytes(initial_frames);
6790 EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
6791
6792 EXPECT_TRUE(adapter->want_write());
6793
6794 // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
6795 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
6796 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
6797 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
6798 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
6799
6800 int send_result = adapter->Send();
6801 EXPECT_EQ(0, send_result);
6802 EXPECT_THAT(visitor.data(),
6803 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
6804 visitor.Clear();
6805
6806 // Let the client send a SETTINGS ack and then attempt to open more than the
6807 // advertised number of streams. The overflow stream should be rejected.
6808 const std::string stream_frames =
6809 TestFrameSequence()
6810 .SettingsAck()
6811 .Headers(1,
6812 {{":method", "GET"},
6813 {":scheme", "https"},
6814 {":authority", "example.com"},
6815 {":path", "/this/is/request/one"}},
6816 /*fin=*/true)
6817 .Headers(3,
6818 {{":method", "GET"},
6819 {":scheme", "http"},
6820 {":authority", "example.com"},
6821 {":path", "/this/is/request/two"}},
6822 /*fin=*/true)
6823 .Serialize();
6824
6825 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, ACK_FLAG));
6826 EXPECT_CALL(visitor, OnSettingsAck());
6827 EXPECT_CALL(visitor,
6828 OnFrameHeader(1, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
6829 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6830 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
6831 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6832 EXPECT_CALL(visitor, OnEndStream(1));
6833 EXPECT_CALL(visitor,
6834 OnFrameHeader(3, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
6835 EXPECT_CALL(
6836 visitor,
6837 OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kProtocol));
6838 // The oghttp2 stack also signals the error via OnConnectionError().
6839 EXPECT_CALL(visitor, OnConnectionError(
6840 ConnectionError::kExceededMaxConcurrentStreams));
6841
6842 const int64_t stream_result = adapter->ProcessBytes(stream_frames);
6843 EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
6844
6845 // The server should send a GOAWAY for this error, even though
6846 // OnInvalidFrame() returns true.
6847 EXPECT_TRUE(adapter->want_write());
6848 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
6849 EXPECT_CALL(visitor,
6850 OnFrameSent(GOAWAY, 0, _, 0x0,
6851 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6852
6853 send_result = adapter->Send();
6854 EXPECT_EQ(0, send_result);
6855 EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
6856 }
6857
TEST(OgHttp2AdapterTest,ServerRstStreamsNewStreamAboveStreamLimitBeforeAck)6858 TEST(OgHttp2AdapterTest, ServerRstStreamsNewStreamAboveStreamLimitBeforeAck) {
6859 DataSavingVisitor visitor;
6860 OgHttp2Adapter::Options options;
6861 options.perspective = Perspective::kServer;
6862 auto adapter = OgHttp2Adapter::Create(visitor, options);
6863 adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
6864
6865 const std::string initial_frames =
6866 TestFrameSequence().ClientPreface().Serialize();
6867
6868 testing::InSequence s;
6869
6870 // Client preface (empty SETTINGS)
6871 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6872 EXPECT_CALL(visitor, OnSettingsStart());
6873 EXPECT_CALL(visitor, OnSettingsEnd());
6874
6875 const int64_t initial_result = adapter->ProcessBytes(initial_frames);
6876 EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
6877
6878 EXPECT_TRUE(adapter->want_write());
6879
6880 // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
6881 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
6882 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
6883 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
6884 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
6885
6886 int send_result = adapter->Send();
6887 EXPECT_EQ(0, send_result);
6888 EXPECT_THAT(visitor.data(),
6889 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
6890 visitor.Clear();
6891
6892 // Let the client avoid sending a SETTINGS ack and attempt to open more than
6893 // the advertised number of streams. The server should still reject the
6894 // overflow stream, albeit with RST_STREAM REFUSED_STREAM instead of GOAWAY.
6895 const std::string stream_frames =
6896 TestFrameSequence()
6897 .Headers(1,
6898 {{":method", "GET"},
6899 {":scheme", "https"},
6900 {":authority", "example.com"},
6901 {":path", "/this/is/request/one"}},
6902 /*fin=*/true)
6903 .Headers(3,
6904 {{":method", "GET"},
6905 {":scheme", "http"},
6906 {":authority", "example.com"},
6907 {":path", "/this/is/request/two"}},
6908 /*fin=*/true)
6909 .Serialize();
6910
6911 EXPECT_CALL(visitor,
6912 OnFrameHeader(1, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
6913 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6914 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
6915 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
6916 EXPECT_CALL(visitor, OnEndStream(1));
6917 EXPECT_CALL(visitor,
6918 OnFrameHeader(3, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
6919 EXPECT_CALL(visitor,
6920 OnInvalidFrame(
6921 3, Http2VisitorInterface::InvalidFrameError::kRefusedStream));
6922
6923 const int64_t stream_result = adapter->ProcessBytes(stream_frames);
6924 EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
6925
6926 // The server sends a RST_STREAM for the offending stream.
6927 EXPECT_TRUE(adapter->want_write());
6928 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
6929 EXPECT_CALL(visitor,
6930 OnFrameSent(RST_STREAM, 3, _, 0x0,
6931 static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
6932
6933 send_result = adapter->Send();
6934 EXPECT_EQ(0, send_result);
6935 EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
6936 }
6937
TEST(OgHttp2AdapterTest,ServerForbidsProtocolPseudoheaderBeforeAck)6938 TEST(OgHttp2AdapterTest, ServerForbidsProtocolPseudoheaderBeforeAck) {
6939 DataSavingVisitor visitor;
6940 OgHttp2Adapter::Options options;
6941 options.perspective = Perspective::kServer;
6942 options.allow_extended_connect = false;
6943 auto adapter = OgHttp2Adapter::Create(visitor, options);
6944
6945 const std::string initial_frames =
6946 TestFrameSequence().ClientPreface().Serialize();
6947
6948 testing::InSequence s;
6949
6950 // Client preface (empty SETTINGS)
6951 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
6952 EXPECT_CALL(visitor, OnSettingsStart());
6953 EXPECT_CALL(visitor, OnSettingsEnd());
6954
6955 const int64_t initial_result = adapter->ProcessBytes(initial_frames);
6956 EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
6957
6958 // The client attempts to send a CONNECT request with the `:protocol`
6959 // pseudoheader before receiving the server's SETTINGS frame.
6960 const std::string stream1_frames =
6961 TestFrameSequence()
6962 .Headers(1,
6963 {{":method", "CONNECT"},
6964 {":scheme", "https"},
6965 {":authority", "example.com"},
6966 {":path", "/this/is/request/one"},
6967 {":protocol", "websocket"}},
6968 /*fin=*/true)
6969 .Serialize();
6970
6971 EXPECT_CALL(visitor,
6972 OnFrameHeader(1, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
6973 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
6974 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
6975 EXPECT_CALL(visitor,
6976 OnInvalidFrame(
6977 1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
6978
6979 int64_t stream_result = adapter->ProcessBytes(stream1_frames);
6980 EXPECT_EQ(static_cast<size_t>(stream_result), stream1_frames.size());
6981
6982 // Server initial SETTINGS and SETTINGS ack.
6983 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x0));
6984 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x0, 0));
6985 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
6986 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
6987
6988 // The server sends a RST_STREAM for the offending stream.
6989 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
6990 EXPECT_CALL(visitor,
6991 OnFrameSent(RST_STREAM, 1, _, 0x0,
6992 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
6993 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
6994
6995 // Server settings with ENABLE_CONNECT_PROTOCOL.
6996 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
6997 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
6998
6999 adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
7000 int send_result = adapter->Send();
7001 EXPECT_EQ(0, send_result);
7002 EXPECT_THAT(
7003 visitor.data(),
7004 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
7005 SpdyFrameType::RST_STREAM, SpdyFrameType::SETTINGS}));
7006 visitor.Clear();
7007
7008 // The client attempts to send a CONNECT request with the `:protocol`
7009 // pseudoheader before acking the server's SETTINGS frame.
7010 const std::string stream3_frames =
7011 TestFrameSequence()
7012 .Headers(3,
7013 {{":method", "CONNECT"},
7014 {":scheme", "https"},
7015 {":authority", "example.com"},
7016 {":path", "/this/is/request/two"},
7017 {":protocol", "websocket"}},
7018 /*fin=*/true)
7019 .Serialize();
7020
7021 // After sending SETTINGS with `ENABLE_CONNECT_PROTOCOL`, oghttp2 matches
7022 // nghttp2 in allowing this, even though the `allow_extended_connect` option
7023 // is false.
7024 EXPECT_CALL(visitor,
7025 OnFrameHeader(3, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
7026 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
7027 EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
7028 EXPECT_CALL(visitor, OnEndHeadersForStream(3));
7029 EXPECT_CALL(visitor, OnEndStream(3));
7030
7031 stream_result = adapter->ProcessBytes(stream3_frames);
7032 EXPECT_EQ(static_cast<size_t>(stream_result), stream3_frames.size());
7033
7034 EXPECT_FALSE(adapter->want_write());
7035 }
7036
TEST(OgHttp2AdapterTest,ServerAllowsProtocolPseudoheaderAfterAck)7037 TEST(OgHttp2AdapterTest, ServerAllowsProtocolPseudoheaderAfterAck) {
7038 DataSavingVisitor visitor;
7039 OgHttp2Adapter::Options options;
7040 options.perspective = Perspective::kServer;
7041 auto adapter = OgHttp2Adapter::Create(visitor, options);
7042 adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
7043
7044 const std::string initial_frames =
7045 TestFrameSequence().ClientPreface().Serialize();
7046
7047 testing::InSequence s;
7048
7049 // Client preface (empty SETTINGS)
7050 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7051 EXPECT_CALL(visitor, OnSettingsStart());
7052 EXPECT_CALL(visitor, OnSettingsEnd());
7053
7054 const int64_t initial_result = adapter->ProcessBytes(initial_frames);
7055 EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
7056
7057 // Server initial SETTINGS (with ENABLE_CONNECT_PROTOCOL) and SETTINGS ack.
7058 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
7059 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
7060 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
7061 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
7062
7063 int send_result = adapter->Send();
7064 EXPECT_EQ(0, send_result);
7065 visitor.Clear();
7066
7067 // The client attempts to send a CONNECT request with the `:protocol`
7068 // pseudoheader after acking the server's SETTINGS frame.
7069 const std::string stream_frames =
7070 TestFrameSequence()
7071 .SettingsAck()
7072 .Headers(1,
7073 {{":method", "CONNECT"},
7074 {":scheme", "https"},
7075 {":authority", "example.com"},
7076 {":path", "/this/is/request/one"},
7077 {":protocol", "websocket"}},
7078 /*fin=*/true)
7079 .Serialize();
7080
7081 EXPECT_CALL(visitor, OnFrameHeader(0, _, SETTINGS, ACK_FLAG));
7082 EXPECT_CALL(visitor, OnSettingsAck());
7083 EXPECT_CALL(visitor,
7084 OnFrameHeader(1, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
7085 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7086 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
7087 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7088 EXPECT_CALL(visitor, OnEndStream(1));
7089
7090 const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7091 EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
7092
7093 EXPECT_FALSE(adapter->want_write());
7094 }
7095
TEST(OgHttp2AdapterTest,SkipsSendingFramesForRejectedStream)7096 TEST(OgHttp2AdapterTest, SkipsSendingFramesForRejectedStream) {
7097 DataSavingVisitor visitor;
7098 OgHttp2Adapter::Options options;
7099 options.perspective = Perspective::kServer;
7100 auto adapter = OgHttp2Adapter::Create(visitor, options);
7101
7102 const std::string initial_frames =
7103 TestFrameSequence()
7104 .ClientPreface()
7105 .Headers(1,
7106 {{":method", "GET"},
7107 {":scheme", "http"},
7108 {":authority", "example.com"},
7109 {":path", "/this/is/request/one"}},
7110 /*fin=*/true)
7111 .Serialize();
7112
7113 testing::InSequence s;
7114
7115 // Client preface (empty SETTINGS)
7116 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7117 EXPECT_CALL(visitor, OnSettingsStart());
7118 EXPECT_CALL(visitor, OnSettingsEnd());
7119 EXPECT_CALL(visitor,
7120 OnFrameHeader(1, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
7121 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7122 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7123 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7124 EXPECT_CALL(visitor, OnEndStream(1));
7125
7126 const int64_t initial_result = adapter->ProcessBytes(initial_frames);
7127 EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
7128
7129 auto body = std::make_unique<TestDataFrameSource>(visitor, true);
7130 body->AppendPayload("Here is some data, which will be completely ignored!");
7131
7132 int submit_result = adapter->SubmitResponse(
7133 1, ToHeaders({{":status", "200"}}), std::move(body));
7134 ASSERT_EQ(0, submit_result);
7135
7136 auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
7137 {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
7138 adapter->SubmitMetadata(1, 16384u, std::move(source));
7139
7140 adapter->SubmitWindowUpdate(1, 1024);
7141 adapter->SubmitRst(1, Http2ErrorCode::INTERNAL_ERROR);
7142
7143 // Server initial SETTINGS and SETTINGS ack.
7144 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
7145 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
7146 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
7147 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
7148
7149 // The server sends a RST_STREAM for the offending stream.
7150 // The response HEADERS, DATA and WINDOW_UPDATE are all ignored.
7151 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
7152 EXPECT_CALL(visitor,
7153 OnFrameSent(RST_STREAM, 1, _, 0x0,
7154 static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
7155 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
7156
7157 int send_result = adapter->Send();
7158 EXPECT_EQ(0, send_result);
7159 EXPECT_THAT(visitor.data(),
7160 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
7161 SpdyFrameType::RST_STREAM}));
7162 }
7163
TEST(OgHttpAdapterServerTest,ServerStartsShutdown)7164 TEST(OgHttpAdapterServerTest, ServerStartsShutdown) {
7165 DataSavingVisitor visitor;
7166 OgHttp2Adapter::Options options;
7167 options.perspective = Perspective::kServer;
7168 auto adapter = OgHttp2Adapter::Create(visitor, options);
7169
7170 EXPECT_FALSE(adapter->want_write());
7171
7172 adapter->SubmitShutdownNotice();
7173 EXPECT_TRUE(adapter->want_write());
7174
7175 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
7176 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
7177 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
7178 EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
7179
7180 int result = adapter->Send();
7181 EXPECT_EQ(0, result);
7182 EXPECT_THAT(visitor.data(),
7183 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
7184 }
7185
TEST(OgHttp2AdapterTest,ServerStartsShutdownAfterGoaway)7186 TEST(OgHttp2AdapterTest, ServerStartsShutdownAfterGoaway) {
7187 DataSavingVisitor visitor;
7188 OgHttp2Adapter::Options options;
7189 options.perspective = Perspective::kServer;
7190 auto adapter = OgHttp2Adapter::Create(visitor, options);
7191
7192 EXPECT_FALSE(adapter->want_write());
7193
7194 adapter->SubmitGoAway(1, Http2ErrorCode::HTTP2_NO_ERROR,
7195 "and don't come back!");
7196 EXPECT_TRUE(adapter->want_write());
7197
7198 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
7199 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
7200 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
7201 EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
7202
7203 int result = adapter->Send();
7204 EXPECT_EQ(0, result);
7205 EXPECT_THAT(visitor.data(),
7206 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
7207
7208 // No-op, since a GOAWAY has previously been enqueued.
7209 adapter->SubmitShutdownNotice();
7210 EXPECT_FALSE(adapter->want_write());
7211 }
7212
7213 // Verifies that a connection-level processing error results in repeatedly
7214 // returning a positive value for ProcessBytes() to mark all data as consumed
7215 // when the blackhole option is enabled.
TEST(OgHttp2AdapterTest,ConnectionErrorWithBlackholingData)7216 TEST(OgHttp2AdapterTest, ConnectionErrorWithBlackholingData) {
7217 DataSavingVisitor visitor;
7218 OgHttp2Adapter::Options options;
7219 options.perspective = Perspective::kServer;
7220 options.blackhole_data_on_connection_error = true;
7221 auto adapter = OgHttp2Adapter::Create(visitor, options);
7222
7223 const std::string frames =
7224 TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
7225
7226 testing::InSequence s;
7227
7228 // Client preface (empty SETTINGS)
7229 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7230 EXPECT_CALL(visitor, OnSettingsStart());
7231 EXPECT_CALL(visitor, OnSettingsEnd());
7232
7233 EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
7234 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
7235
7236 const int64_t result = adapter->ProcessBytes(frames);
7237 EXPECT_EQ(static_cast<size_t>(result), frames.size());
7238
7239 // Ask the connection to process more bytes. Because the option is enabled,
7240 // the data should be marked as consumed.
7241 const std::string next_frame = TestFrameSequence().Ping(42).Serialize();
7242 const int64_t next_result = adapter->ProcessBytes(next_frame);
7243 EXPECT_EQ(static_cast<size_t>(next_result), next_frame.size());
7244 }
7245
7246 // Verifies that a connection-level processing error results in returning a
7247 // negative value for ProcessBytes() when the blackhole option is disabled.
TEST(OgHttp2AdapterTest,ConnectionErrorWithoutBlackholingData)7248 TEST(OgHttp2AdapterTest, ConnectionErrorWithoutBlackholingData) {
7249 DataSavingVisitor visitor;
7250 OgHttp2Adapter::Options options;
7251 options.perspective = Perspective::kServer;
7252 options.blackhole_data_on_connection_error = false;
7253 auto adapter = OgHttp2Adapter::Create(visitor, options);
7254
7255 const std::string frames =
7256 TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
7257
7258 testing::InSequence s;
7259
7260 // Client preface (empty SETTINGS)
7261 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7262 EXPECT_CALL(visitor, OnSettingsStart());
7263 EXPECT_CALL(visitor, OnSettingsEnd());
7264
7265 EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
7266 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
7267
7268 const int64_t result = adapter->ProcessBytes(frames);
7269 EXPECT_LT(result, 0);
7270
7271 // Ask the connection to process more bytes. Because the option is disabled,
7272 // ProcessBytes() should continue to return an error.
7273 const std::string next_frame = TestFrameSequence().Ping(42).Serialize();
7274 const int64_t next_result = adapter->ProcessBytes(next_frame);
7275 EXPECT_LT(next_result, 0);
7276 }
7277
TEST(OgHttp2AdapterTest,ServerDoesNotSendFramesAfterImmediateGoAway)7278 TEST(OgHttp2AdapterTest, ServerDoesNotSendFramesAfterImmediateGoAway) {
7279 DataSavingVisitor visitor;
7280 OgHttp2Adapter::Options options;
7281 options.perspective = Perspective::kServer;
7282 auto adapter = OgHttp2Adapter::Create(visitor, options);
7283
7284 // Submit a custom initial SETTINGS frame with one setting.
7285 adapter->SubmitSettings({{HEADER_TABLE_SIZE, 100u}});
7286
7287 const std::string frames = TestFrameSequence()
7288 .ClientPreface()
7289 .Headers(1,
7290 {{":method", "GET"},
7291 {":scheme", "https"},
7292 {":authority", "example.com"},
7293 {":path", "/this/is/request/one"}},
7294 /*fin=*/true)
7295 .Serialize();
7296 testing::InSequence s;
7297
7298 // Client preface (empty SETTINGS)
7299 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7300 EXPECT_CALL(visitor, OnSettingsStart());
7301 EXPECT_CALL(visitor, OnSettingsEnd());
7302 // Stream 1
7303 EXPECT_CALL(visitor,
7304 OnFrameHeader(1, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
7305 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7306 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7307 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7308 EXPECT_CALL(visitor, OnEndStream(1));
7309
7310 const int64_t read_result = adapter->ProcessBytes(frames);
7311 EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
7312
7313 // Submit a response for the stream.
7314 auto body = std::make_unique<TestDataFrameSource>(visitor, true);
7315 body->AppendPayload("This data is doomed to never be written.");
7316 int submit_result = adapter->SubmitResponse(
7317 1, ToHeaders({{":status", "200"}}), std::move(body));
7318 ASSERT_EQ(0, submit_result);
7319
7320 // Submit a WINDOW_UPDATE frame.
7321 adapter->SubmitWindowUpdate(kConnectionStreamId, 42);
7322
7323 // Submit another SETTINGS frame.
7324 adapter->SubmitSettings({});
7325
7326 // Submit some metadata.
7327 auto source = std::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
7328 {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
7329 adapter->SubmitMetadata(1, 16384u, std::move(source));
7330
7331 EXPECT_TRUE(adapter->want_write());
7332
7333 // Trigger a connection error. Only the response headers will be written.
7334 const std::string connection_error_frames =
7335 TestFrameSequence().WindowUpdate(3, 42).Serialize();
7336
7337 EXPECT_CALL(visitor, OnFrameHeader(3, 4, WINDOW_UPDATE, 0));
7338 EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
7339
7340 const int64_t result = adapter->ProcessBytes(connection_error_frames);
7341 EXPECT_EQ(static_cast<size_t>(result), connection_error_frames.size());
7342
7343 EXPECT_TRUE(adapter->want_write());
7344
7345 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
7346 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
7347 EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
7348 EXPECT_CALL(visitor,
7349 OnFrameSent(GOAWAY, 0, _, 0x0,
7350 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7351
7352 int send_result = adapter->Send();
7353 // Some bytes should have been serialized.
7354 EXPECT_EQ(0, send_result);
7355 EXPECT_THAT(visitor.data(),
7356 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
7357 visitor.Clear();
7358
7359 // Try to submit more frames for writing. They should not be written.
7360 adapter->SubmitPing(42);
7361 // TODO(diannahu): Enable the below expectation.
7362 // EXPECT_FALSE(adapter->want_write());
7363 send_result = adapter->Send();
7364 EXPECT_EQ(0, send_result);
7365 EXPECT_THAT(visitor.data(), testing::IsEmpty());
7366 }
7367
TEST(OgHttp2AdapterTest,ServerHandlesContentLength)7368 TEST(OgHttp2AdapterTest, ServerHandlesContentLength) {
7369 DataSavingVisitor visitor;
7370 OgHttp2Adapter::Options options;
7371 options.perspective = Perspective::kServer;
7372 auto adapter = OgHttp2Adapter::Create(visitor, options);
7373
7374 testing::InSequence s;
7375
7376 const std::string stream_frames =
7377 TestFrameSequence()
7378 .ClientPreface()
7379 .Headers(1, {{":method", "GET"},
7380 {":scheme", "https"},
7381 {":authority", "example.com"},
7382 {":path", "/this/is/request/one"},
7383 {"content-length", "2"}})
7384 .Data(1, "hi", /*fin=*/true)
7385 .Headers(3,
7386 {{":method", "GET"},
7387 {":scheme", "https"},
7388 {":authority", "example.com"},
7389 {":path", "/this/is/request/three"},
7390 {"content-length", "nan"}},
7391 /*fin=*/true)
7392 .Serialize();
7393
7394 // Client preface (empty SETTINGS)
7395 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7396 EXPECT_CALL(visitor, OnSettingsStart());
7397 EXPECT_CALL(visitor, OnSettingsEnd());
7398
7399 // Stream 1: content-length is correct
7400 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
7401 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7402 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
7403 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7404 EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
7405 EXPECT_CALL(visitor, OnBeginDataForStream(1, 2));
7406 EXPECT_CALL(visitor, OnDataForStream(1, "hi"));
7407 EXPECT_CALL(visitor, OnEndStream(1));
7408
7409 // Stream 3: content-length is not a number
7410 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
7411 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
7412 EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
7413 EXPECT_CALL(
7414 visitor,
7415 OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7416
7417 const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7418 EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7419
7420 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
7421 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
7422 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
7423 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
7424 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
7425 EXPECT_CALL(visitor,
7426 OnFrameSent(RST_STREAM, 3, _, 0x0,
7427 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7428 EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
7429
7430 EXPECT_TRUE(adapter->want_write());
7431 int result = adapter->Send();
7432 EXPECT_EQ(0, result);
7433 EXPECT_THAT(visitor.data(),
7434 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
7435 SpdyFrameType::RST_STREAM}));
7436 }
7437
TEST(OgHttp2AdapterTest,ServerHandlesContentLengthMismatch)7438 TEST(OgHttp2AdapterTest, ServerHandlesContentLengthMismatch) {
7439 DataSavingVisitor visitor;
7440 OgHttp2Adapter::Options options;
7441 options.perspective = Perspective::kServer;
7442 auto adapter = OgHttp2Adapter::Create(visitor, options);
7443
7444 testing::InSequence s;
7445
7446 const std::string stream_frames =
7447 TestFrameSequence()
7448 .ClientPreface()
7449 .Headers(1, {{":method", "GET"},
7450 {":scheme", "https"},
7451 {":authority", "example.com"},
7452 {":path", "/this/is/request/two"},
7453 {"content-length", "2"}})
7454 .Data(1, "h", /*fin=*/true)
7455 .Headers(3, {{":method", "GET"},
7456 {":scheme", "https"},
7457 {":authority", "example.com"},
7458 {":path", "/this/is/request/three"},
7459 {"content-length", "2"}})
7460 .Data(3, "howdy", /*fin=*/true)
7461 .Headers(5,
7462 {{":method", "GET"},
7463 {":scheme", "https"},
7464 {":authority", "example.com"},
7465 {":path", "/this/is/request/four"},
7466 {"content-length", "2"}},
7467 /*fin=*/true)
7468 .Headers(7,
7469 {{":method", "GET"},
7470 {":scheme", "https"},
7471 {":authority", "example.com"},
7472 {":path", "/this/is/request/four"},
7473 {"content-length", "2"}},
7474 /*fin=*/false)
7475 .Data(7, "h", /*fin=*/false)
7476 .Headers(7, {{"extra-info", "Trailers with content-length mismatch"}},
7477 /*fin=*/true)
7478 .Serialize();
7479
7480 // Client preface (empty SETTINGS)
7481 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7482 EXPECT_CALL(visitor, OnSettingsStart());
7483 EXPECT_CALL(visitor, OnSettingsEnd());
7484
7485 // Stream 1: content-length is larger than actual data
7486 // All data is delivered to the visitor. Note that neither oghttp2 nor
7487 // nghttp2 delivers OnInvalidFrame().
7488 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
7489 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7490 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
7491 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7492 EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
7493 EXPECT_CALL(visitor, OnBeginDataForStream(1, 1));
7494 EXPECT_CALL(visitor, OnDataForStream(1, "h"));
7495
7496 // Stream 3: content-length is smaller than actual data
7497 // The beginning of data is delivered to the visitor, but not the actual data.
7498 // Again, neither oghttp2 nor nghttp2 delivers OnInvalidFrame().
7499 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
7500 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
7501 EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
7502 EXPECT_CALL(visitor, OnEndHeadersForStream(3));
7503 EXPECT_CALL(visitor, OnFrameHeader(3, _, DATA, 1));
7504 EXPECT_CALL(visitor, OnBeginDataForStream(3, 5));
7505
7506 // Stream 5: content-length is invalid and HEADERS ends the stream
7507 // Only oghttp2 invokes OnEndHeadersForStream(). Both invoke
7508 // OnInvalidFrame().
7509 EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
7510 EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
7511 EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(5);
7512 EXPECT_CALL(visitor, OnEndHeadersForStream(5));
7513 EXPECT_CALL(visitor,
7514 OnInvalidFrame(
7515 5, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
7516
7517 // Stream 7: content-length is invalid and trailers end the stream
7518 // Only oghttp2 invokes OnEndHeadersForStream(). Both invoke
7519 // OnInvalidFrame().
7520 EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 4));
7521 EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
7522 EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(5);
7523 EXPECT_CALL(visitor, OnEndHeadersForStream(7));
7524 EXPECT_CALL(visitor, OnFrameHeader(7, _, DATA, 0));
7525 EXPECT_CALL(visitor, OnBeginDataForStream(7, 1));
7526 EXPECT_CALL(visitor, OnDataForStream(7, "h"));
7527 EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
7528 EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
7529 EXPECT_CALL(visitor, OnHeaderForStream(7, _, _));
7530 EXPECT_CALL(visitor, OnEndHeadersForStream(7));
7531 EXPECT_CALL(visitor,
7532 OnInvalidFrame(
7533 7, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
7534
7535 const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7536 EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7537
7538 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
7539 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
7540 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
7541 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
7542 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
7543 EXPECT_CALL(visitor,
7544 OnFrameSent(RST_STREAM, 1, _, 0x0,
7545 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7546 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
7547 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
7548 EXPECT_CALL(visitor,
7549 OnFrameSent(RST_STREAM, 3, _, 0x0,
7550 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7551 EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
7552 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
7553 EXPECT_CALL(visitor,
7554 OnFrameSent(RST_STREAM, 5, _, 0x0,
7555 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7556 EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
7557 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
7558 EXPECT_CALL(visitor,
7559 OnFrameSent(RST_STREAM, 7, _, 0x0,
7560 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7561 EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::HTTP2_NO_ERROR));
7562
7563 EXPECT_TRUE(adapter->want_write());
7564 int result = adapter->Send();
7565 EXPECT_EQ(0, result);
7566 EXPECT_THAT(
7567 visitor.data(),
7568 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
7569 SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
7570 SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
7571 }
7572
TEST(OgHttp2AdapterTest,ServerHandlesAsteriskPathForOptions)7573 TEST(OgHttp2AdapterTest, ServerHandlesAsteriskPathForOptions) {
7574 DataSavingVisitor visitor;
7575 OgHttp2Adapter::Options options;
7576 options.perspective = Perspective::kServer;
7577 auto adapter = OgHttp2Adapter::Create(visitor, options);
7578
7579 testing::InSequence s;
7580
7581 const std::string stream_frames = TestFrameSequence()
7582 .ClientPreface()
7583 .Headers(1,
7584 {{":scheme", "https"},
7585 {":authority", "example.com"},
7586 {":path", "*"},
7587 {":method", "OPTIONS"}},
7588 /*fin=*/true)
7589 .Serialize();
7590
7591 // Client preface (empty SETTINGS)
7592 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7593 EXPECT_CALL(visitor, OnSettingsStart());
7594 EXPECT_CALL(visitor, OnSettingsEnd());
7595
7596 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
7597 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7598 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7599 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7600 EXPECT_CALL(visitor, OnEndStream(1));
7601
7602 const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7603 EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7604
7605 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
7606 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
7607 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
7608 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
7609
7610 EXPECT_TRUE(adapter->want_write());
7611 int result = adapter->Send();
7612 EXPECT_EQ(0, result);
7613 EXPECT_THAT(visitor.data(),
7614 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
7615 }
7616
TEST(OgHttp2AdapterTest,ServerHandlesInvalidPath)7617 TEST(OgHttp2AdapterTest, ServerHandlesInvalidPath) {
7618 DataSavingVisitor visitor;
7619 OgHttp2Adapter::Options options;
7620 options.perspective = Perspective::kServer;
7621 auto adapter = OgHttp2Adapter::Create(visitor, options);
7622
7623 testing::InSequence s;
7624
7625 const std::string stream_frames =
7626 TestFrameSequence()
7627 .ClientPreface()
7628 .Headers(1,
7629 {{":scheme", "https"},
7630 {":authority", "example.com"},
7631 {":path", "*"},
7632 {":method", "GET"}},
7633 /*fin=*/true)
7634 .Headers(3,
7635 {{":scheme", "https"},
7636 {":authority", "example.com"},
7637 {":path", "other/non/slash/starter"},
7638 {":method", "GET"}},
7639 /*fin=*/true)
7640 .Headers(5,
7641 {{":scheme", "https"},
7642 {":authority", "example.com"},
7643 {":path", ""},
7644 {":method", "GET"}},
7645 /*fin=*/true)
7646 .Serialize();
7647
7648 // Client preface (empty SETTINGS)
7649 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7650 EXPECT_CALL(visitor, OnSettingsStart());
7651 EXPECT_CALL(visitor, OnSettingsEnd());
7652
7653 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
7654 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7655 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7656 EXPECT_CALL(visitor,
7657 OnInvalidFrame(
7658 1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
7659
7660 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
7661 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
7662 EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
7663 EXPECT_CALL(visitor,
7664 OnInvalidFrame(
7665 3, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
7666
7667 EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
7668 EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
7669 EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(2);
7670 EXPECT_CALL(
7671 visitor,
7672 OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7673
7674 const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7675 EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7676
7677 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
7678 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
7679 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
7680 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
7681 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
7682 EXPECT_CALL(visitor,
7683 OnFrameSent(RST_STREAM, 1, _, 0x0,
7684 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7685 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
7686 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
7687 EXPECT_CALL(visitor,
7688 OnFrameSent(RST_STREAM, 3, _, 0x0,
7689 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7690 EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
7691 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
7692 EXPECT_CALL(visitor,
7693 OnFrameSent(RST_STREAM, 5, _, 0x0,
7694 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7695 EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
7696
7697 EXPECT_TRUE(adapter->want_write());
7698 int result = adapter->Send();
7699 EXPECT_EQ(0, result);
7700 EXPECT_THAT(
7701 visitor.data(),
7702 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
7703 SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
7704 SpdyFrameType::RST_STREAM}));
7705 }
7706
TEST(OgHttp2AdapterTest,ServerHandlesTeHeader)7707 TEST(OgHttp2AdapterTest, ServerHandlesTeHeader) {
7708 DataSavingVisitor visitor;
7709 OgHttp2Adapter::Options options;
7710 options.perspective = Perspective::kServer;
7711 auto adapter = OgHttp2Adapter::Create(visitor, options);
7712
7713 testing::InSequence s;
7714
7715 const std::string stream_frames = TestFrameSequence()
7716 .ClientPreface()
7717 .Headers(1,
7718 {{":scheme", "https"},
7719 {":authority", "example.com"},
7720 {":path", "/"},
7721 {":method", "GET"},
7722 {"te", "trailers"}},
7723 /*fin=*/true)
7724 .Headers(3,
7725 {{":scheme", "https"},
7726 {":authority", "example.com"},
7727 {":path", "/"},
7728 {":method", "GET"},
7729 {"te", "trailers, deflate"}},
7730 /*fin=*/true)
7731 .Serialize();
7732
7733 // Client preface (empty SETTINGS)
7734 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7735 EXPECT_CALL(visitor, OnSettingsStart());
7736 EXPECT_CALL(visitor, OnSettingsEnd());
7737
7738 // Stream 1: TE: trailers should be allowed.
7739 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
7740 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7741 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
7742 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7743 EXPECT_CALL(visitor, OnEndStream(1));
7744
7745 // Stream 3: TE: <non-trailers> should be rejected.
7746 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
7747 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
7748 EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
7749 EXPECT_CALL(
7750 visitor,
7751 OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7752
7753 const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7754 EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7755
7756 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
7757 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
7758 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
7759 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
7760 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
7761 EXPECT_CALL(visitor,
7762 OnFrameSent(RST_STREAM, 3, _, 0x0,
7763 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7764 EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
7765
7766 EXPECT_TRUE(adapter->want_write());
7767 int result = adapter->Send();
7768 EXPECT_EQ(0, result);
7769 EXPECT_THAT(visitor.data(),
7770 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
7771 SpdyFrameType::RST_STREAM}));
7772 }
7773
TEST(OgHttp2AdapterTest,ServerHandlesConnectionSpecificHeaders)7774 TEST(OgHttp2AdapterTest, ServerHandlesConnectionSpecificHeaders) {
7775 DataSavingVisitor visitor;
7776 OgHttp2Adapter::Options options;
7777 options.perspective = Perspective::kServer;
7778 auto adapter = OgHttp2Adapter::Create(visitor, options);
7779
7780 testing::InSequence s;
7781
7782 const std::string stream_frames =
7783 TestFrameSequence()
7784 .ClientPreface()
7785 .Headers(1,
7786 {{":scheme", "https"},
7787 {":authority", "example.com"},
7788 {":path", "/"},
7789 {":method", "GET"},
7790 {"connection", "keep-alive"}},
7791 /*fin=*/true)
7792 .Headers(3,
7793 {{":scheme", "https"},
7794 {":authority", "example.com"},
7795 {":path", "/"},
7796 {":method", "GET"},
7797 {"proxy-connection", "keep-alive"}},
7798 /*fin=*/true)
7799 .Headers(5,
7800 {{":scheme", "https"},
7801 {":authority", "example.com"},
7802 {":path", "/"},
7803 {":method", "GET"},
7804 {"keep-alive", "timeout=42"}},
7805 /*fin=*/true)
7806 .Headers(7,
7807 {{":scheme", "https"},
7808 {":authority", "example.com"},
7809 {":path", "/"},
7810 {":method", "GET"},
7811 {"transfer-encoding", "chunked"}},
7812 /*fin=*/true)
7813 .Headers(9,
7814 {{":scheme", "https"},
7815 {":authority", "example.com"},
7816 {":path", "/"},
7817 {":method", "GET"},
7818 {"upgrade", "h2c"}},
7819 /*fin=*/true)
7820 .Serialize();
7821
7822 // Client preface (empty SETTINGS)
7823 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7824 EXPECT_CALL(visitor, OnSettingsStart());
7825 EXPECT_CALL(visitor, OnSettingsEnd());
7826
7827 // All streams contain a connection-specific header and should be rejected.
7828 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
7829 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7830 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7831 EXPECT_CALL(
7832 visitor,
7833 OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7834 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
7835 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
7836 EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
7837 EXPECT_CALL(
7838 visitor,
7839 OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7840 EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
7841 EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
7842 EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(4);
7843 EXPECT_CALL(
7844 visitor,
7845 OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7846 EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
7847 EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
7848 EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(4);
7849 EXPECT_CALL(
7850 visitor,
7851 OnInvalidFrame(7, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7852 EXPECT_CALL(visitor, OnFrameHeader(9, _, HEADERS, 5));
7853 EXPECT_CALL(visitor, OnBeginHeadersForStream(9));
7854 EXPECT_CALL(visitor, OnHeaderForStream(9, _, _)).Times(4);
7855 EXPECT_CALL(
7856 visitor,
7857 OnInvalidFrame(9, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
7858
7859 const int64_t stream_result = adapter->ProcessBytes(stream_frames);
7860 EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
7861
7862 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
7863 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
7864 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
7865 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
7866 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
7867 EXPECT_CALL(visitor,
7868 OnFrameSent(RST_STREAM, 1, _, 0x0,
7869 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7870 EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
7871 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
7872 EXPECT_CALL(visitor,
7873 OnFrameSent(RST_STREAM, 3, _, 0x0,
7874 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7875 EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
7876 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
7877 EXPECT_CALL(visitor,
7878 OnFrameSent(RST_STREAM, 5, _, 0x0,
7879 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7880 EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
7881 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
7882 EXPECT_CALL(visitor,
7883 OnFrameSent(RST_STREAM, 7, _, 0x0,
7884 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7885 EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::HTTP2_NO_ERROR));
7886 EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 9, _, 0x0));
7887 EXPECT_CALL(visitor,
7888 OnFrameSent(RST_STREAM, 9, _, 0x0,
7889 static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
7890 EXPECT_CALL(visitor, OnCloseStream(9, Http2ErrorCode::HTTP2_NO_ERROR));
7891
7892 EXPECT_TRUE(adapter->want_write());
7893 int result = adapter->Send();
7894 EXPECT_EQ(0, result);
7895 EXPECT_THAT(
7896 visitor.data(),
7897 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
7898 SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
7899 SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
7900 SpdyFrameType::RST_STREAM}));
7901 }
7902
TEST(OgHttp2AdapterTest,ServerUsesCustomWindowUpdateStrategy)7903 TEST(OgHttp2AdapterTest, ServerUsesCustomWindowUpdateStrategy) {
7904 // Test the use of a custom WINDOW_UPDATE strategy.
7905 DataSavingVisitor visitor;
7906 OgHttp2Adapter::Options options;
7907 options.should_window_update_fn = [](int64_t /*limit*/, int64_t /*size*/,
7908 int64_t /*delta*/) { return true; };
7909 options.perspective = Perspective::kServer;
7910 auto adapter = OgHttp2Adapter::Create(visitor, options);
7911
7912 const std::string frames = TestFrameSequence()
7913 .ClientPreface()
7914 .Headers(1,
7915 {{":method", "POST"},
7916 {":scheme", "https"},
7917 {":authority", "example.com"},
7918 {":path", "/this/is/request/one"}},
7919 /*fin=*/false)
7920 .Data(1, "This is the request body.",
7921 /*fin=*/true)
7922 .Serialize();
7923 testing::InSequence s;
7924
7925 // Client preface (empty SETTINGS)
7926 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
7927 EXPECT_CALL(visitor, OnSettingsStart());
7928 EXPECT_CALL(visitor, OnSettingsEnd());
7929
7930 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
7931 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
7932 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
7933 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
7934 EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, END_STREAM_FLAG));
7935 EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
7936 EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
7937 EXPECT_CALL(visitor, OnEndStream(1));
7938
7939 const int64_t result = adapter->ProcessBytes(frames);
7940 EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
7941
7942 // Mark a small number of bytes for the stream as consumed. Because of the
7943 // custom WINDOW_UPDATE strategy, the session should send WINDOW_UPDATEs.
7944 adapter->MarkDataConsumedForStream(1, 5);
7945
7946 EXPECT_TRUE(adapter->want_write());
7947
7948 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
7949 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
7950 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
7951 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
7952 EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 1, 4, 0x0));
7953 EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 1, 4, 0x0, 0));
7954 EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
7955 EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
7956
7957 int send_result = adapter->Send();
7958 EXPECT_EQ(0, send_result);
7959 EXPECT_THAT(visitor.data(),
7960 EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
7961 SpdyFrameType::WINDOW_UPDATE,
7962 SpdyFrameType::WINDOW_UPDATE}));
7963 }
7964
7965 // Verifies that NoopHeaderValidator allows several header combinations that
7966 // would otherwise be invalid.
TEST(OgHttp2AdapterTest,NoopHeaderValidatorTest)7967 TEST(OgHttp2AdapterTest, NoopHeaderValidatorTest) {
7968 DataSavingVisitor visitor;
7969 OgHttp2Adapter::Options options;
7970 options.perspective = Perspective::kServer;
7971 options.validate_http_headers = false;
7972 auto adapter = OgHttp2Adapter::Create(visitor, options);
7973
7974 const std::string frames = TestFrameSequence()
7975 .ClientPreface()
7976 .Headers(1,
7977 {{":method", "POST"},
7978 {":scheme", "https"},
7979 {":authority", "example.com"},
7980 {":path", "/1"},
7981 {"content-length", "7"},
7982 {"content-length", "7"}},
7983 /*fin=*/false)
7984 .Headers(3,
7985 {{":method", "POST"},
7986 {":scheme", "https"},
7987 {":authority", "example.com"},
7988 {":path", "/3"},
7989 {"content-length", "11"},
7990 {"content-length", "13"}},
7991 /*fin=*/false)
7992 .Headers(5,
7993 {{":method", "POST"},
7994 {":scheme", "https"},
7995 {":authority", "foo.com"},
7996 {":path", "/"},
7997 {"host", "bar.com"}},
7998 /*fin=*/true)
7999 .Headers(7,
8000 {{":method", "POST"},
8001 {":scheme", "https"},
8002 {":authority", "example.com"},
8003 {":path", "/"},
8004 {"Accept", "uppercase, oh boy!"}},
8005 /*fin=*/false)
8006 .Headers(9,
8007 {{":method", "POST"},
8008 {":scheme", "https"},
8009 {":authority", "ex|ample.com"},
8010 {":path", "/"}},
8011 /*fin=*/false)
8012 .Headers(11,
8013 {{":method", "GET"},
8014 {":scheme", "https"},
8015 {":authority", "example.com"},
8016 {":path", "/"},
8017 {"content-length", "nan"}},
8018 /*fin=*/true)
8019 .Serialize();
8020 testing::InSequence s;
8021
8022 // Client preface (empty SETTINGS)
8023 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
8024 EXPECT_CALL(visitor, OnSettingsStart());
8025 EXPECT_CALL(visitor, OnSettingsEnd());
8026 // Stream 1
8027 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
8028 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
8029 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
8030 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
8031 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
8032 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/1"));
8033 EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "7"));
8034 EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "7"));
8035 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
8036 // Stream 3
8037 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
8038 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
8039 EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "POST"));
8040 EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "https"));
8041 EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
8042 EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/3"));
8043 EXPECT_CALL(visitor, OnHeaderForStream(3, "content-length", "11"));
8044 EXPECT_CALL(visitor, OnHeaderForStream(3, "content-length", "13"));
8045 EXPECT_CALL(visitor, OnEndHeadersForStream(3));
8046 // Stream 5
8047 EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
8048 EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
8049 EXPECT_CALL(visitor, OnHeaderForStream(5, ":method", "POST"));
8050 EXPECT_CALL(visitor, OnHeaderForStream(5, ":scheme", "https"));
8051 EXPECT_CALL(visitor, OnHeaderForStream(5, ":authority", "foo.com"));
8052 EXPECT_CALL(visitor, OnHeaderForStream(5, ":path", "/"));
8053 EXPECT_CALL(visitor, OnHeaderForStream(5, "host", "bar.com"));
8054 EXPECT_CALL(visitor, OnEndHeadersForStream(5));
8055 EXPECT_CALL(visitor, OnEndStream(5));
8056 // Stream 7
8057 EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 4));
8058 EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
8059 EXPECT_CALL(visitor, OnHeaderForStream(7, ":method", "POST"));
8060 EXPECT_CALL(visitor, OnHeaderForStream(7, ":scheme", "https"));
8061 EXPECT_CALL(visitor, OnHeaderForStream(7, ":authority", "example.com"));
8062 EXPECT_CALL(visitor, OnHeaderForStream(7, ":path", "/"));
8063 EXPECT_CALL(visitor, OnHeaderForStream(7, "Accept", "uppercase, oh boy!"));
8064 EXPECT_CALL(visitor, OnEndHeadersForStream(7));
8065 // Stream 9
8066 EXPECT_CALL(visitor, OnFrameHeader(9, _, HEADERS, 4));
8067 EXPECT_CALL(visitor, OnBeginHeadersForStream(9));
8068 EXPECT_CALL(visitor, OnHeaderForStream(9, ":method", "POST"));
8069 EXPECT_CALL(visitor, OnHeaderForStream(9, ":scheme", "https"));
8070 EXPECT_CALL(visitor, OnHeaderForStream(9, ":authority", "ex|ample.com"));
8071 EXPECT_CALL(visitor, OnHeaderForStream(9, ":path", "/"));
8072 EXPECT_CALL(visitor, OnEndHeadersForStream(9));
8073 // Stream 11
8074 EXPECT_CALL(visitor, OnFrameHeader(11, _, HEADERS, 5));
8075 EXPECT_CALL(visitor, OnBeginHeadersForStream(11));
8076 EXPECT_CALL(visitor, OnHeaderForStream(11, ":method", "GET"));
8077 EXPECT_CALL(visitor, OnHeaderForStream(11, ":scheme", "https"));
8078 EXPECT_CALL(visitor, OnHeaderForStream(11, ":authority", "example.com"));
8079 EXPECT_CALL(visitor, OnHeaderForStream(11, ":path", "/"));
8080 EXPECT_CALL(visitor, OnHeaderForStream(11, "content-length", "nan"));
8081 EXPECT_CALL(visitor, OnEndHeadersForStream(11));
8082 EXPECT_CALL(visitor, OnEndStream(11));
8083
8084 const int64_t result = adapter->ProcessBytes(frames);
8085 EXPECT_EQ(frames.size(), static_cast<size_t>(result));
8086 }
8087
TEST(OgHttp2AdapterTest,NegativeFlowControlStreamResumption)8088 TEST(OgHttp2AdapterTest, NegativeFlowControlStreamResumption) {
8089 DataSavingVisitor visitor;
8090 OgHttp2Adapter::Options options;
8091 options.perspective = Perspective::kServer;
8092 auto adapter = OgHttp2Adapter::Create(visitor, options);
8093
8094 const std::string frames =
8095 TestFrameSequence()
8096 .ClientPreface({{INITIAL_WINDOW_SIZE, 128u * 1024u}})
8097 .WindowUpdate(0, 1 << 20)
8098 .Headers(1,
8099 {{":method", "GET"},
8100 {":scheme", "https"},
8101 {":authority", "example.com"},
8102 {":path", "/this/is/request/one"}},
8103 /*fin=*/true)
8104 .Serialize();
8105 testing::InSequence s;
8106
8107 // Client preface (empty SETTINGS)
8108 EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
8109 EXPECT_CALL(visitor, OnSettingsStart());
8110 EXPECT_CALL(visitor,
8111 OnSetting(Http2Setting{Http2KnownSettingsId::INITIAL_WINDOW_SIZE,
8112 128u * 1024u}));
8113 EXPECT_CALL(visitor, OnSettingsEnd());
8114
8115 EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
8116 EXPECT_CALL(visitor, OnWindowUpdate(0, 1 << 20));
8117
8118 // Stream 1
8119 EXPECT_CALL(visitor,
8120 OnFrameHeader(1, _, HEADERS, END_STREAM_FLAG | END_HEADERS_FLAG));
8121 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
8122 EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
8123 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
8124 EXPECT_CALL(visitor, OnEndStream(1));
8125
8126 const int64_t read_result = adapter->ProcessBytes(frames);
8127 EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
8128
8129 // Submit a response for the stream.
8130 auto body = std::make_unique<TestDataFrameSource>(visitor, true);
8131 TestDataFrameSource& body_ref = *body;
8132 body_ref.AppendPayload(std::string(70000, 'a'));
8133 int submit_result = adapter->SubmitResponse(
8134 1, ToHeaders({{":status", "200"}}), std::move(body));
8135 ASSERT_EQ(0, submit_result);
8136
8137 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
8138 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
8139
8140 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
8141 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
8142 EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, END_HEADERS_FLAG));
8143 EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, END_HEADERS_FLAG, 0));
8144 EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0)).Times(5);
8145
8146 adapter->Send();
8147 EXPECT_FALSE(adapter->want_write());
8148
8149 EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
8150 EXPECT_CALL(visitor, OnSettingsStart());
8151 EXPECT_CALL(visitor,
8152 OnSetting(Http2Setting{Http2KnownSettingsId::INITIAL_WINDOW_SIZE,
8153 64u * 1024u}));
8154 EXPECT_CALL(visitor, OnSettingsEnd());
8155
8156 // Processing these SETTINGS will cause stream 1's send window to become
8157 // negative.
8158 adapter->ProcessBytes(TestFrameSequence()
8159 .Settings({{INITIAL_WINDOW_SIZE, 64u * 1024u}})
8160 .Serialize());
8161 EXPECT_TRUE(adapter->want_write());
8162 EXPECT_LT(adapter->GetStreamSendWindowSize(1), 0);
8163
8164 body_ref.AppendPayload("Stream should be resumed.");
8165 adapter->ResumeStream(1);
8166
8167 EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK_FLAG));
8168 EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK_FLAG, 0));
8169 adapter->Send();
8170 EXPECT_FALSE(adapter->want_write());
8171
8172 // Upon receiving the WINDOW_UPDATE, stream 1 should be ready to write.
8173 EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
8174 EXPECT_CALL(visitor, OnWindowUpdate(1, 10000));
8175 adapter->ProcessBytes(TestFrameSequence().WindowUpdate(1, 10000).Serialize());
8176 EXPECT_TRUE(adapter->want_write());
8177 EXPECT_GT(adapter->GetStreamSendWindowSize(1), 0);
8178
8179 EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
8180 adapter->Send();
8181 }
8182
8183 // Verifies that Set-Cookie headers are not folded in either the sending or
8184 // receiving direction.
TEST(OgHttp2AdapterTest,SetCookieRoundtrip)8185 TEST(OgHttp2AdapterTest, SetCookieRoundtrip) {
8186 DataSavingVisitor client_visitor;
8187 OgHttp2Adapter::Options options;
8188 options.perspective = Perspective::kClient;
8189 auto client_adapter = OgHttp2Adapter::Create(client_visitor, options);
8190
8191 DataSavingVisitor server_visitor;
8192 options.perspective = Perspective::kServer;
8193 auto server_adapter = OgHttp2Adapter::Create(server_visitor, options);
8194
8195 // Set-Cookie is a response headers. For the server to respond, the client
8196 // needs to send a request to open the stream.
8197 const std::vector<Header> request_headers =
8198 ToHeaders({{":method", "GET"},
8199 {":scheme", "http"},
8200 {":authority", "example.com"},
8201 {":path", "/this/is/request/one"}});
8202
8203 const int32_t stream_id1 =
8204 client_adapter->SubmitRequest(request_headers, nullptr, nullptr);
8205 ASSERT_GT(stream_id1, 0);
8206
8207 // Client visitor expectations on send.
8208 // Client preface with SETTINGS.
8209 EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
8210 EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
8211 // The client request.
8212 EXPECT_CALL(client_visitor,
8213 OnBeforeFrameSent(HEADERS, stream_id1, _,
8214 END_STREAM_FLAG | END_HEADERS_FLAG));
8215 EXPECT_CALL(client_visitor,
8216 OnFrameSent(HEADERS, stream_id1, _,
8217 END_STREAM_FLAG | END_HEADERS_FLAG, 0));
8218
8219 EXPECT_EQ(0, client_adapter->Send());
8220
8221 // Server visitor expectations on receive.
8222 // Client preface (empty SETTINGS)
8223 EXPECT_CALL(server_visitor, OnFrameHeader(0, 6, SETTINGS, 0));
8224 EXPECT_CALL(server_visitor, OnSettingsStart());
8225 EXPECT_CALL(server_visitor,
8226 OnSetting(Http2Setting{Http2KnownSettingsId::ENABLE_PUSH, 0u}));
8227 EXPECT_CALL(server_visitor, OnSettingsEnd());
8228 // Stream 1
8229 EXPECT_CALL(server_visitor, OnFrameHeader(stream_id1, _, HEADERS, 5));
8230 EXPECT_CALL(server_visitor, OnBeginHeadersForStream(stream_id1));
8231 EXPECT_CALL(server_visitor, OnHeaderForStream).Times(4);
8232 EXPECT_CALL(server_visitor, OnEndHeadersForStream(stream_id1));
8233 EXPECT_CALL(server_visitor, OnEndStream(stream_id1));
8234
8235 // The server adapter processes the client's output.
8236 ASSERT_EQ(client_visitor.data().size(),
8237 server_adapter->ProcessBytes(client_visitor.data()));
8238
8239 // Response headers contain two individual Set-Cookie fields.
8240 const std::vector<Header> response_headers =
8241 ToHeaders({{":status", "200"},
8242 {"set-cookie", "chocolate_chip=yummy"},
8243 {"set-cookie", "macadamia_nut=okay"}});
8244
8245 EXPECT_EQ(
8246 0, server_adapter->SubmitResponse(stream_id1, response_headers, nullptr));
8247
8248 // Server visitor expectations on send.
8249 // Server preface with initial SETTINGS.
8250 EXPECT_CALL(server_visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
8251 EXPECT_CALL(server_visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
8252 // SETTINGS ack
8253 EXPECT_CALL(server_visitor, OnBeforeFrameSent(SETTINGS, 0, 0, ACK_FLAG));
8254 EXPECT_CALL(server_visitor, OnFrameSent(SETTINGS, 0, 0, ACK_FLAG, 0));
8255 // Stream 1 response.
8256 EXPECT_CALL(server_visitor,
8257 OnBeforeFrameSent(HEADERS, stream_id1, _,
8258 END_STREAM_FLAG | END_HEADERS_FLAG));
8259 EXPECT_CALL(server_visitor,
8260 OnFrameSent(HEADERS, stream_id1, _,
8261 END_STREAM_FLAG | END_HEADERS_FLAG, 0));
8262 // Stream 1 is complete.
8263 EXPECT_CALL(server_visitor,
8264 OnCloseStream(stream_id1, Http2ErrorCode::HTTP2_NO_ERROR));
8265
8266 EXPECT_EQ(0, server_adapter->Send());
8267
8268 // Client visitor expectations on receive.
8269 // Server preface with initial SETTINGS.
8270 EXPECT_CALL(client_visitor, OnFrameHeader(0, 6, SETTINGS, 0));
8271 EXPECT_CALL(client_visitor, OnSettingsStart());
8272 EXPECT_CALL(client_visitor,
8273 OnSetting(Http2Setting{
8274 Http2KnownSettingsId::ENABLE_CONNECT_PROTOCOL, 1u}));
8275 EXPECT_CALL(client_visitor, OnSettingsEnd());
8276 // SETTINGS ack.
8277 EXPECT_CALL(client_visitor, OnFrameHeader(0, 0, SETTINGS, ACK_FLAG));
8278 EXPECT_CALL(client_visitor, OnSettingsAck());
8279 // Stream 1 response.
8280 EXPECT_CALL(client_visitor, OnFrameHeader(stream_id1, _, HEADERS, 5));
8281 EXPECT_CALL(client_visitor, OnBeginHeadersForStream(stream_id1));
8282 EXPECT_CALL(client_visitor, OnHeaderForStream(stream_id1, ":status", "200"));
8283 // Note that the Set-Cookie headers are delivered individually.
8284 EXPECT_CALL(client_visitor, OnHeaderForStream(stream_id1, "set-cookie",
8285 "chocolate_chip=yummy"));
8286 EXPECT_CALL(client_visitor, OnHeaderForStream(stream_id1, "set-cookie",
8287 "macadamia_nut=okay"));
8288 EXPECT_CALL(client_visitor, OnEndHeadersForStream(stream_id1));
8289 EXPECT_CALL(client_visitor, OnEndStream(stream_id1));
8290 EXPECT_CALL(client_visitor,
8291 OnCloseStream(stream_id1, Http2ErrorCode::HTTP2_NO_ERROR));
8292
8293 // The client adapter processes the server's output.
8294 ASSERT_EQ(server_visitor.data().size(),
8295 client_adapter->ProcessBytes(server_visitor.data()));
8296 }
8297
8298 } // namespace
8299 } // namespace test
8300 } // namespace adapter
8301 } // namespace http2
8302