OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/spdy/hpack/hpack_decoder.h" | 5 #include "net/spdy/hpack/hpack_decoder.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 | 54 |
55 namespace { | 55 namespace { |
56 | 56 |
57 using base::StringPiece; | 57 using base::StringPiece; |
58 using std::string; | 58 using std::string; |
59 using test::a2b_hex; | 59 using test::a2b_hex; |
60 | 60 |
61 using testing::ElementsAre; | 61 using testing::ElementsAre; |
62 using testing::Pair; | 62 using testing::Pair; |
63 | 63 |
64 const size_t kLiteralBound = 1024; | |
65 | |
66 class HpackDecoderTest : public ::testing::TestWithParam<bool> { | 64 class HpackDecoderTest : public ::testing::TestWithParam<bool> { |
67 protected: | 65 protected: |
68 HpackDecoderTest() : decoder_(), decoder_peer_(&decoder_) {} | 66 HpackDecoderTest() : decoder_(), decoder_peer_(&decoder_) {} |
69 | 67 |
70 void SetUp() override { handler_exists_ = GetParam(); } | 68 void SetUp() override { handler_exists_ = GetParam(); } |
71 | 69 |
72 bool DecodeHeaderBlock(StringPiece str) { | 70 bool DecodeHeaderBlock(StringPiece str) { |
73 if (handler_exists_) { | 71 if (handler_exists_) { |
74 decoder_.HandleControlFrameHeadersStart(&handler_); | 72 decoder_.HandleControlFrameHeadersStart(&handler_); |
75 } | 73 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 ElementsAre(Pair("cookie", " part 1; part 2 ; part3; fin!"), | 189 ElementsAre(Pair("cookie", " part 1; part 2 ; part3; fin!"), |
192 Pair("passed-through", StringPiece("foo\0baz", 7)), | 190 Pair("passed-through", StringPiece("foo\0baz", 7)), |
193 Pair("joined", "not joined"), | 191 Pair("joined", "not joined"), |
194 Pair("joineD", StringPiece("value 1\0value 2", 15)), | 192 Pair("joineD", StringPiece("value 1\0value 2", 15)), |
195 Pair("empty", ""), | 193 Pair("empty", ""), |
196 Pair("empty-joined", StringPiece("\0foo\0\0", 6)))); | 194 Pair("empty-joined", StringPiece("\0foo\0\0", 6)))); |
197 } | 195 } |
198 | 196 |
199 // Decoding an encoded name with a valid string literal should work. | 197 // Decoding an encoded name with a valid string literal should work. |
200 TEST_P(HpackDecoderTest, DecodeNextNameLiteral) { | 198 TEST_P(HpackDecoderTest, DecodeNextNameLiteral) { |
201 HpackInputStream input_stream(kLiteralBound, StringPiece("\x00\x04name", 6)); | 199 HpackInputStream input_stream(StringPiece("\x00\x04name", 6)); |
202 | 200 |
203 StringPiece string_piece; | 201 StringPiece string_piece; |
204 EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); | 202 EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); |
205 EXPECT_EQ("name", string_piece); | 203 EXPECT_EQ("name", string_piece); |
206 EXPECT_FALSE(input_stream.HasMoreData()); | 204 EXPECT_FALSE(input_stream.HasMoreData()); |
207 EXPECT_FALSE(input_stream.NeedMoreData()); | 205 EXPECT_FALSE(input_stream.NeedMoreData()); |
208 input_stream.MarkCurrentPosition(); | 206 input_stream.MarkCurrentPosition(); |
209 EXPECT_EQ(6u, input_stream.ParsedBytes()); | 207 EXPECT_EQ(6u, input_stream.ParsedBytes()); |
210 } | 208 } |
211 | 209 |
212 // Decoding an encoded name with an incomplete string literal. | 210 // Decoding an encoded name with an incomplete string literal. |
213 TEST_P(HpackDecoderTest, DecodeNextNameLiteralWithIncompleteHeader) { | 211 TEST_P(HpackDecoderTest, DecodeNextNameLiteralWithIncompleteHeader) { |
214 HpackInputStream input_stream(kLiteralBound, | 212 HpackInputStream input_stream(StringPiece("\x00\x04name\x00\x02g", 9)); |
215 StringPiece("\x00\x04name\x00\x02g", 9)); | |
216 | 213 |
217 StringPiece string_piece; | 214 StringPiece string_piece; |
218 EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); | 215 EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); |
219 EXPECT_FALSE(input_stream.NeedMoreData()); | 216 EXPECT_FALSE(input_stream.NeedMoreData()); |
220 input_stream.MarkCurrentPosition(); | 217 input_stream.MarkCurrentPosition(); |
221 EXPECT_EQ(6u, input_stream.ParsedBytes()); | 218 EXPECT_EQ(6u, input_stream.ParsedBytes()); |
222 | 219 |
223 EXPECT_FALSE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); | 220 EXPECT_FALSE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); |
224 EXPECT_TRUE(input_stream.NeedMoreData()); | 221 EXPECT_TRUE(input_stream.NeedMoreData()); |
225 input_stream.MarkCurrentPosition(); | 222 input_stream.MarkCurrentPosition(); |
226 EXPECT_EQ(8u, input_stream.ParsedBytes()); | 223 EXPECT_EQ(8u, input_stream.ParsedBytes()); |
227 } | 224 } |
228 | 225 |
229 TEST_P(HpackDecoderTest, DecodeNextNameLiteralWithHuffmanEncoding) { | 226 TEST_P(HpackDecoderTest, DecodeNextNameLiteralWithHuffmanEncoding) { |
230 string input = a2b_hex("008825a849e95ba97d7f"); | 227 string input = a2b_hex("008825a849e95ba97d7f"); |
231 HpackInputStream input_stream(kLiteralBound, input); | 228 HpackInputStream input_stream(input); |
232 | 229 |
233 StringPiece string_piece; | 230 StringPiece string_piece; |
234 EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); | 231 EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); |
235 EXPECT_EQ("custom-key", string_piece); | 232 EXPECT_EQ("custom-key", string_piece); |
236 EXPECT_FALSE(input_stream.HasMoreData()); | 233 EXPECT_FALSE(input_stream.HasMoreData()); |
237 EXPECT_FALSE(input_stream.NeedMoreData()); | 234 EXPECT_FALSE(input_stream.NeedMoreData()); |
238 input_stream.MarkCurrentPosition(); | 235 input_stream.MarkCurrentPosition(); |
239 EXPECT_EQ(input.size(), input_stream.ParsedBytes()); | 236 EXPECT_EQ(input.size(), input_stream.ParsedBytes()); |
240 } | 237 } |
241 | 238 |
242 // Decode with incomplete huffman encoding. | 239 // Decode with incomplete huffman encoding. |
243 TEST_P(HpackDecoderTest, DecodeNextNameLiteralWithIncompleteHuffmanEncoding) { | 240 TEST_P(HpackDecoderTest, DecodeNextNameLiteralWithIncompleteHuffmanEncoding) { |
244 // CHECK(huffman_table_.Initialize(kHpackHuffmanCode, | 241 // CHECK(huffman_table_.Initialize(kHpackHuffmanCode, |
245 // arraysize(kHpackHuffmanCode))); | 242 // arraysize(kHpackHuffmanCode))); |
246 // Put two copies of the same huffman encoding into input. | 243 // Put two copies of the same huffman encoding into input. |
247 string input = a2b_hex("008825a849e95ba97d7f008825a849e95ba97d7f"); | 244 string input = a2b_hex("008825a849e95ba97d7f008825a849e95ba97d7f"); |
248 input.resize(input.size() - 1); // Remove the last byte. | 245 input.resize(input.size() - 1); // Remove the last byte. |
249 HpackInputStream input_stream(kLiteralBound, input); | 246 HpackInputStream input_stream(input); |
250 | 247 |
251 StringPiece string_piece; | 248 StringPiece string_piece; |
252 EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); | 249 EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); |
253 EXPECT_FALSE(input_stream.NeedMoreData()); | 250 EXPECT_FALSE(input_stream.NeedMoreData()); |
254 input_stream.MarkCurrentPosition(); | 251 input_stream.MarkCurrentPosition(); |
255 EXPECT_EQ(10u, input_stream.ParsedBytes()); | 252 EXPECT_EQ(10u, input_stream.ParsedBytes()); |
256 | 253 |
257 EXPECT_FALSE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); | 254 EXPECT_FALSE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); |
258 EXPECT_TRUE(input_stream.NeedMoreData()); | 255 EXPECT_TRUE(input_stream.NeedMoreData()); |
259 input_stream.MarkCurrentPosition(); | 256 input_stream.MarkCurrentPosition(); |
260 EXPECT_EQ(12u, input_stream.ParsedBytes()); | 257 EXPECT_EQ(12u, input_stream.ParsedBytes()); |
261 } | 258 } |
262 | 259 |
263 // Decoding an encoded name with a valid index should work. | 260 // Decoding an encoded name with a valid index should work. |
264 TEST_P(HpackDecoderTest, DecodeNextNameIndexed) { | 261 TEST_P(HpackDecoderTest, DecodeNextNameIndexed) { |
265 HpackInputStream input_stream(kLiteralBound, "\x01"); | 262 HpackInputStream input_stream("\x01"); |
266 | 263 |
267 StringPiece string_piece; | 264 StringPiece string_piece; |
268 EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); | 265 EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); |
269 EXPECT_EQ(":authority", string_piece); | 266 EXPECT_EQ(":authority", string_piece); |
270 EXPECT_FALSE(input_stream.HasMoreData()); | 267 EXPECT_FALSE(input_stream.HasMoreData()); |
271 EXPECT_FALSE(input_stream.NeedMoreData()); | 268 EXPECT_FALSE(input_stream.NeedMoreData()); |
272 input_stream.MarkCurrentPosition(); | 269 input_stream.MarkCurrentPosition(); |
273 EXPECT_EQ(1u, input_stream.ParsedBytes()); | 270 EXPECT_EQ(1u, input_stream.ParsedBytes()); |
274 } | 271 } |
275 | 272 |
276 // Decoding an encoded name with an invalid index should fail. | 273 // Decoding an encoded name with an invalid index should fail. |
277 TEST_P(HpackDecoderTest, DecodeNextNameInvalidIndex) { | 274 TEST_P(HpackDecoderTest, DecodeNextNameInvalidIndex) { |
278 // One more than the number of static table entries. | 275 // One more than the number of static table entries. |
279 HpackInputStream input_stream(kLiteralBound, "\x3e"); | 276 HpackInputStream input_stream("\x3e"); |
280 | 277 |
281 StringPiece string_piece; | 278 StringPiece string_piece; |
282 EXPECT_FALSE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); | 279 EXPECT_FALSE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); |
283 EXPECT_FALSE(input_stream.NeedMoreData()); | 280 EXPECT_FALSE(input_stream.NeedMoreData()); |
284 input_stream.MarkCurrentPosition(); | 281 input_stream.MarkCurrentPosition(); |
285 EXPECT_EQ(1u, input_stream.ParsedBytes()); | 282 EXPECT_EQ(1u, input_stream.ParsedBytes()); |
286 } | 283 } |
287 | 284 |
288 // Decoding indexed static table field should work. | 285 // Decoding indexed static table field should work. |
289 TEST_P(HpackDecoderTest, IndexedHeaderStatic) { | 286 TEST_P(HpackDecoderTest, IndexedHeaderStatic) { |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 TEST_P(HpackDecoderTest, LiteralHeaderNeverIndexedInvalidNameIndex) { | 514 TEST_P(HpackDecoderTest, LiteralHeaderNeverIndexedInvalidNameIndex) { |
518 // Name is the last static index. Works. | 515 // Name is the last static index. Works. |
519 EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x1f\x2e\x03ooo"))); | 516 EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x1f\x2e\x03ooo"))); |
520 // Name is one beyond the last static index. Fails. | 517 // Name is one beyond the last static index. Fails. |
521 EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x1f\x2f\x03ooo"))); | 518 EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x1f\x2f\x03ooo"))); |
522 } | 519 } |
523 | 520 |
524 // Decode with incomplete string literal. | 521 // Decode with incomplete string literal. |
525 TEST_P(HpackDecoderTest, StringLiteralIncomplete) { | 522 TEST_P(HpackDecoderTest, StringLiteralIncomplete) { |
526 const char input[] = "\x0c/sample/path\x06:path2\x0e/sample/path/"; | 523 const char input[] = "\x0c/sample/path\x06:path2\x0e/sample/path/"; |
527 HpackInputStream input_stream(kLiteralBound, input); | 524 HpackInputStream input_stream(input); |
528 StringPiece str; | 525 StringPiece str; |
529 EXPECT_TRUE( | 526 EXPECT_TRUE( |
530 decoder_peer_.DecodeNextStringLiteral(&input_stream, false, &str)); | 527 decoder_peer_.DecodeNextStringLiteral(&input_stream, false, &str)); |
531 EXPECT_FALSE(input_stream.NeedMoreData()); | 528 EXPECT_FALSE(input_stream.NeedMoreData()); |
532 input_stream.MarkCurrentPosition(); | 529 input_stream.MarkCurrentPosition(); |
533 EXPECT_EQ(13u, input_stream.ParsedBytes()); | 530 EXPECT_EQ(13u, input_stream.ParsedBytes()); |
534 | 531 |
535 EXPECT_TRUE( | 532 EXPECT_TRUE( |
536 decoder_peer_.DecodeNextStringLiteral(&input_stream, false, &str)); | 533 decoder_peer_.DecodeNextStringLiteral(&input_stream, false, &str)); |
537 EXPECT_FALSE(input_stream.NeedMoreData()); | 534 EXPECT_FALSE(input_stream.NeedMoreData()); |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;" | 846 "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;" |
850 " max-age=3600; version=1"); | 847 " max-age=3600; version=1"); |
851 expectEntry(63, 52, "content-encoding", "gzip"); | 848 expectEntry(63, 52, "content-encoding", "gzip"); |
852 expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:22 GMT"); | 849 expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:22 GMT"); |
853 EXPECT_EQ(215u, decoder_peer_.header_table()->size()); | 850 EXPECT_EQ(215u, decoder_peer_.header_table()->size()); |
854 } | 851 } |
855 | 852 |
856 } // namespace | 853 } // namespace |
857 } // namespace test | 854 } // namespace test |
858 } // namespace net | 855 } // namespace net |
OLD | NEW |