Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Side by Side Diff: net/http2/decoder/http2_frame_decoder_test.cc

Issue 2554683003: Revert of Add new HTTP/2 and HPACK decoder in net/http2/. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/http2/decoder/http2_frame_decoder.h"
6
7 // Tests of Http2FrameDecoder.
8
9 #include <string>
10 #include <vector>
11
12 #include "base/bind.h"
13 #include "base/bind_helpers.h"
14 #include "base/logging.h"
15 #include "net/http2/decoder/frame_parts.h"
16 #include "net/http2/decoder/frame_parts_collector_listener.h"
17 #include "net/http2/http2_constants.h"
18 #include "net/http2/tools/failure.h"
19 #include "net/http2/tools/http2_random.h"
20 #include "net/http2/tools/random_decoder_test.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 using base::StringPiece;
24 using std::string;
25 using ::testing::AssertionResult;
26 using ::testing::AssertionSuccess;
27
28 namespace net {
29 namespace test {
30 class Http2FrameDecoderPeer {
31 public:
32 static size_t remaining_total_payload(Http2FrameDecoder* decoder) {
33 return decoder->frame_decoder_state_.remaining_total_payload();
34 }
35 };
36
37 namespace {
38
39 class Http2FrameDecoderTest : public RandomDecoderTest {
40 public:
41 AssertionResult ValidatorForDecodePayloadExpectingError(
42 const FrameParts& expected,
43 const DecodeBuffer& input,
44 DecodeStatus status) {
45 VERIFY_EQ(status, DecodeStatus::kDecodeError);
46 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected));
47 }
48
49 AssertionResult ValidatorForBeyondMaximum(const FrameParts& expected,
50 const DecodeBuffer& input,
51 DecodeStatus status) {
52 VERIFY_EQ(status, DecodeStatus::kDecodeError);
53 // The decoder detects this error after decoding the header, and without
54 // trying to decode the payload.
55 VERIFY_EQ(input.Offset(), Http2FrameHeader::EncodedSize());
56 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected));
57 }
58
59 protected:
60 void SetUp() override {
61 // On any one run of this suite, we'll always choose the same value for
62 // use_default_reconstruct_ because the random seed is the same for each
63 // test case, but across runs the random seed changes.
64 use_default_reconstruct_ = Random().OneIn(2);
65 }
66
67 DecodeStatus StartDecoding(DecodeBuffer* db) override {
68 DVLOG(2) << "StartDecoding, db->Remaining=" << db->Remaining();
69 collector_.Reset();
70 PrepareDecoder();
71
72 DecodeStatus status = decoder_.DecodeFrame(db);
73 if (status != DecodeStatus::kDecodeInProgress) {
74 // Keep track of this so that a concrete test can verify that both fast
75 // and slow decoding paths have been tested.
76 ++fast_decode_count_;
77 if (status == DecodeStatus::kDecodeError) {
78 ConfirmDiscardsRemainingPayload();
79 }
80 }
81 return status;
82 }
83
84 DecodeStatus ResumeDecoding(DecodeBuffer* db) override {
85 DVLOG(2) << "ResumeDecoding, db->Remaining=" << db->Remaining();
86 DecodeStatus status = decoder_.DecodeFrame(db);
87 if (status != DecodeStatus::kDecodeInProgress) {
88 // Keep track of this so that a concrete test can verify that both fast
89 // and slow decoding paths have been tested.
90 ++slow_decode_count_;
91 if (status == DecodeStatus::kDecodeError) {
92 ConfirmDiscardsRemainingPayload();
93 }
94 }
95 return status;
96 }
97
98 // When an error is returned, the decoder is in state kDiscardPayload, and
99 // stays there until the remaining bytes of the frame's payload have been
100 // skipped over. There are no callbacks for this situation.
101 void ConfirmDiscardsRemainingPayload() {
102 ASSERT_TRUE(decoder_.IsDiscardingPayload());
103 size_t remaining =
104 Http2FrameDecoderPeer::remaining_total_payload(&decoder_);
105 // The decoder will discard the remaining bytes, but not go beyond that,
106 // which these conditions verify.
107 size_t extra = 10;
108 string junk(remaining + extra, '0');
109 DecodeBuffer tmp(junk);
110 EXPECT_EQ(DecodeStatus::kDecodeDone, decoder_.DecodeFrame(&tmp));
111 EXPECT_EQ(remaining, tmp.Offset());
112 EXPECT_EQ(extra, tmp.Remaining());
113 EXPECT_FALSE(decoder_.IsDiscardingPayload());
114 }
115
116 void PrepareDecoder() {
117 // Save and restore the maximum_payload_size when reconstructing
118 // the decoder.
119 size_t maximum_payload_size = decoder_.maximum_payload_size();
120
121 // Alternate which constructor is used.
122 if (use_default_reconstruct_) {
123 decoder_.~Http2FrameDecoder();
124 new (&decoder_) Http2FrameDecoder;
125 decoder_.set_listener(&collector_);
126 } else {
127 decoder_.~Http2FrameDecoder();
128 new (&decoder_) Http2FrameDecoder(&collector_);
129 }
130 decoder_.set_maximum_payload_size(maximum_payload_size);
131
132 use_default_reconstruct_ = !use_default_reconstruct_;
133 }
134
135 void ResetDecodeSpeedCounters() {
136 fast_decode_count_ = 0;
137 slow_decode_count_ = 0;
138 }
139
140 AssertionResult VerifyCollected(const FrameParts& expected) {
141 VERIFY_FALSE(collector_.IsInProgress());
142 VERIFY_EQ(1u, collector_.size());
143 VERIFY_AND_RETURN_SUCCESS(expected.VerifyEquals(*collector_.frame(0)));
144 }
145
146 AssertionResult DecodePayloadAndValidateSeveralWays(StringPiece payload,
147 Validator validator) {
148 DecodeBuffer db(payload);
149 bool start_decoding_requires_non_empty = false;
150 return DecodeAndValidateSeveralWays(&db, start_decoding_requires_non_empty,
151 validator);
152 }
153
154 AssertionResult ValidatorForDecodePayloadAndValidateSeveralWays(
155 const FrameParts& expected,
156 const DecodeBuffer& input,
157 DecodeStatus status) {
158 VERIFY_EQ(status, DecodeStatus::kDecodeDone);
159 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected));
160 }
161
162 // Decode one frame's payload and confirm that the listener recorded the
163 // expected FrameParts instance, and only one FrameParts instance. The
164 // payload will be decoded several times with different partitionings
165 // of the payload, and after each the validator will be called.
166 AssertionResult DecodePayloadAndValidateSeveralWays(
167 StringPiece payload,
168 const FrameParts& expected) {
169 Validator validator = base::Bind(
170 &Http2FrameDecoderTest::ValidatorForDecodePayloadAndValidateSeveralWays,
171 base::Unretained(this), base::ConstRef(expected));
172 ResetDecodeSpeedCounters();
173 VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays(
174 payload, ValidateDoneAndEmpty(validator)));
175 VERIFY_GT(fast_decode_count_, 0u);
176 VERIFY_GT(slow_decode_count_, 0u);
177
178 // Repeat with more input; it should stop without reading that input.
179 string next_frame = Random().RandString(10);
180 string input;
181 payload.AppendToString(&input);
182 input += next_frame;
183
184 ResetDecodeSpeedCounters();
185 VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays(
186 payload, ValidateDoneAndOffset(payload.size(), validator)));
187 VERIFY_GT(fast_decode_count_, 0u);
188 VERIFY_GT(slow_decode_count_, 0u);
189
190 return AssertionSuccess();
191 }
192
193 template <size_t N>
194 AssertionResult DecodePayloadAndValidateSeveralWays(
195 const char (&buf)[N],
196 const FrameParts& expected) {
197 return DecodePayloadAndValidateSeveralWays(StringPiece(buf, N), expected);
198 }
199
200 template <size_t N>
201 AssertionResult DecodePayloadAndValidateSeveralWays(
202 const char (&buf)[N],
203 const Http2FrameHeader& header) {
204 return DecodePayloadAndValidateSeveralWays(StringPiece(buf, N),
205 FrameParts(header));
206 }
207
208 template <size_t N>
209 AssertionResult DecodePayloadExpectingError(const char (&buf)[N],
210 const FrameParts& expected) {
211 ResetDecodeSpeedCounters();
212 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(
213 ToStringPiece(buf),
214 base::Bind(
215 &Http2FrameDecoderTest::ValidatorForDecodePayloadExpectingError,
216 base::Unretained(this), expected)));
217 EXPECT_GT(fast_decode_count_, 0u);
218 EXPECT_GT(slow_decode_count_, 0u);
219 return AssertionSuccess();
220 }
221
222 template <size_t N>
223 AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N],
224 FrameParts expected) {
225 expected.has_frame_size_error = true;
226 VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected));
227 }
228
229 template <size_t N>
230 AssertionResult DecodePayloadExpectingFrameSizeError(
231 const char (&buf)[N],
232 const Http2FrameHeader& header) {
233 return DecodePayloadExpectingFrameSizeError(buf, FrameParts(header));
234 }
235
236 // Count of payloads that are fully decoded by StartDecodingPayload or for
237 // which an error was detected by StartDecodingPayload.
238 size_t fast_decode_count_ = 0;
239
240 // Count of payloads that required calling ResumeDecodingPayload in order to
241 // decode completely, or for which an error was detected by
242 // ResumeDecodingPayload.
243 size_t slow_decode_count_ = 0;
244
245 FramePartsCollectorListener collector_;
246 Http2FrameDecoder decoder_;
247 bool use_default_reconstruct_;
248 };
249
250 ////////////////////////////////////////////////////////////////////////////////
251 // Tests that pass the minimum allowed size for the frame type, which is often
252 // empty. The tests are in order by frame type value (i.e. 0 for DATA frames).
253
254 TEST_F(Http2FrameDecoderTest, DataEmpty) {
255 const char kFrameData[] = {
256 0x00, 0x00, 0x00, // Payload length: 0
257 0x00, // DATA
258 0x00, // Flags: none
259 0x00, 0x00, 0x00, 0x00, // Stream ID: 0 (invalid but unchecked here)
260 };
261 Http2FrameHeader header(0, Http2FrameType::DATA, 0, 0);
262 FrameParts expected(header, "");
263 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
264 }
265
266 TEST_F(Http2FrameDecoderTest, HeadersEmpty) {
267 const char kFrameData[] = {
268 0x00, 0x00, 0x00, // Payload length: 0
269 0x01, // HEADERS
270 0x00, // Flags: none
271 0x00, 0x00, 0x00, 0x01, // Stream ID: 0 (REQUIRES ID)
272 };
273 Http2FrameHeader header(0, Http2FrameType::HEADERS, 0, 1);
274 FrameParts expected(header, "");
275 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
276 }
277
278 TEST_F(Http2FrameDecoderTest, Priority) {
279 const char kFrameData[] = {
280 0x00, 0x00, 0x05, // Length: 5
281 0x02, // Type: PRIORITY
282 0x00, // Flags: none
283 0x00, 0x00, 0x00, 0x02, // Stream: 2
284 0x80u, 0x00, 0x00, 0x01, // Parent: 1 (Exclusive)
285 0x10, // Weight: 17
286 };
287 Http2FrameHeader header(5, Http2FrameType::PRIORITY, 0, 2);
288 FrameParts expected(header);
289 expected.opt_priority = Http2PriorityFields(1, 17, true);
290 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
291 }
292
293 TEST_F(Http2FrameDecoderTest, RstStream) {
294 const char kFrameData[] = {
295 0x00, 0x00, 0x04, // Length: 4
296 0x03, // Type: RST_STREAM
297 0x00, // Flags: none
298 0x00, 0x00, 0x00, 0x01, // Stream: 1
299 0x00, 0x00, 0x00, 0x01, // Error: PROTOCOL_ERROR
300 };
301 Http2FrameHeader header(4, Http2FrameType::RST_STREAM, 0, 1);
302 FrameParts expected(header);
303 expected.opt_rst_stream_error_code = Http2ErrorCode::PROTOCOL_ERROR;
304 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
305 }
306
307 TEST_F(Http2FrameDecoderTest, SettingsEmpty) {
308 const char kFrameData[] = {
309 0x00, 0x00, 0x00, // Length: 0
310 0x04, // Type: SETTINGS
311 0x00, // Flags: none
312 0x00, 0x00, 0x00, 0x01, // Stream: 1 (invalid but unchecked here)
313 };
314 Http2FrameHeader header(0, Http2FrameType::SETTINGS, 0, 1);
315 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, header));
316 }
317
318 TEST_F(Http2FrameDecoderTest, SettingsAck) {
319 const char kFrameData[] = {
320 0x00, 0x00, 0x00, // Length: 6
321 0x04, // Type: SETTINGS
322 0x01, // Flags: ACK
323 0x00, 0x00, 0x00, 0x00, // Stream: 0
324 };
325 Http2FrameHeader header(0, Http2FrameType::SETTINGS, Http2FrameFlag::FLAG_ACK,
326 0);
327 FrameParts expected(header);
328 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
329 }
330
331 TEST_F(Http2FrameDecoderTest, PushPromiseMinimal) {
332 const char kFrameData[] = {
333 0x00, 0x00, 0x04, // Payload length: 4
334 0x05, // PUSH_PROMISE
335 0x04, // Flags: END_HEADERS
336 0x00, 0x00, 0x00, 0x02, // Stream: 2 (invalid but unchecked here)
337 0x00, 0x00, 0x00, 0x01, // Promised: 1 (invalid but unchecked here)
338 };
339 Http2FrameHeader header(4, Http2FrameType::PUSH_PROMISE,
340 Http2FrameFlag::FLAG_END_HEADERS, 2);
341 FrameParts expected(header, "");
342 expected.opt_push_promise = Http2PushPromiseFields{1};
343 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
344 }
345
346 TEST_F(Http2FrameDecoderTest, Ping) {
347 const char kFrameData[] = {
348 0x00, 0x00, 0x08, // Length: 8
349 0x06, // Type: PING
350 0xfeu, // Flags: no valid flags
351 0x00, 0x00, 0x00, 0x00, // Stream: 0
352 's', 'o', 'm', 'e', // "some"
353 'd', 'a', 't', 'a', // "data"
354 };
355 Http2FrameHeader header(8, Http2FrameType::PING, 0, 0);
356 FrameParts expected(header);
357 expected.opt_ping = Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}};
358 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
359 }
360
361 TEST_F(Http2FrameDecoderTest, PingAck) {
362 const char kFrameData[] = {
363 0x00, 0x00, 0x08, // Length: 8
364 0x06, // Type: PING
365 0xffu, // Flags: ACK (plus all invalid flags)
366 0x00, 0x00, 0x00, 0x00, // Stream: 0
367 's', 'o', 'm', 'e', // "some"
368 'd', 'a', 't', 'a', // "data"
369 };
370 Http2FrameHeader header(8, Http2FrameType::PING, Http2FrameFlag::FLAG_ACK, 0);
371 FrameParts expected(header);
372 expected.opt_ping = Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}};
373 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
374 }
375
376 TEST_F(Http2FrameDecoderTest, GoAwayMinimal) {
377 const char kFrameData[] = {
378 0x00, 0x00, 0x08, // Length: 8 (no opaque data)
379 0x07, // Type: GOAWAY
380 0xffu, // Flags: 0xff (no valid flags)
381 0x00, 0x00, 0x00, 0x01, // Stream: 1 (invalid but unchecked here)
382 0x80u, 0x00, 0x00, 0xffu, // Last: 255 (plus R bit)
383 0x00, 0x00, 0x00, 0x09, // Error: COMPRESSION_ERROR
384 };
385 Http2FrameHeader header(8, Http2FrameType::GOAWAY, 0, 1);
386 FrameParts expected(header);
387 expected.opt_goaway =
388 Http2GoAwayFields(255, Http2ErrorCode::COMPRESSION_ERROR);
389 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
390 }
391
392 TEST_F(Http2FrameDecoderTest, WindowUpdate) {
393 const char kFrameData[] = {
394 0x00, 0x00, 0x04, // Length: 4
395 0x08, // Type: WINDOW_UPDATE
396 0x0f, // Flags: 0xff (no valid flags)
397 0x00, 0x00, 0x00, 0x01, // Stream: 1
398 0x80u, 0x00, 0x04, 0x00, // Incr: 1024 (plus R bit)
399 };
400 Http2FrameHeader header(4, Http2FrameType::WINDOW_UPDATE, 0, 1);
401 FrameParts expected(header);
402 expected.opt_window_update_increment = 1024;
403 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
404 }
405
406 TEST_F(Http2FrameDecoderTest, ContinuationEmpty) {
407 const char kFrameData[] = {
408 0x00, 0x00, 0x00, // Payload length: 0
409 0x09, // CONTINUATION
410 0x00, // Flags: none
411 0x00, 0x00, 0x00, 0x00, // Stream ID: 0 (invalid but unchecked here)
412 };
413 Http2FrameHeader header(0, Http2FrameType::CONTINUATION, 0, 0);
414 FrameParts expected(header);
415 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
416 }
417
418 TEST_F(Http2FrameDecoderTest, AltSvcMinimal) {
419 const char kFrameData[] = {
420 0x00, 0x00, 0x02, // Payload length: 2
421 0x0a, // ALTSVC
422 0xffu, // Flags: none (plus 0xff)
423 0x00, 0x00, 0x00, 0x00, // Stream ID: 0 (invalid but unchecked here)
424 0x00, 0x00, // Origin Length: 0
425 };
426 Http2FrameHeader header(2, Http2FrameType::ALTSVC, 0, 0);
427 FrameParts expected(header);
428 expected.opt_altsvc_origin_length = 0;
429 expected.opt_altsvc_value_length = 0;
430 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
431 }
432
433 TEST_F(Http2FrameDecoderTest, UnknownEmpty) {
434 const char kFrameData[] = {
435 0x00, 0x00, 0x00, // Payload length: 0
436 0x20, // 32 (unknown)
437 0xffu, // Flags: all
438 0x00, 0x00, 0x00, 0x00, // Stream ID: 0
439 };
440 Http2FrameHeader header(0, static_cast<Http2FrameType>(32), 0xff, 0);
441 FrameParts expected(header);
442 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
443 }
444
445 ////////////////////////////////////////////////////////////////////////////////
446 // Tests of longer payloads, for those frame types that allow longer payloads.
447
448 TEST_F(Http2FrameDecoderTest, DataPayload) {
449 const char kFrameData[] = {
450 0x00, 0x00, 0x03, // Payload length: 7
451 0x00, // DATA
452 0x80u, // Flags: 0x80
453 0x00, 0x00, 0x02, 0x02, // Stream ID: 514
454 'a', 'b', 'c', // Data
455 };
456 Http2FrameHeader header(3, Http2FrameType::DATA, 0, 514);
457 FrameParts expected(header, "abc");
458 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
459 }
460
461 TEST_F(Http2FrameDecoderTest, HeadersPayload) {
462 const char kFrameData[] = {
463 0x00, 0x00, 0x03, // Payload length: 3
464 0x01, // HEADERS
465 0x05, // Flags: END_STREAM | END_HEADERS
466 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID)
467 'a', 'b', 'c', // HPACK fragment (doesn't have to be valid)
468 };
469 Http2FrameHeader header(
470 3, Http2FrameType::HEADERS,
471 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_END_HEADERS, 2);
472 FrameParts expected(header, "abc");
473 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
474 }
475
476 TEST_F(Http2FrameDecoderTest, HeadersPriority) {
477 const char kFrameData[] = {
478 0x00, 0x00, 0x05, // Payload length: 5
479 0x01, // HEADERS
480 0x20, // Flags: PRIORITY
481 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID)
482 0x00, 0x00, 0x00, 0x01, // Parent: 1 (Not Exclusive)
483 0xffu, // Weight: 256
484 };
485 Http2FrameHeader header(5, Http2FrameType::HEADERS,
486 Http2FrameFlag::FLAG_PRIORITY, 2);
487 FrameParts expected(header);
488 expected.opt_priority = Http2PriorityFields(1, 256, false);
489 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
490 }
491
492 TEST_F(Http2FrameDecoderTest, Settings) {
493 const char kFrameData[] = {
494 0x00, 0x00, 0x0c, // Length: 12
495 0x04, // Type: SETTINGS
496 0x00, // Flags: none
497 0x00, 0x00, 0x00, 0x00, // Stream: 0
498 0x00, 0x04, // Param: INITIAL_WINDOW_SIZE
499 0x0a, 0x0b, 0x0c, 0x0d, // Value: 168496141
500 0x00, 0x02, // Param: ENABLE_PUSH
501 0x00, 0x00, 0x00, 0x03, // Value: 3 (invalid but unchecked here)
502 };
503 Http2FrameHeader header(12, Http2FrameType::SETTINGS, 0, 0);
504 FrameParts expected(header);
505 expected.settings.push_back(Http2SettingFields(
506 Http2SettingsParameter::INITIAL_WINDOW_SIZE, 168496141));
507 expected.settings.push_back(
508 Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3));
509 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
510 }
511
512 TEST_F(Http2FrameDecoderTest, PushPromisePayload) {
513 const char kFrameData[] = {
514 0x00, 0x00, 7, // Payload length: 7
515 0x05, // PUSH_PROMISE
516 0x04, // Flags: END_HEADERS
517 0x00, 0x00, 0x00, 0xffu, // Stream ID: 255
518 0x00, 0x00, 0x01, 0x00, // Promised: 256
519 'a', 'b', 'c', // HPACK fragment (doesn't have to be valid)
520 };
521 Http2FrameHeader header(7, Http2FrameType::PUSH_PROMISE,
522 Http2FrameFlag::FLAG_END_HEADERS, 255);
523 FrameParts expected(header, "abc");
524 expected.opt_push_promise = Http2PushPromiseFields{256};
525 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
526 }
527
528 TEST_F(Http2FrameDecoderTest, GoAwayOpaqueData) {
529 const char kFrameData[] = {
530 0x00, 0x00, 0x0e, // Length: 14
531 0x07, // Type: GOAWAY
532 0xffu, // Flags: 0xff (no valid flags)
533 0x80u, 0x00, 0x00, 0x00, // Stream: 0 (plus R bit)
534 0x00, 0x00, 0x01, 0x00, // Last: 256
535 0x00, 0x00, 0x00, 0x03, // Error: FLOW_CONTROL_ERROR
536 'o', 'p', 'a', 'q', 'u', 'e',
537 };
538 Http2FrameHeader header(14, Http2FrameType::GOAWAY, 0, 0);
539 FrameParts expected(header, "opaque");
540 expected.opt_goaway =
541 Http2GoAwayFields(256, Http2ErrorCode::FLOW_CONTROL_ERROR);
542 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
543 }
544
545 TEST_F(Http2FrameDecoderTest, ContinuationPayload) {
546 const char kFrameData[] = {
547 0x00, 0x00, 0x03, // Payload length: 3
548 0x09, // CONTINUATION
549 0xffu, // Flags: END_HEADERS | 0xfb
550 0x00, 0x00, 0x00, 0x02, // Stream ID: 2
551 'a', 'b', 'c', // Data
552 };
553 Http2FrameHeader header(3, Http2FrameType::CONTINUATION,
554 Http2FrameFlag::FLAG_END_HEADERS, 2);
555 FrameParts expected(header, "abc");
556 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
557 }
558
559 TEST_F(Http2FrameDecoderTest, AltSvcPayload) {
560 const char kFrameData[] = {
561 0x00, 0x00, 0x08, // Payload length: 3
562 0x0a, // ALTSVC
563 0x00, // Flags: none
564 0x00, 0x00, 0x00, 0x02, // Stream ID: 2
565 0x00, 0x03, // Origin Length: 0
566 'a', 'b', 'c', // Origin
567 'd', 'e', 'f', // Value
568 };
569 Http2FrameHeader header(8, Http2FrameType::ALTSVC, 0, 2);
570 FrameParts expected(header);
571 expected.SetAltSvcExpected("abc", "def");
572 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
573 }
574
575 TEST_F(Http2FrameDecoderTest, UnknownPayload) {
576 const char kFrameData[] = {
577 0x00, 0x00, 0x03, // Payload length: 3
578 0x30, // 48 (unknown)
579 0x00, // Flags: none
580 0x00, 0x00, 0x00, 0x02, // Stream ID: 2
581 'a', 'b', 'c', // Payload
582 };
583 Http2FrameHeader header(3, static_cast<Http2FrameType>(48), 0, 2);
584 FrameParts expected(header, "abc");
585 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
586 }
587
588 ////////////////////////////////////////////////////////////////////////////////
589 // Tests of padded payloads, for those frame types that allow padding.
590
591 TEST_F(Http2FrameDecoderTest, DataPayloadAndPadding) {
592 const char kFrameData[] = {
593 0x00, 0x00, 0x07, // Payload length: 7
594 0x00, // DATA
595 0x09, // Flags: END_STREAM | PADDED
596 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID)
597 0x03, // Pad Len
598 'a', 'b', 'c', // Data
599 0x00, 0x00, 0x00, // Padding
600 };
601 Http2FrameHeader header(
602 7, Http2FrameType::DATA,
603 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_PADDED, 2);
604 size_t total_pad_length = 4; // Including the Pad Length field.
605 FrameParts expected(header, "abc", total_pad_length);
606 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
607 }
608
609 TEST_F(Http2FrameDecoderTest, HeadersPayloadAndPadding) {
610 const char kFrameData[] = {
611 0x00, 0x00, 0x07, // Payload length: 7
612 0x01, // HEADERS
613 0x08, // Flags: PADDED
614 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID)
615 0x03, // Pad Len
616 'a', 'b', 'c', // HPACK fragment (doesn't have to be valid)
617 0x00, 0x00, 0x00, // Padding
618 };
619 Http2FrameHeader header(7, Http2FrameType::HEADERS,
620 Http2FrameFlag::FLAG_PADDED, 2);
621 size_t total_pad_length = 4; // Including the Pad Length field.
622 FrameParts expected(header, "abc", total_pad_length);
623 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
624 }
625
626 TEST_F(Http2FrameDecoderTest, HeadersPayloadPriorityAndPadding) {
627 const char kFrameData[] = {
628 0x00, 0x00, 0x0c, // Payload length: 12
629 0x01, // HEADERS
630 0xffu, // Flags: all, including undefined
631 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID)
632 0x03, // Pad Len
633 0x80u, 0x00, 0x00, 0x01, // Parent: 1 (Exclusive)
634 0x10, // Weight: 17
635 'a', 'b', 'c', // HPACK fragment (doesn't have to be valid)
636 0x00, 0x00, 0x00, // Padding
637 };
638 Http2FrameHeader header(
639 12, Http2FrameType::HEADERS,
640 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_END_HEADERS |
641 Http2FrameFlag::FLAG_PADDED | Http2FrameFlag::FLAG_PRIORITY,
642 2);
643 size_t total_pad_length = 4; // Including the Pad Length field.
644 FrameParts expected(header, "abc", total_pad_length);
645 expected.opt_priority = Http2PriorityFields(1, 17, true);
646 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
647 }
648
649 TEST_F(Http2FrameDecoderTest, PushPromisePayloadAndPadding) {
650 const char kFrameData[] = {
651 0x00, 0x00, 11, // Payload length: 11
652 0x05, // PUSH_PROMISE
653 0xffu, // Flags: END_HEADERS | PADDED | 0xf3
654 0x00, 0x00, 0x00, 0x01, // Stream ID: 1
655 0x03, // Pad Len
656 0x00, 0x00, 0x00, 0x02, // Promised: 2
657 'a', 'b', 'c', // HPACK fragment (doesn't have to be valid)
658 0x00, 0x00, 0x00, // Padding
659 };
660 Http2FrameHeader header(
661 11, Http2FrameType::PUSH_PROMISE,
662 Http2FrameFlag::FLAG_END_HEADERS | Http2FrameFlag::FLAG_PADDED, 1);
663 size_t total_pad_length = 4; // Including the Pad Length field.
664 FrameParts expected(header, "abc", total_pad_length);
665 expected.opt_push_promise = Http2PushPromiseFields{2};
666 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
667 }
668
669 ////////////////////////////////////////////////////////////////////////////////
670 // Payload too short errors.
671
672 TEST_F(Http2FrameDecoderTest, DataMissingPadLengthField) {
673 const char kFrameData[] = {
674 0x00, 0x00, 0x00, // Payload length: 0
675 0x00, // DATA
676 0x08, // Flags: PADDED
677 0x00, 0x00, 0x00, 0x01, // Stream ID: 1
678 };
679 Http2FrameHeader header(0, Http2FrameType::DATA, Http2FrameFlag::FLAG_PADDED,
680 1);
681 FrameParts expected(header);
682 expected.opt_missing_length = 1;
683 EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected));
684 }
685
686 TEST_F(Http2FrameDecoderTest, HeaderPaddingTooLong) {
687 const char kFrameData[] = {
688 0x00, 0x00, 0x02, // Payload length: 0
689 0x01, // HEADERS
690 0x08, // Flags: PADDED
691 0x00, 0x01, 0x00, 0x00, // Stream ID: 65536
692 0xffu, // Pad Len: 255
693 0x00, // Only one byte of padding
694 };
695 Http2FrameHeader header(2, Http2FrameType::HEADERS,
696 Http2FrameFlag::FLAG_PADDED, 65536);
697 FrameParts expected(header);
698 expected.opt_missing_length = 254;
699 EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected));
700 }
701
702 TEST_F(Http2FrameDecoderTest, HeaderMissingPriority) {
703 const char kFrameData[] = {
704 0x00, 0x00, 0x04, // Payload length: 0
705 0x01, // HEADERS
706 0x20, // Flags: PRIORITY
707 0x00, 0x01, 0x00, 0x00, // Stream ID: 65536
708 0x00, 0x00, 0x00, 0x00, // Priority (truncated)
709 };
710 Http2FrameHeader header(4, Http2FrameType::HEADERS,
711 Http2FrameFlag::FLAG_PRIORITY, 65536);
712 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
713 }
714
715 TEST_F(Http2FrameDecoderTest, PriorityTooShort) {
716 const char kFrameData[] = {
717 0x00, 0x00, 0x04, // Length: 5
718 0x02, // Type: PRIORITY
719 0x00, // Flags: none
720 0x00, 0x00, 0x00, 0x02, // Stream: 2
721 0x80u, 0x00, 0x00, 0x01, // Parent: 1 (Exclusive)
722 };
723 Http2FrameHeader header(4, Http2FrameType::PRIORITY, 0, 2);
724 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
725 }
726
727 TEST_F(Http2FrameDecoderTest, RstStreamTooShort) {
728 const char kFrameData[] = {
729 0x00, 0x00, 0x03, // Length: 4
730 0x03, // Type: RST_STREAM
731 0x00, // Flags: none
732 0x00, 0x00, 0x00, 0x01, // Stream: 1
733 0x00, 0x00, 0x00, // Truncated
734 };
735 Http2FrameHeader header(3, Http2FrameType::RST_STREAM, 0, 1);
736 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
737 }
738
739 // SETTINGS frames must a multiple of 6 bytes long, so an 9 byte payload is
740 // invalid.
741 TEST_F(Http2FrameDecoderTest, SettingsWrongSize) {
742 const char kFrameData[] = {
743 0x00, 0x00, 0x09, // Length: 2
744 0x04, // Type: SETTINGS
745 0x00, // Flags: none
746 0x00, 0x00, 0x00, 0x00, // Stream: 0
747 0x00, 0x02, // Param: ENABLE_PUSH
748 0x00, 0x00, 0x00, 0x03, // Value: 1
749 0x00, 0x04, // Param: INITIAL_WINDOW_SIZE
750 0x00, // Value: Truncated
751 };
752 Http2FrameHeader header(9, Http2FrameType::SETTINGS, 0, 0);
753 FrameParts expected(header);
754 expected.settings.push_back(
755 Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3));
756 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, expected));
757 }
758
759 TEST_F(Http2FrameDecoderTest, PushPromiseTooShort) {
760 const char kFrameData[] = {
761 0x00, 0x00, 3, // Payload length: 3
762 0x05, // PUSH_PROMISE
763 0x00, // Flags: none
764 0x00, 0x00, 0x00, 0x01, // Stream ID: 1
765 0x00, 0x00, 0x00, // Truncated promise id
766 };
767 Http2FrameHeader header(3, Http2FrameType::PUSH_PROMISE, 0, 1);
768 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
769 }
770
771 TEST_F(Http2FrameDecoderTest, PushPromisePaddedTruncatedPromise) {
772 const char kFrameData[] = {
773 0x00, 0x00, 4, // Payload length: 4
774 0x05, // PUSH_PROMISE
775 0x08, // Flags: PADDED
776 0x00, 0x00, 0x00, 0x01, // Stream ID: 1
777 0x00, // Pad Len
778 0x00, 0x00, 0x00, // Truncated promise id
779 };
780 Http2FrameHeader header(4, Http2FrameType::PUSH_PROMISE,
781 Http2FrameFlag::FLAG_PADDED, 1);
782 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
783 }
784
785 TEST_F(Http2FrameDecoderTest, PingTooShort) {
786 const char kFrameData[] = {
787 0x00, 0x00, 0x07, // Length: 8
788 0x06, // Type: PING
789 0xfeu, // Flags: no valid flags
790 0x00, 0x00, 0x00, 0x00, // Stream: 0
791 's', 'o', 'm', 'e', // "some"
792 'd', 'a', 't', // Too little
793 };
794 Http2FrameHeader header(7, Http2FrameType::PING, 0, 0);
795 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
796 }
797
798 TEST_F(Http2FrameDecoderTest, GoAwayTooShort) {
799 const char kFrameData[] = {
800 0x00, 0x00, 0x00, // Length: 0
801 0x07, // Type: GOAWAY
802 0xffu, // Flags: 0xff (no valid flags)
803 0x00, 0x00, 0x00, 0x00, // Stream: 0
804 };
805 Http2FrameHeader header(0, Http2FrameType::GOAWAY, 0, 0);
806 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
807 }
808
809 TEST_F(Http2FrameDecoderTest, WindowUpdateTooShort) {
810 const char kFrameData[] = {
811 0x00, 0x00, 0x03, // Length: 3
812 0x08, // Type: WINDOW_UPDATE
813 0x0f, // Flags: 0xff (no valid flags)
814 0x00, 0x00, 0x00, 0x01, // Stream: 1
815 0x80u, 0x00, 0x04, // Truncated
816 };
817 Http2FrameHeader header(3, Http2FrameType::WINDOW_UPDATE, 0, 1);
818 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
819 }
820
821 TEST_F(Http2FrameDecoderTest, AltSvcTruncatedOriginLength) {
822 const char kFrameData[] = {
823 0x00, 0x00, 0x01, // Payload length: 3
824 0x0a, // ALTSVC
825 0x00, // Flags: none
826 0x00, 0x00, 0x00, 0x02, // Stream ID: 2
827 0x00, // Origin Length: truncated
828 };
829 Http2FrameHeader header(1, Http2FrameType::ALTSVC, 0, 2);
830 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
831 }
832
833 TEST_F(Http2FrameDecoderTest, AltSvcTruncatedOrigin) {
834 const char kFrameData[] = {
835 0x00, 0x00, 0x05, // Payload length: 3
836 0x0a, // ALTSVC
837 0x00, // Flags: none
838 0x00, 0x00, 0x00, 0x02, // Stream ID: 2
839 0x00, 0x04, // Origin Length: 4 (too long)
840 'a', 'b', 'c', // Origin
841 };
842 Http2FrameHeader header(5, Http2FrameType::ALTSVC, 0, 2);
843 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
844 }
845
846 ////////////////////////////////////////////////////////////////////////////////
847 // Payload too long errors.
848
849 // The decoder calls the listener's OnFrameSizeError method if the frame's
850 // payload is longer than the currently configured maximum payload size.
851 TEST_F(Http2FrameDecoderTest, BeyondMaximum) {
852 decoder_.set_maximum_payload_size(2);
853 const char kFrameData[] = {
854 0x00, 0x00, 0x07, // Payload length: 7
855 0x00, // DATA
856 0x09, // Flags: END_STREAM | PADDED
857 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID)
858 0x03, // Pad Len
859 'a', 'b', 'c', // Data
860 0x00, 0x00, 0x00, // Padding
861 };
862 Http2FrameHeader header(
863 7, Http2FrameType::DATA,
864 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_PADDED, 2);
865 FrameParts expected(header);
866 expected.has_frame_size_error = true;
867 ResetDecodeSpeedCounters();
868 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(
869 ToStringPiece(kFrameData),
870 base::Bind(&Http2FrameDecoderTest::ValidatorForBeyondMaximum,
871 base::Unretained(this), expected)));
872 EXPECT_GT(fast_decode_count_, 0u);
873 EXPECT_GT(slow_decode_count_, 0u);
874 }
875
876 TEST_F(Http2FrameDecoderTest, PriorityTooLong) {
877 const char kFrameData[] = {
878 0x00, 0x00, 0x06, // Length: 5
879 0x02, // Type: PRIORITY
880 0x00, // Flags: none
881 0x00, 0x00, 0x00, 0x02, // Stream: 2
882 0x80u, 0x00, 0x00, 0x01, // Parent: 1 (Exclusive)
883 0x10, // Weight: 17
884 0x00, // Too much
885 };
886 Http2FrameHeader header(6, Http2FrameType::PRIORITY, 0, 2);
887 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
888 }
889
890 TEST_F(Http2FrameDecoderTest, RstStreamTooLong) {
891 const char kFrameData[] = {
892 0x00, 0x00, 0x05, // Length: 4
893 0x03, // Type: RST_STREAM
894 0x00, // Flags: none
895 0x00, 0x00, 0x00, 0x01, // Stream: 1
896 0x00, 0x00, 0x00, 0x01, // Error: PROTOCOL_ERROR
897 0x00, // Too much
898 };
899 Http2FrameHeader header(5, Http2FrameType::RST_STREAM, 0, 1);
900 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
901 }
902
903 TEST_F(Http2FrameDecoderTest, SettingsAckTooLong) {
904 const char kFrameData[] = {
905 0x00, 0x00, 0x06, // Length: 6
906 0x04, // Type: SETTINGS
907 0x01, // Flags: ACK
908 0x00, 0x00, 0x00, 0x00, // Stream: 0
909 0x00, 0x00, // Extra
910 0x00, 0x00, 0x00, 0x00, // Extra
911 };
912 Http2FrameHeader header(6, Http2FrameType::SETTINGS, Http2FrameFlag::FLAG_ACK,
913 0);
914 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
915 }
916
917 TEST_F(Http2FrameDecoderTest, PingAckTooLong) {
918 const char kFrameData[] = {
919 0x00, 0x00, 0x09, // Length: 8
920 0x06, // Type: PING
921 0xffu, // Flags: ACK | 0xfe
922 0x00, 0x00, 0x00, 0x00, // Stream: 0
923 's', 'o', 'm', 'e', // "some"
924 'd', 'a', 't', 'a', // "data"
925 0x00, // Too much
926 };
927 Http2FrameHeader header(9, Http2FrameType::PING, Http2FrameFlag::FLAG_ACK, 0);
928 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
929 }
930
931 TEST_F(Http2FrameDecoderTest, WindowUpdateTooLong) {
932 const char kFrameData[] = {
933 0x00, 0x00, 0x05, // Length: 5
934 0x08, // Type: WINDOW_UPDATE
935 0x0f, // Flags: 0xff (no valid flags)
936 0x00, 0x00, 0x00, 0x01, // Stream: 1
937 0x80u, 0x00, 0x04, 0x00, // Incr: 1024 (plus R bit)
938 0x00, // Too much
939 };
940 Http2FrameHeader header(5, Http2FrameType::WINDOW_UPDATE, 0, 1);
941 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
942 }
943
944 } // namespace
945 } // namespace test
946 } // namespace net
OLDNEW
« no previous file with comments | « net/http2/decoder/http2_frame_decoder_listener_test_util.cc ('k') | net/http2/decoder/http2_structure_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698