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/hpack/decoder/hpack_block_decoder.h" | 5 #include "net/http2/hpack/decoder/hpack_block_decoder.h" |
6 | 6 |
7 // Tests of HpackBlockDecoder. | 7 // Tests of HpackBlockDecoder. |
8 | 8 |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
11 #include "base/bind.h" | |
12 #include "base/bind_helpers.h" | |
13 #include "net/http2/decoder/decode_buffer.h" | 11 #include "net/http2/decoder/decode_buffer.h" |
14 #include "net/http2/hpack/decoder/hpack_block_collector.h" | 12 #include "net/http2/hpack/decoder/hpack_block_collector.h" |
15 #include "net/http2/hpack/http2_hpack_constants.h" | 13 #include "net/http2/hpack/http2_hpack_constants.h" |
16 #include "net/http2/hpack/tools/hpack_block_builder.h" | 14 #include "net/http2/hpack/tools/hpack_block_builder.h" |
17 #include "net/http2/hpack/tools/hpack_example.h" | 15 #include "net/http2/hpack/tools/hpack_example.h" |
18 #include "net/http2/tools/failure.h" | 16 #include "net/http2/tools/failure.h" |
19 #include "net/http2/tools/http2_random.h" | 17 #include "net/http2/tools/http2_random.h" |
20 #include "net/http2/tools/random_decoder_test.h" | 18 #include "net/http2/tools/random_decoder_test.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
22 | 20 |
23 using ::testing::AssertionSuccess; | 21 using ::testing::AssertionSuccess; |
24 using std::string; | 22 using std::string; |
25 using base::StringPiece; | 23 using base::StringPiece; |
26 | 24 |
27 namespace net { | 25 namespace net { |
28 namespace test { | 26 namespace test { |
29 namespace { | 27 namespace { |
30 | 28 |
31 class HpackBlockDecoderTest : public RandomDecoderTest { | 29 class HpackBlockDecoderTest : public RandomDecoderTest { |
32 public: | |
33 AssertionResult VerifyExpected(const HpackBlockCollector& expected) { | |
34 VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected)); | |
35 } | |
36 | |
37 AssertionResult ValidateForSpecExample_C_2_1() { | |
38 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader( | |
39 HpackEntryType::kIndexedLiteralHeader, false, "custom-key", false, | |
40 "custom-header")); | |
41 } | |
42 | |
43 AssertionResult ValidateForSpecExample_C_2_2() { | |
44 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralValueHeader( | |
45 HpackEntryType::kUnindexedLiteralHeader, 4, false, "/sample/path")); | |
46 } | |
47 | |
48 AssertionResult ValidateForSpecExample_C_2_3() { | |
49 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader( | |
50 HpackEntryType::kNeverIndexedLiteralHeader, false, "password", false, | |
51 "secret")); | |
52 } | |
53 | |
54 AssertionResult ValidateForSpecExample_C_2_4() { | |
55 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleIndexedHeader(2)); | |
56 } | |
57 | 30 |
58 protected: | 31 protected: |
59 HpackBlockDecoderTest() : listener_(&collector_), decoder_(&listener_) { | 32 HpackBlockDecoderTest() : listener_(&collector_), decoder_(&listener_) { |
60 stop_decode_on_done_ = false; | 33 stop_decode_on_done_ = false; |
61 decoder_.Reset(); | 34 decoder_.Reset(); |
62 // Make sure logging doesn't crash. Not examining the result. | 35 // Make sure logging doesn't crash. Not examining the result. |
63 std::ostringstream strm; | 36 std::ostringstream strm; |
64 strm << decoder_; | 37 strm << decoder_; |
65 } | 38 } |
66 | 39 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 | 78 |
106 string Rand8String() { return Random().RandString(Rand8()); } | 79 string Rand8String() { return Random().RandString(Rand8()); } |
107 | 80 |
108 HpackBlockCollector collector_; | 81 HpackBlockCollector collector_; |
109 HpackEntryDecoderVLoggingListener listener_; | 82 HpackEntryDecoderVLoggingListener listener_; |
110 HpackBlockDecoder decoder_; | 83 HpackBlockDecoder decoder_; |
111 }; | 84 }; |
112 | 85 |
113 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.1 | 86 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.1 |
114 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_1) { | 87 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_1) { |
115 NoArgValidator do_check = | 88 NoArgValidator do_check = [this]() { |
116 base::Bind(&HpackBlockDecoderTest::ValidateForSpecExample_C_2_1, | 89 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader( |
117 base::Unretained(this)); | 90 HpackEntryType::kIndexedLiteralHeader, false, "custom-key", false, |
| 91 "custom-header")); |
| 92 }; |
118 EXPECT_TRUE( | 93 EXPECT_TRUE( |
119 DecodeHpackExampleAndValidateSeveralWays(R"( | 94 DecodeHpackExampleAndValidateSeveralWays(R"( |
120 40 | == Literal indexed == | 95 40 | == Literal indexed == |
121 0a | Literal name (len = 10) | 96 0a | Literal name (len = 10) |
122 6375 7374 6f6d 2d6b 6579 | custom-key | 97 6375 7374 6f6d 2d6b 6579 | custom-key |
123 0d | Literal value (len = 13) | 98 0d | Literal value (len = 13) |
124 6375 7374 6f6d 2d68 6561 6465 72 | custom-header | 99 6375 7374 6f6d 2d68 6561 6465 72 | custom-header |
125 | -> custom-key: | 100 | -> custom-key: |
126 | custom-header | 101 | custom-header |
127 )", | 102 )", |
128 ValidateDoneAndEmpty(do_check))); | 103 ValidateDoneAndEmpty(do_check))); |
129 EXPECT_TRUE(do_check.Run()); | 104 EXPECT_TRUE(do_check()); |
130 } | 105 } |
131 | 106 |
132 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.2 | 107 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.2 |
133 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_2) { | 108 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_2) { |
134 NoArgValidator do_check = | 109 NoArgValidator do_check = [this]() { |
135 base::Bind(&HpackBlockDecoderTest::ValidateForSpecExample_C_2_2, | 110 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralValueHeader( |
136 base::Unretained(this)); | 111 HpackEntryType::kUnindexedLiteralHeader, 4, false, "/sample/path")); |
| 112 }; |
137 EXPECT_TRUE( | 113 EXPECT_TRUE( |
138 DecodeHpackExampleAndValidateSeveralWays(R"( | 114 DecodeHpackExampleAndValidateSeveralWays(R"( |
139 04 | == Literal not indexed == | 115 04 | == Literal not indexed == |
140 | Indexed name (idx = 4) | 116 | Indexed name (idx = 4) |
141 | :path | 117 | :path |
142 0c | Literal value (len = 12) | 118 0c | Literal value (len = 12) |
143 2f73 616d 706c 652f 7061 7468 | /sample/path | 119 2f73 616d 706c 652f 7061 7468 | /sample/path |
144 | -> :path: /sample/path | 120 | -> :path: /sample/path |
145 )", | 121 )", |
146 ValidateDoneAndEmpty(do_check))); | 122 ValidateDoneAndEmpty(do_check))); |
147 EXPECT_TRUE(do_check.Run()); | 123 EXPECT_TRUE(do_check()); |
148 } | 124 } |
149 | 125 |
150 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.3 | 126 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.3 |
151 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_3) { | 127 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_3) { |
152 NoArgValidator do_check = | 128 NoArgValidator do_check = [this]() { |
153 base::Bind(&HpackBlockDecoderTest::ValidateForSpecExample_C_2_3, | 129 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader( |
154 base::Unretained(this)); | 130 HpackEntryType::kNeverIndexedLiteralHeader, false, "password", false, |
| 131 "secret")); |
| 132 }; |
155 EXPECT_TRUE( | 133 EXPECT_TRUE( |
156 DecodeHpackExampleAndValidateSeveralWays(R"( | 134 DecodeHpackExampleAndValidateSeveralWays(R"( |
157 10 | == Literal never indexed == | 135 10 | == Literal never indexed == |
158 08 | Literal name (len = 8) | 136 08 | Literal name (len = 8) |
159 7061 7373 776f 7264 | password | 137 7061 7373 776f 7264 | password |
160 06 | Literal value (len = 6) | 138 06 | Literal value (len = 6) |
161 7365 6372 6574 | secret | 139 7365 6372 6574 | secret |
162 | -> password: secret | 140 | -> password: secret |
163 )", | 141 )", |
164 ValidateDoneAndEmpty(do_check))); | 142 ValidateDoneAndEmpty(do_check))); |
165 EXPECT_TRUE(do_check.Run()); | 143 EXPECT_TRUE(do_check()); |
166 } | 144 } |
167 | 145 |
168 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.4 | 146 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.4 |
169 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_4) { | 147 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_4) { |
170 NoArgValidator do_check = | 148 NoArgValidator do_check = [this]() { |
171 base::Bind(&HpackBlockDecoderTest::ValidateForSpecExample_C_2_4, | 149 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleIndexedHeader(2)); |
172 base::Unretained(this)); | 150 }; |
173 EXPECT_TRUE( | 151 EXPECT_TRUE( |
174 DecodeHpackExampleAndValidateSeveralWays(R"( | 152 DecodeHpackExampleAndValidateSeveralWays(R"( |
175 82 | == Indexed - Add == | 153 82 | == Indexed - Add == |
176 | idx = 2 | 154 | idx = 2 |
177 | -> :method: GET | 155 | -> :method: GET |
178 )", | 156 )", |
179 ValidateDoneAndEmpty(do_check))); | 157 ValidateDoneAndEmpty(do_check))); |
180 EXPECT_TRUE(do_check.Run()); | 158 EXPECT_TRUE(do_check()); |
181 } | 159 } |
182 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1 | 160 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1 |
183 TEST_F(HpackBlockDecoderTest, SpecExample_C_3_1) { | 161 TEST_F(HpackBlockDecoderTest, SpecExample_C_3_1) { |
184 string example = R"( | 162 string example = R"( |
185 82 | == Indexed - Add == | 163 82 | == Indexed - Add == |
186 | idx = 2 | 164 | idx = 2 |
187 | -> :method: GET | 165 | -> :method: GET |
188 86 | == Indexed - Add == | 166 86 | == Indexed - Add == |
189 | idx = 6 | 167 | idx = 6 |
190 | -> :scheme: http | 168 | -> :scheme: http |
191 84 | == Indexed - Add == | 169 84 | == Indexed - Add == |
192 | idx = 4 | 170 | idx = 4 |
193 | -> :path: / | 171 | -> :path: / |
194 41 | == Literal indexed == | 172 41 | == Literal indexed == |
195 | Indexed name (idx = 1) | 173 | Indexed name (idx = 1) |
196 | :authority | 174 | :authority |
197 0f | Literal value (len = 15) | 175 0f | Literal value (len = 15) |
198 7777 772e 6578 616d 706c 652e 636f 6d | www.example.com | 176 7777 772e 6578 616d 706c 652e 636f 6d | www.example.com |
199 | -> :authority: | 177 | -> :authority: |
200 | www.example.com | 178 | www.example.com |
201 )"; | 179 )"; |
202 HpackBlockCollector expected; | 180 HpackBlockCollector expected; |
203 expected.ExpectIndexedHeader(2); | 181 expected.ExpectIndexedHeader(2); |
204 expected.ExpectIndexedHeader(6); | 182 expected.ExpectIndexedHeader(6); |
205 expected.ExpectIndexedHeader(4); | 183 expected.ExpectIndexedHeader(4); |
206 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, | 184 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, |
207 1, false, "www.example.com"); | 185 1, false, "www.example.com"); |
208 NoArgValidator do_check = base::Bind(&HpackBlockDecoderTest::VerifyExpected, | 186 NoArgValidator do_check = [expected, this]() { |
209 base::Unretained(this), expected); | 187 VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected)); |
| 188 }; |
210 EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays( | 189 EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays( |
211 example, ValidateDoneAndEmpty(do_check))); | 190 example, ValidateDoneAndEmpty(do_check))); |
212 EXPECT_TRUE(do_check.Run()); | 191 EXPECT_TRUE(do_check()); |
213 } | 192 } |
214 | 193 |
215 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.5.1 | 194 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.5.1 |
216 TEST_F(HpackBlockDecoderTest, SpecExample_C_5_1) { | 195 TEST_F(HpackBlockDecoderTest, SpecExample_C_5_1) { |
217 string example = R"( | 196 string example = R"( |
218 48 | == Literal indexed == | 197 48 | == Literal indexed == |
219 | Indexed name (idx = 8) | 198 | Indexed name (idx = 8) |
220 | :status | 199 | :status |
221 03 | Literal value (len = 3) | 200 03 | Literal value (len = 3) |
222 3330 32 | 302 | 201 3330 32 | 302 |
(...skipping 24 matching lines...) Expand all Loading... |
247 HpackBlockCollector expected; | 226 HpackBlockCollector expected; |
248 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, | 227 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, |
249 8, false, "302"); | 228 8, false, "302"); |
250 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, | 229 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, |
251 24, false, "private"); | 230 24, false, "private"); |
252 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, | 231 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, |
253 33, false, | 232 33, false, |
254 "Mon, 21 Oct 2013 20:13:21 GMT"); | 233 "Mon, 21 Oct 2013 20:13:21 GMT"); |
255 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, | 234 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, |
256 46, false, "https://www.example.com"); | 235 46, false, "https://www.example.com"); |
257 NoArgValidator do_check = base::Bind(&HpackBlockDecoderTest::VerifyExpected, | 236 NoArgValidator do_check = [expected, this]() { |
258 base::Unretained(this), expected); | 237 VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected)); |
| 238 }; |
259 EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays( | 239 EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays( |
260 example, ValidateDoneAndEmpty(do_check))); | 240 example, ValidateDoneAndEmpty(do_check))); |
261 EXPECT_TRUE(do_check.Run()); | 241 EXPECT_TRUE(do_check()); |
262 } | 242 } |
263 | 243 |
264 // Generate a bunch of HPACK block entries to expect, use those expectations | 244 // Generate a bunch of HPACK block entries to expect, use those expectations |
265 // to generate an HPACK block, then decode it and confirm it matches those | 245 // to generate an HPACK block, then decode it and confirm it matches those |
266 // expectations. Some of these are invalid (such as Indexed, with index=0), | 246 // expectations. Some of these are invalid (such as Indexed, with index=0), |
267 // but well-formed, and the decoder doesn't check for validity, just | 247 // but well-formed, and the decoder doesn't check for validity, just |
268 // well-formedness. That includes the validity of the strings not being checked, | 248 // well-formedness. That includes the validity of the strings not being checked, |
269 // such as lower-case ascii for the names, and valid Huffman encodings. | 249 // such as lower-case ascii for the names, and valid Huffman encodings. |
270 TEST_F(HpackBlockDecoderTest, Computed) { | 250 TEST_F(HpackBlockDecoderTest, Computed) { |
271 HpackBlockCollector expected; | 251 HpackBlockCollector expected; |
(...skipping 24 matching lines...) Expand all Loading... |
296 value_huffman, Rand8String()); | 276 value_huffman, Rand8String()); |
297 expected.ExpectLiteralNameAndValue(type, true, Rand8String(), | 277 expected.ExpectLiteralNameAndValue(type, true, Rand8String(), |
298 value_huffman, Rand8String()); | 278 value_huffman, Rand8String()); |
299 } | 279 } |
300 } | 280 } |
301 // Shuffle the entries and serialize them to produce an HPACK block. | 281 // Shuffle the entries and serialize them to produce an HPACK block. |
302 expected.ShuffleEntries(RandomPtr()); | 282 expected.ShuffleEntries(RandomPtr()); |
303 HpackBlockBuilder hbb; | 283 HpackBlockBuilder hbb; |
304 expected.AppendToHpackBlockBuilder(&hbb); | 284 expected.AppendToHpackBlockBuilder(&hbb); |
305 | 285 |
306 NoArgValidator do_check = base::Bind(&HpackBlockDecoderTest::VerifyExpected, | 286 NoArgValidator do_check = [expected, this]() { |
307 base::Unretained(this), expected); | 287 VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected)); |
| 288 }; |
308 EXPECT_TRUE( | 289 EXPECT_TRUE( |
309 DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check))); | 290 DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check))); |
310 EXPECT_TRUE(do_check.Run()); | 291 EXPECT_TRUE(do_check()); |
311 } | 292 } |
312 | 293 |
313 } // namespace | 294 } // namespace |
314 } // namespace test | 295 } // namespace test |
315 } // namespace net | 296 } // namespace net |
OLD | NEW |