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

Side by Side Diff: net/spdy/hpack/hpack_huffman_table_test.cc

Issue 1568423002: Implement better HPACK Huffman code decoder. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Do not use binary literals. Created 4 years, 11 months 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
« no previous file with comments | « net/spdy/hpack/hpack_huffman_table.cc ('k') | net/spdy/hpack/hpack_input_stream.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_huffman_table.h" 5 #include "net/spdy/hpack/hpack_huffman_table.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <bitset> 9 #include <bitset>
10 #include <limits> 10 #include <limits>
11 #include <string> 11 #include <string>
12 #include <utility>
12 13
13 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h"
14 #include "net/spdy/hpack/hpack_constants.h" 16 #include "net/spdy/hpack/hpack_constants.h"
17 #include "net/spdy/hpack/hpack_huffman_decoder.h"
15 #include "net/spdy/hpack/hpack_input_stream.h" 18 #include "net/spdy/hpack/hpack_input_stream.h"
16 #include "net/spdy/hpack/hpack_output_stream.h" 19 #include "net/spdy/hpack/hpack_output_stream.h"
17 #include "net/spdy/spdy_test_utils.h" 20 #include "net/spdy/spdy_test_utils.h"
18 #include "testing/gmock/include/gmock/gmock.h" 21 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
20 23
21 using base::StringPiece; 24 using base::StringPiece;
22 using std::string; 25 using std::string;
23 using testing::ElementsAreArray; 26 using testing::ElementsAreArray;
24 using testing::Pointwise; 27 using testing::Pointwise;
(...skipping 27 matching lines...) Expand all
52 table_.decode_entries_.begin() + decode_table.entries_offset; 55 table_.decode_entries_.begin() + decode_table.entries_offset;
53 return std::vector<DecodeEntry>(begin, begin + decode_table.size()); 56 return std::vector<DecodeEntry>(begin, begin + decode_table.size());
54 } 57 }
55 58
56 private: 59 private:
57 const HpackHuffmanTable& table_; 60 const HpackHuffmanTable& table_;
58 }; 61 };
59 62
60 namespace { 63 namespace {
61 64
62 class HpackHuffmanTableTest : public ::testing::Test { 65 // Tests of the ability to decode some canonical Huffman code,
66 // not just the one defined in the RFC 7541.
67 class GenericHuffmanTableTest : public ::testing::TestWithParam<bool> {
63 protected: 68 protected:
64 HpackHuffmanTableTest() : table_(), peer_(table_) {} 69 GenericHuffmanTableTest() : table_(), peer_(table_) {}
65 70
66 string EncodeString(StringPiece input) { 71 string EncodeString(StringPiece input) {
67 string result; 72 string result;
68 HpackOutputStream output_stream; 73 HpackOutputStream output_stream;
69 table_.EncodeString(input, &output_stream); 74 table_.EncodeString(input, &output_stream);
70 75
71 output_stream.TakeString(&result); 76 output_stream.TakeString(&result);
72 // Verify EncodedSize() agrees with EncodeString(). 77 // Verify EncodedSize() agrees with EncodeString().
73 EXPECT_EQ(result.size(), table_.EncodedSize(input)); 78 EXPECT_EQ(result.size(), table_.EncodedSize(input));
74 return result; 79 return result;
(...skipping 10 matching lines...) Expand all
85 lhs.length == rhs.length && lhs.symbol_id == rhs.symbol_id; 90 lhs.length == rhs.length && lhs.symbol_id == rhs.symbol_id;
86 } 91 }
87 92
88 uint32_t bits32(const string& bitstring) { 93 uint32_t bits32(const string& bitstring) {
89 return std::bitset<32>(bitstring).to_ulong(); 94 return std::bitset<32>(bitstring).to_ulong();
90 } 95 }
91 char bits8(const string& bitstring) { 96 char bits8(const string& bitstring) {
92 return static_cast<char>(std::bitset<8>(bitstring).to_ulong()); 97 return static_cast<char>(std::bitset<8>(bitstring).to_ulong());
93 } 98 }
94 99
95 TEST_F(HpackHuffmanTableTest, InitializeHpackCode) { 100 TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) {
96 std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
97 EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
98 EXPECT_TRUE(table_.IsInitialized());
99 EXPECT_EQ(peer_.pad_bits(), bits8("11111111")); // First 8 bits of EOS.
100 }
101
102 TEST_F(HpackHuffmanTableTest, InitializeEdgeCases) {
103 { 101 {
104 // Verify eight symbols can be encoded with 3 bits per symbol. 102 // Verify eight symbols can be encoded with 3 bits per symbol.
105 HpackHuffmanSymbol code[] = { 103 HpackHuffmanSymbol code[] = {
106 {bits32("00000000000000000000000000000000"), 3, 0}, 104 {bits32("00000000000000000000000000000000"), 3, 0},
107 {bits32("00100000000000000000000000000000"), 3, 1}, 105 {bits32("00100000000000000000000000000000"), 3, 1},
108 {bits32("01000000000000000000000000000000"), 3, 2}, 106 {bits32("01000000000000000000000000000000"), 3, 2},
109 {bits32("01100000000000000000000000000000"), 3, 3}, 107 {bits32("01100000000000000000000000000000"), 3, 3},
110 {bits32("10000000000000000000000000000000"), 3, 4}, 108 {bits32("10000000000000000000000000000000"), 3, 4},
111 {bits32("10100000000000000000000000000000"), 3, 5}, 109 {bits32("10100000000000000000000000000000"), 3, 5},
112 {bits32("11000000000000000000000000000000"), 3, 6}, 110 {bits32("11000000000000000000000000000000"), 3, 6},
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 HpackHuffmanSymbol code[] = { 186 HpackHuffmanSymbol code[] = {
189 {bits32("00000000000000000000000000000000"), 1, 0}, 187 {bits32("00000000000000000000000000000000"), 1, 0},
190 {bits32("10000000000000000000000000000000"), 2, 1}, 188 {bits32("10000000000000000000000000000000"), 2, 1},
191 {bits32("11000000000000000000000000000000"), 3, 2}, 189 {bits32("11000000000000000000000000000000"), 3, 2},
192 {bits32("11100000000000000000000000000000"), 7, 3}}; 190 {bits32("11100000000000000000000000000000"), 7, 3}};
193 HpackHuffmanTable table; 191 HpackHuffmanTable table;
194 EXPECT_FALSE(table.Initialize(code, arraysize(code))); 192 EXPECT_FALSE(table.Initialize(code, arraysize(code)));
195 } 193 }
196 } 194 }
197 195
198 TEST_F(HpackHuffmanTableTest, ValidateInternalsWithSmallCode) { 196 TEST_F(GenericHuffmanTableTest, ValidateInternalsWithSmallCode) {
199 HpackHuffmanSymbol code[] = { 197 HpackHuffmanSymbol code[] = {
200 {bits32("01100000000000000000000000000000"), 4, 0}, // 3rd. 198 {bits32("01100000000000000000000000000000"), 4, 0}, // 3rd.
201 {bits32("01110000000000000000000000000000"), 4, 1}, // 4th. 199 {bits32("01110000000000000000000000000000"), 4, 1}, // 4th.
202 {bits32("00000000000000000000000000000000"), 2, 2}, // 1st assigned code. 200 {bits32("00000000000000000000000000000000"), 2, 2}, // 1st assigned code.
203 {bits32("01000000000000000000000000000000"), 3, 3}, // 2nd. 201 {bits32("01000000000000000000000000000000"), 3, 3}, // 2nd.
204 {bits32("10000000000000000000000000000000"), 5, 4}, // 5th. 202 {bits32("10000000000000000000000000000000"), 5, 4}, // 5th.
205 {bits32("10001000000000000000000000000000"), 5, 5}, // 6th. 203 {bits32("10001000000000000000000000000000"), 5, 5}, // 6th.
206 {bits32("10011000000000000000000000000000"), 8, 6}, // 8th. 204 {bits32("10011000000000000000000000000000"), 8, 6}, // 8th.
207 {bits32("10010000000000000000000000000000"), 5, 7}}; // 7th. 205 {bits32("10010000000000000000000000000000"), 5, 7}}; // 7th.
208 EXPECT_TRUE(table_.Initialize(code, arraysize(code))); 206 EXPECT_TRUE(table_.Initialize(code, arraysize(code)));
(...skipping 28 matching lines...) Expand all
237 char expect_storage[] = {bits8("00010001"), bits8("00101000"), 235 char expect_storage[] = {bits8("00010001"), bits8("00101000"),
238 bits8("01001100")}; 236 bits8("01001100")};
239 StringPiece expect(expect_storage, arraysize(expect_storage)); 237 StringPiece expect(expect_storage, arraysize(expect_storage));
240 238
241 string buffer_in = EncodeString(input); 239 string buffer_in = EncodeString(input);
242 EXPECT_EQ(expect, buffer_in); 240 EXPECT_EQ(expect, buffer_in);
243 241
244 string buffer_out; 242 string buffer_out;
245 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), 243 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
246 buffer_in); 244 buffer_in);
247 EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out)); 245 EXPECT_TRUE(
246 table_.GenericDecodeString(&input_stream, input.size(), &buffer_out));
248 EXPECT_EQ(buffer_out, input); 247 EXPECT_EQ(buffer_out, input);
249 } 248 }
250 249
251 TEST_F(HpackHuffmanTableTest, ValidateMultiLevelDecodeTables) { 250 TEST_F(GenericHuffmanTableTest, ValidateMultiLevelDecodeTables) {
252 HpackHuffmanSymbol code[] = { 251 HpackHuffmanSymbol code[] = {
253 {bits32("00000000000000000000000000000000"), 6, 0}, 252 {bits32("00000000000000000000000000000000"), 6, 0},
254 {bits32("00000100000000000000000000000000"), 6, 1}, 253 {bits32("00000100000000000000000000000000"), 6, 1},
255 {bits32("00001000000000000000000000000000"), 11, 2}, 254 {bits32("00001000000000000000000000000000"), 11, 2},
256 {bits32("00001000001000000000000000000000"), 11, 3}, 255 {bits32("00001000001000000000000000000000"), 11, 3},
257 {bits32("00001000010000000000000000000000"), 12, 4}, 256 {bits32("00001000010000000000000000000000"), 12, 4},
258 }; 257 };
259 EXPECT_TRUE(table_.Initialize(code, arraysize(code))); 258 EXPECT_TRUE(table_.Initialize(code, arraysize(code)));
260 259
261 EXPECT_EQ(2u, peer_.decode_tables().size()); 260 EXPECT_EQ(2u, peer_.decode_tables().size());
(...skipping 19 matching lines...) Expand all
281 280
282 const DecodeTable& decode_table = peer_.decode_tables()[1]; 281 const DecodeTable& decode_table = peer_.decode_tables()[1];
283 EXPECT_EQ(decode_table.prefix_length, 9); 282 EXPECT_EQ(decode_table.prefix_length, 9);
284 EXPECT_EQ(decode_table.indexed_length, 3); 283 EXPECT_EQ(decode_table.indexed_length, 3);
285 EXPECT_THAT(peer_.decode_entries(decode_table), 284 EXPECT_THAT(peer_.decode_entries(decode_table),
286 Pointwise(DecodeEntryEq(), expected)); 285 Pointwise(DecodeEntryEq(), expected));
287 } 286 }
288 EXPECT_EQ(bits8("00001000"), peer_.pad_bits()); 287 EXPECT_EQ(bits8("00001000"), peer_.pad_bits());
289 } 288 }
290 289
291 TEST_F(HpackHuffmanTableTest, DecodeWithBadInput) { 290 TEST_F(GenericHuffmanTableTest, DecodeWithBadInput) {
292 HpackHuffmanSymbol code[] = { 291 HpackHuffmanSymbol code[] = {
293 {bits32("01100000000000000000000000000000"), 4, 0}, 292 {bits32("01100000000000000000000000000000"), 4, 0},
294 {bits32("01110000000000000000000000000000"), 4, 1}, 293 {bits32("01110000000000000000000000000000"), 4, 1},
295 {bits32("00000000000000000000000000000000"), 2, 2}, 294 {bits32("00000000000000000000000000000000"), 2, 2},
296 {bits32("01000000000000000000000000000000"), 3, 3}, 295 {bits32("01000000000000000000000000000000"), 3, 3},
297 {bits32("10000000000000000000000000000000"), 5, 4}, 296 {bits32("10000000000000000000000000000000"), 5, 4},
298 {bits32("10001000000000000000000000000000"), 5, 5}, 297 {bits32("10001000000000000000000000000000"), 5, 5},
299 {bits32("10011000000000000000000000000000"), 6, 6}, 298 {bits32("10011000000000000000000000000000"), 6, 6},
300 {bits32("10010000000000000000000000000000"), 5, 7}, 299 {bits32("10010000000000000000000000000000"), 5, 7},
301 {bits32("10011100000000000000000000000000"), 16, 8}}; 300 {bits32("10011100000000000000000000000000"), 16, 8}};
302 EXPECT_TRUE(table_.Initialize(code, arraysize(code))); 301 EXPECT_TRUE(table_.Initialize(code, arraysize(code)));
303 302
304 string buffer; 303 string buffer;
305 const size_t capacity = 4; 304 const size_t capacity = 4;
306 { 305 {
307 // This example works: (2) 00 (3) 010 (2) 00 (6) 100110 (pad) 100. 306 // This example works: (2) 00 (3) 010 (2) 00 (6) 100110 (pad) 100.
308 char input_storage[] = {bits8("00010001"), bits8("00110100")}; 307 char input_storage[] = {bits8("00010001"), bits8("00110100")};
309 StringPiece input(input_storage, arraysize(input_storage)); 308 StringPiece input(input_storage, arraysize(input_storage));
310 309
311 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input); 310 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
312 EXPECT_TRUE(table_.DecodeString(&input_stream, capacity, &buffer)); 311 EXPECT_TRUE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
313 EXPECT_EQ(buffer, "\x02\x03\x02\x06"); 312 EXPECT_EQ(buffer, "\x02\x03\x02\x06");
314 } 313 }
315 { 314 {
316 // Expect to fail on an invalid code prefix. 315 // Expect to fail on an invalid code prefix.
317 // (2) 00 (3) 010 (2) 00 (too-large) 101000 (pad) 100. 316 // (2) 00 (3) 010 (2) 00 (too-large) 101000 (pad) 100.
318 char input_storage[] = {bits8("00010001"), bits8("01000111")}; 317 char input_storage[] = {bits8("00010001"), bits8("01000111")};
319 StringPiece input(input_storage, arraysize(input_storage)); 318 StringPiece input(input_storage, arraysize(input_storage));
320 319
321 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input); 320 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
322 EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer)); 321 EXPECT_FALSE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
323 EXPECT_EQ(buffer, "\x02\x03\x02"); 322 EXPECT_EQ(buffer, "\x02\x03\x02");
324 } 323 }
325 { 324 {
326 // Repeat the shortest 0b00 code to overflow |buffer|. Expect to fail. 325 // Repeat the shortest 0b00 code to overflow |buffer|. Expect to fail.
327 std::vector<char> input_storage(1 + capacity / 4, '\0'); 326 std::vector<char> input_storage(1 + capacity / 4, '\0');
328 StringPiece input(&input_storage[0], input_storage.size()); 327 StringPiece input(&input_storage[0], input_storage.size());
329 328
330 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input); 329 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
331 EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer)); 330 EXPECT_FALSE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
332 331
333 std::vector<char> expected(capacity, '\x02'); 332 std::vector<char> expected(capacity, '\x02');
334 EXPECT_THAT(buffer, ElementsAreArray(expected)); 333 EXPECT_THAT(buffer, ElementsAreArray(expected));
335 EXPECT_EQ(capacity, buffer.size()); 334 EXPECT_EQ(capacity, buffer.size());
336 } 335 }
337 { 336 {
338 // Expect to fail if more than a byte of unconsumed input remains. 337 // Expect to fail if more than a byte of unconsumed input remains.
339 // (6) 100110 (8 truncated) 1001110000 338 // (6) 100110 (8 truncated) 1001110000
340 char input_storage[] = {bits8("10011010"), bits8("01110000")}; 339 char input_storage[] = {bits8("10011010"), bits8("01110000")};
341 StringPiece input(input_storage, arraysize(input_storage)); 340 StringPiece input(input_storage, arraysize(input_storage));
342 341
343 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input); 342 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
344 EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer)); 343 EXPECT_FALSE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
345 EXPECT_EQ(buffer, "\x06"); 344 EXPECT_EQ(buffer, "\x06");
346 } 345 }
347 } 346 }
348 347
348 // Tests of the ability to decode the HPACK Huffman Code, defined in:
349 // https://httpwg.github.io/specs/rfc7541.html#huffman.code
350 class HpackHuffmanTableTest : public GenericHuffmanTableTest {
351 protected:
352 void SetUp() override {
353 std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
354 EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
355 EXPECT_TRUE(table_.IsInitialized());
356 }
357
358 void DecodeStringTwice(const string& encoded,
359 size_t out_capacity,
360 string* out) {
361 // First decode with HpackHuffmanTable.
362 {
363 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
364 encoded);
365 EXPECT_TRUE(table_.GenericDecodeString(&input_stream, out_capacity, out));
366 }
367 // And decode again with the fixed decoder, confirming that the result is
368 // the same.
369 {
370 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
371 encoded);
372 string buf;
373 EXPECT_TRUE(
374 HpackHuffmanDecoder::DecodeString(&input_stream, out_capacity, &buf));
375 EXPECT_EQ(*out, buf);
376 }
377 }
378 };
379
380 TEST_F(HpackHuffmanTableTest, InitializeHpackCode) {
381 EXPECT_EQ(peer_.pad_bits(), '\xFF'); // First 8 bits of EOS.
382 }
383
349 TEST_F(HpackHuffmanTableTest, SpecRequestExamples) { 384 TEST_F(HpackHuffmanTableTest, SpecRequestExamples) {
350 std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
351 EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
352
353 string buffer; 385 string buffer;
354 string test_table[] = { 386 string test_table[] = {
355 a2b_hex("f1e3c2e5f23a6ba0ab90f4ff"), 387 a2b_hex("f1e3c2e5f23a6ba0ab90f4ff"),
356 "www.example.com", 388 "www.example.com",
357 a2b_hex("a8eb10649cbf"), 389 a2b_hex("a8eb10649cbf"),
358 "no-cache", 390 "no-cache",
359 a2b_hex("25a849e95ba97d7f"), 391 a2b_hex("25a849e95ba97d7f"),
360 "custom-key", 392 "custom-key",
361 a2b_hex("25a849e95bb8e8b4bf"), 393 a2b_hex("25a849e95bb8e8b4bf"),
362 "custom-value", 394 "custom-value",
363 }; 395 };
364 // Round-trip each test example. 396 // Round-trip each test example.
365 for (size_t i = 0; i != arraysize(test_table); i += 2) { 397 for (size_t i = 0; i != arraysize(test_table); i += 2) {
366 const string& encodedFixture(test_table[i]); 398 const string& encodedFixture(test_table[i]);
367 const string& decodedFixture(test_table[i + 1]); 399 const string& decodedFixture(test_table[i + 1]);
368 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), 400 DecodeStringTwice(encodedFixture, decodedFixture.size(), &buffer);
369 encodedFixture);
370
371 EXPECT_TRUE(
372 table_.DecodeString(&input_stream, decodedFixture.size(), &buffer));
373 EXPECT_EQ(decodedFixture, buffer); 401 EXPECT_EQ(decodedFixture, buffer);
374 buffer = EncodeString(decodedFixture); 402 buffer = EncodeString(decodedFixture);
375 EXPECT_EQ(encodedFixture, buffer); 403 EXPECT_EQ(encodedFixture, buffer);
376 } 404 }
377 } 405 }
378 406
379 TEST_F(HpackHuffmanTableTest, SpecResponseExamples) { 407 TEST_F(HpackHuffmanTableTest, SpecResponseExamples) {
380 std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
381 EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
382
383 string buffer; 408 string buffer;
384 string test_table[] = { 409 string test_table[] = {
385 a2b_hex("6402"), "302", a2b_hex("aec3771a4b"), "private", 410 a2b_hex("6402"), "302", a2b_hex("aec3771a4b"), "private",
386 a2b_hex("d07abe941054d444a8200595040b8166" 411 a2b_hex("d07abe941054d444a8200595040b8166"
387 "e082a62d1bff"), 412 "e082a62d1bff"),
388 "Mon, 21 Oct 2013 20:13:21 GMT", 413 "Mon, 21 Oct 2013 20:13:21 GMT",
389 a2b_hex("9d29ad171863c78f0b97c8e9ae82ae43" 414 a2b_hex("9d29ad171863c78f0b97c8e9ae82ae43"
390 "d3"), 415 "d3"),
391 "https://www.example.com", a2b_hex("94e7821dd7f2e6c7b335dfdfcd5b3960" 416 "https://www.example.com", a2b_hex("94e7821dd7f2e6c7b335dfdfcd5b3960"
392 "d5af27087f3672c1ab270fb5291f9587" 417 "d5af27087f3672c1ab270fb5291f9587"
393 "316065c003ed4ee5b1063d5007"), 418 "316065c003ed4ee5b1063d5007"),
394 "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", 419 "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
395 }; 420 };
396 // Round-trip each test example. 421 // Round-trip each test example.
397 for (size_t i = 0; i != arraysize(test_table); i += 2) { 422 for (size_t i = 0; i != arraysize(test_table); i += 2) {
398 const string& encodedFixture(test_table[i]); 423 const string& encodedFixture(test_table[i]);
399 const string& decodedFixture(test_table[i + 1]); 424 const string& decodedFixture(test_table[i + 1]);
400 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), 425 DecodeStringTwice(encodedFixture, decodedFixture.size(), &buffer);
401 encodedFixture);
402
403 EXPECT_TRUE(
404 table_.DecodeString(&input_stream, decodedFixture.size(), &buffer));
405 EXPECT_EQ(decodedFixture, buffer); 426 EXPECT_EQ(decodedFixture, buffer);
406 buffer = EncodeString(decodedFixture); 427 buffer = EncodeString(decodedFixture);
407 EXPECT_EQ(encodedFixture, buffer); 428 EXPECT_EQ(encodedFixture, buffer);
408 } 429 }
409 } 430 }
410 431
411 TEST_F(HpackHuffmanTableTest, RoundTripIndvidualSymbols) { 432 TEST_F(HpackHuffmanTableTest, RoundTripIndividualSymbols) {
412 std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
413 EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
414
415 for (size_t i = 0; i != 256; i++) { 433 for (size_t i = 0; i != 256; i++) {
416 char c = static_cast<char>(i); 434 char c = static_cast<char>(i);
417 char storage[3] = {c, c, c}; 435 char storage[3] = {c, c, c};
418 StringPiece input(storage, arraysize(storage)); 436 StringPiece input(storage, arraysize(storage));
419
420 string buffer_in = EncodeString(input); 437 string buffer_in = EncodeString(input);
421 string buffer_out; 438 string buffer_out;
422 439
423 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), 440 DecodeStringTwice(buffer_in, input.size(), &buffer_out);
424 buffer_in);
425 EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out));
426 EXPECT_EQ(input, buffer_out); 441 EXPECT_EQ(input, buffer_out);
427 } 442 }
428 } 443 }
429 444
430 TEST_F(HpackHuffmanTableTest, RoundTripSymbolSequence) { 445 TEST_F(HpackHuffmanTableTest, RoundTripSymbolSequence) {
431 std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
432 EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
433
434 char storage[512]; 446 char storage[512];
435 for (size_t i = 0; i != 256; i++) { 447 for (size_t i = 0; i != 256; i++) {
436 storage[i] = static_cast<char>(i); 448 storage[i] = static_cast<char>(i);
437 storage[511 - i] = static_cast<char>(i); 449 storage[511 - i] = static_cast<char>(i);
438 } 450 }
439 StringPiece input(storage, arraysize(storage)); 451 StringPiece input(storage, arraysize(storage));
440 452
441 string buffer_in = EncodeString(input); 453 string buffer_in = EncodeString(input);
442 string buffer_out; 454 string buffer_out;
443 455 DecodeStringTwice(buffer_in, input.size(), &buffer_out);
444 HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
445 buffer_in);
446 EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out));
447 EXPECT_EQ(input, buffer_out); 456 EXPECT_EQ(input, buffer_out);
448 } 457 }
449 458
450 TEST_F(HpackHuffmanTableTest, EncodedSizeAgreesWithEncodeString) { 459 TEST_F(HpackHuffmanTableTest, EncodedSizeAgreesWithEncodeString) {
451 std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
452 EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
453
454 string test_table[] = { 460 string test_table[] = {
455 "", 461 "",
456 "Mon, 21 Oct 2013 20:13:21 GMT", 462 "Mon, 21 Oct 2013 20:13:21 GMT",
457 "https://www.example.com", 463 "https://www.example.com",
458 "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", 464 "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
459 string(1, '\0'), 465 string(1, '\0'),
460 string("foo\0bar", 7), 466 string("foo\0bar", 7),
461 string(256, '\0'), 467 string(256, '\0'),
462 }; 468 };
463 for (size_t i = 0; i != 256; ++i) { 469 for (size_t i = 0; i != 256; ++i) {
464 // Expand last |test_table| entry to cover all codes. 470 // Expand last |test_table| entry to cover all codes.
465 test_table[arraysize(test_table) - 1][i] = static_cast<char>(i); 471 test_table[arraysize(test_table) - 1][i] = static_cast<char>(i);
466 } 472 }
467 473
468 HpackOutputStream output_stream; 474 HpackOutputStream output_stream;
469 string encoding; 475 string encoding;
470 for (size_t i = 0; i != arraysize(test_table); ++i) { 476 for (size_t i = 0; i != arraysize(test_table); ++i) {
471 table_.EncodeString(test_table[i], &output_stream); 477 table_.EncodeString(test_table[i], &output_stream);
472 output_stream.TakeString(&encoding); 478 output_stream.TakeString(&encoding);
473 EXPECT_EQ(encoding.size(), table_.EncodedSize(test_table[i])); 479 EXPECT_EQ(encoding.size(), table_.EncodedSize(test_table[i]));
474 } 480 }
475 } 481 }
476 482
477 } // namespace 483 } // namespace
478 484
479 } // namespace test 485 } // namespace test
480 486
481 } // namespace net 487 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/hpack/hpack_huffman_table.cc ('k') | net/spdy/hpack/hpack_input_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698