OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http2/decoder/http2_frame_decoder.h" | 5 #include "net/http2/decoder/http2_frame_decoder.h" |
6 | 6 |
7 // Tests of Http2FrameDecoder. | 7 // Tests of Http2FrameDecoder. |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <string> | 10 #include <string> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/bind.h" | |
14 #include "base/bind_helpers.h" | |
15 #include "base/logging.h" | 13 #include "base/logging.h" |
16 #include "net/http2/decoder/frame_parts.h" | 14 #include "net/http2/decoder/frame_parts.h" |
17 #include "net/http2/decoder/frame_parts_collector_listener.h" | 15 #include "net/http2/decoder/frame_parts_collector_listener.h" |
18 #include "net/http2/http2_constants.h" | 16 #include "net/http2/http2_constants.h" |
19 #include "net/http2/tools/failure.h" | 17 #include "net/http2/tools/failure.h" |
20 #include "net/http2/tools/http2_random.h" | 18 #include "net/http2/tools/http2_random.h" |
21 #include "net/http2/tools/random_decoder_test.h" | 19 #include "net/http2/tools/random_decoder_test.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
23 | 21 |
24 using base::StringPiece; | 22 using base::StringPiece; |
25 using std::string; | 23 using std::string; |
26 using ::testing::AssertionResult; | 24 using ::testing::AssertionResult; |
27 using ::testing::AssertionSuccess; | 25 using ::testing::AssertionSuccess; |
28 | 26 |
29 namespace net { | 27 namespace net { |
30 namespace test { | 28 namespace test { |
31 class Http2FrameDecoderPeer { | 29 class Http2FrameDecoderPeer { |
32 public: | 30 public: |
33 static size_t remaining_total_payload(Http2FrameDecoder* decoder) { | 31 static size_t remaining_total_payload(Http2FrameDecoder* decoder) { |
34 return decoder->frame_decoder_state_.remaining_total_payload(); | 32 return decoder->frame_decoder_state_.remaining_total_payload(); |
35 } | 33 } |
36 }; | 34 }; |
37 | 35 |
38 namespace { | 36 namespace { |
39 | 37 |
40 class Http2FrameDecoderTest : public RandomDecoderTest { | 38 class Http2FrameDecoderTest : public RandomDecoderTest { |
41 public: | |
42 AssertionResult ValidatorForDecodePayloadExpectingError( | |
43 const FrameParts& expected, | |
44 const DecodeBuffer& input, | |
45 DecodeStatus status) { | |
46 VERIFY_EQ(status, DecodeStatus::kDecodeError); | |
47 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
48 } | |
49 | |
50 AssertionResult ValidatorForBeyondMaximum(const FrameParts& expected, | |
51 const DecodeBuffer& input, | |
52 DecodeStatus status) { | |
53 VERIFY_EQ(status, DecodeStatus::kDecodeError); | |
54 // The decoder detects this error after decoding the header, and without | |
55 // trying to decode the payload. | |
56 VERIFY_EQ(input.Offset(), Http2FrameHeader::EncodedSize()); | |
57 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
58 } | |
59 | 39 |
60 protected: | 40 protected: |
61 void SetUp() override { | 41 void SetUp() override { |
62 // On any one run of this suite, we'll always choose the same value for | 42 // On any one run of this suite, we'll always choose the same value for |
63 // use_default_reconstruct_ because the random seed is the same for each | 43 // use_default_reconstruct_ because the random seed is the same for each |
64 // test case, but across runs the random seed changes. | 44 // test case, but across runs the random seed changes. |
65 use_default_reconstruct_ = Random().OneIn(2); | 45 use_default_reconstruct_ = Random().OneIn(2); |
66 } | 46 } |
67 | 47 |
68 DecodeStatus StartDecoding(DecodeBuffer* db) override { | 48 DecodeStatus StartDecoding(DecodeBuffer* db) override { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 } | 125 } |
146 | 126 |
147 AssertionResult DecodePayloadAndValidateSeveralWays(StringPiece payload, | 127 AssertionResult DecodePayloadAndValidateSeveralWays(StringPiece payload, |
148 Validator validator) { | 128 Validator validator) { |
149 DecodeBuffer db(payload); | 129 DecodeBuffer db(payload); |
150 bool start_decoding_requires_non_empty = false; | 130 bool start_decoding_requires_non_empty = false; |
151 return DecodeAndValidateSeveralWays(&db, start_decoding_requires_non_empty, | 131 return DecodeAndValidateSeveralWays(&db, start_decoding_requires_non_empty, |
152 validator); | 132 validator); |
153 } | 133 } |
154 | 134 |
155 AssertionResult ValidatorForDecodePayloadAndValidateSeveralWays( | |
156 const FrameParts& expected, | |
157 const DecodeBuffer& input, | |
158 DecodeStatus status) { | |
159 VERIFY_EQ(status, DecodeStatus::kDecodeDone); | |
160 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
161 } | |
162 | 135 |
163 // Decode one frame's payload and confirm that the listener recorded the | 136 // Decode one frame's payload and confirm that the listener recorded the |
164 // expected FrameParts instance, and only one FrameParts instance. The | 137 // expected FrameParts instance, and only one FrameParts instance. The |
165 // payload will be decoded several times with different partitionings | 138 // payload will be decoded several times with different partitionings |
166 // of the payload, and after each the validator will be called. | 139 // of the payload, and after each the validator will be called. |
167 AssertionResult DecodePayloadAndValidateSeveralWays( | 140 AssertionResult DecodePayloadAndValidateSeveralWays( |
168 StringPiece payload, | 141 StringPiece payload, |
169 const FrameParts& expected) { | 142 const FrameParts& expected) { |
170 Validator validator = base::Bind( | 143 Validator validator = [&expected, this]( |
171 &Http2FrameDecoderTest::ValidatorForDecodePayloadAndValidateSeveralWays, | 144 const DecodeBuffer& input, DecodeStatus status) -> AssertionResult { |
172 base::Unretained(this), base::ConstRef(expected)); | 145 VERIFY_EQ(status, DecodeStatus::kDecodeDone); |
| 146 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); |
| 147 }; |
173 ResetDecodeSpeedCounters(); | 148 ResetDecodeSpeedCounters(); |
174 VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays( | 149 VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays( |
175 payload, ValidateDoneAndEmpty(validator))); | 150 payload, ValidateDoneAndEmpty(validator))); |
176 VERIFY_GT(fast_decode_count_, 0u); | 151 VERIFY_GT(fast_decode_count_, 0u); |
177 VERIFY_GT(slow_decode_count_, 0u); | 152 VERIFY_GT(slow_decode_count_, 0u); |
178 | 153 |
179 // Repeat with more input; it should stop without reading that input. | 154 // Repeat with more input; it should stop without reading that input. |
180 string next_frame = Random().RandString(10); | 155 string next_frame = Random().RandString(10); |
181 string input; | 156 string input; |
182 payload.AppendToString(&input); | 157 payload.AppendToString(&input); |
(...skipping 19 matching lines...) Expand all Loading... |
202 AssertionResult DecodePayloadAndValidateSeveralWays( | 177 AssertionResult DecodePayloadAndValidateSeveralWays( |
203 const char (&buf)[N], | 178 const char (&buf)[N], |
204 const Http2FrameHeader& header) { | 179 const Http2FrameHeader& header) { |
205 return DecodePayloadAndValidateSeveralWays(StringPiece(buf, N), | 180 return DecodePayloadAndValidateSeveralWays(StringPiece(buf, N), |
206 FrameParts(header)); | 181 FrameParts(header)); |
207 } | 182 } |
208 | 183 |
209 template <size_t N> | 184 template <size_t N> |
210 AssertionResult DecodePayloadExpectingError(const char (&buf)[N], | 185 AssertionResult DecodePayloadExpectingError(const char (&buf)[N], |
211 const FrameParts& expected) { | 186 const FrameParts& expected) { |
| 187 auto validator = [&expected, this](const DecodeBuffer& input, |
| 188 DecodeStatus status) -> AssertionResult { |
| 189 VERIFY_EQ(status, DecodeStatus::kDecodeError); |
| 190 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); |
| 191 }; |
212 ResetDecodeSpeedCounters(); | 192 ResetDecodeSpeedCounters(); |
213 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays( | 193 EXPECT_TRUE( |
214 ToStringPiece(buf), | 194 DecodePayloadAndValidateSeveralWays(ToStringPiece(buf), validator)); |
215 base::Bind( | |
216 &Http2FrameDecoderTest::ValidatorForDecodePayloadExpectingError, | |
217 base::Unretained(this), expected))); | |
218 EXPECT_GT(fast_decode_count_, 0u); | 195 EXPECT_GT(fast_decode_count_, 0u); |
219 EXPECT_GT(slow_decode_count_, 0u); | 196 EXPECT_GT(slow_decode_count_, 0u); |
220 return AssertionSuccess(); | 197 return AssertionSuccess(); |
221 } | 198 } |
222 | 199 |
223 template <size_t N> | 200 template <size_t N> |
224 AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N], | 201 AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N], |
225 FrameParts expected) { | 202 FrameParts expected) { |
226 expected.has_frame_size_error = true; | 203 expected.has_frame_size_error = true; |
227 VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected)); | 204 VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected)); |
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) | 835 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) |
859 0x03, // Pad Len | 836 0x03, // Pad Len |
860 'a', 'b', 'c', // Data | 837 'a', 'b', 'c', // Data |
861 0x00, 0x00, 0x00, // Padding | 838 0x00, 0x00, 0x00, // Padding |
862 }; | 839 }; |
863 Http2FrameHeader header( | 840 Http2FrameHeader header( |
864 7, Http2FrameType::DATA, | 841 7, Http2FrameType::DATA, |
865 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_PADDED, 2); | 842 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_PADDED, 2); |
866 FrameParts expected(header); | 843 FrameParts expected(header); |
867 expected.has_frame_size_error = true; | 844 expected.has_frame_size_error = true; |
| 845 auto validator = [&expected, this](const DecodeBuffer& input, |
| 846 DecodeStatus status) -> AssertionResult { |
| 847 VERIFY_EQ(status, DecodeStatus::kDecodeError); |
| 848 // The decoder detects this error after decoding the header, and without |
| 849 // trying to decode the payload. |
| 850 VERIFY_EQ(input.Offset(), Http2FrameHeader::EncodedSize()); |
| 851 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); |
| 852 }; |
868 ResetDecodeSpeedCounters(); | 853 ResetDecodeSpeedCounters(); |
869 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays( | 854 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(ToStringPiece(kFrameData), |
870 ToStringPiece(kFrameData), | 855 validator)); |
871 base::Bind(&Http2FrameDecoderTest::ValidatorForBeyondMaximum, | |
872 base::Unretained(this), expected))); | |
873 EXPECT_GT(fast_decode_count_, 0u); | 856 EXPECT_GT(fast_decode_count_, 0u); |
874 EXPECT_GT(slow_decode_count_, 0u); | 857 EXPECT_GT(slow_decode_count_, 0u); |
875 } | 858 } |
876 | 859 |
877 TEST_F(Http2FrameDecoderTest, PriorityTooLong) { | 860 TEST_F(Http2FrameDecoderTest, PriorityTooLong) { |
878 const char kFrameData[] = { | 861 const char kFrameData[] = { |
879 0x00, 0x00, 0x06, // Length: 5 | 862 0x00, 0x00, 0x06, // Length: 5 |
880 0x02, // Type: PRIORITY | 863 0x02, // Type: PRIORITY |
881 0x00, // Flags: none | 864 0x00, // Flags: none |
882 0x00, 0x00, 0x00, 0x02, // Stream: 2 | 865 0x00, 0x00, 0x00, 0x02, // Stream: 2 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 0x80u, 0x00, 0x04, 0x00, // Incr: 1024 (plus R bit) | 921 0x80u, 0x00, 0x04, 0x00, // Incr: 1024 (plus R bit) |
939 0x00, // Too much | 922 0x00, // Too much |
940 }; | 923 }; |
941 Http2FrameHeader header(5, Http2FrameType::WINDOW_UPDATE, 0, 1); | 924 Http2FrameHeader header(5, Http2FrameType::WINDOW_UPDATE, 0, 1); |
942 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | 925 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); |
943 } | 926 } |
944 | 927 |
945 } // namespace | 928 } // namespace |
946 } // namespace test | 929 } // namespace test |
947 } // namespace net | 930 } // namespace net |
OLD | NEW |