| 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 |