diff options
author | jgraettinger@chromium.org <jgraettinger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-06 01:32:20 +0000 |
---|---|---|
committer | jgraettinger@chromium.org <jgraettinger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-06 01:32:20 +0000 |
commit | fd5cc39ee5bd39f691eb82d00e1c50312e88b151 (patch) | |
tree | 2416eabe70e68dc09b134e79bf53800ec713a2bf | |
parent | 248533d5e55935461905f771fcd1e49b1f21aba6 (diff) | |
download | chromium_src-fd5cc39ee5bd39f691eb82d00e1c50312e88b151.zip chromium_src-fd5cc39ee5bd39f691eb82d00e1c50312e88b151.tar.gz chromium_src-fd5cc39ee5bd39f691eb82d00e1c50312e88b151.tar.bz2 |
Implement decoding of literal headers with incremental indexing for HPACK
This lands server change 60592123 by akalin.
BUG=339578
Review URL: https://codereview.chromium.org/154293002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249196 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/spdy/hpack_constants.h | 4 | ||||
-rw-r--r-- | net/spdy/hpack_decoder.cc | 24 | ||||
-rw-r--r-- | net/spdy/hpack_decoder_test.cc | 49 |
3 files changed, 70 insertions, 7 deletions
diff --git a/net/spdy/hpack_constants.h b/net/spdy/hpack_constants.h index e3da0f1..79aa06b 100644 --- a/net/spdy/hpack_constants.h +++ b/net/spdy/hpack_constants.h @@ -31,6 +31,10 @@ const HpackPrefix kIndexedOpcode = { 0x1, 1 }; // 4.3.1). const HpackPrefix kLiteralNoIndexOpcode = { 0x01, 2 }; +// The opcode for a literal header field with incremental indexing +// (from 4.3.2). +const HpackPrefix kLiteralIncrementalIndexOpcode = { 0x00, 2 }; + } // namespace net #endif // NET_SPDY_HPACK_CONSTANTS_H_ diff --git a/net/spdy/hpack_decoder.cc b/net/spdy/hpack_decoder.cc index e85e6ff..7826ddd 100644 --- a/net/spdy/hpack_decoder.cc +++ b/net/spdy/hpack_decoder.cc @@ -92,6 +92,30 @@ bool HpackDecoder::ProcessNextHeaderRepresentation( return true; } + // Implements 4.3.2. Literal Header Field with Incremental Indexing. + if (input_stream->MatchPrefixAndConsume(kLiteralIncrementalIndexOpcode)) { + StringPiece name; + if (!DecodeNextName(input_stream, &name)) + return false; + + StringPiece value; + if (!DecodeNextValue(input_stream, &value)) + return false; + + header_list->push_back( + HpackHeaderPair(name.as_string(), value.as_string())); + + uint32 new_index = 0; + std::vector<uint32> removed_referenced_indices; + context_.ProcessLiteralHeaderWithIncrementalIndexing( + name, value, &new_index, &removed_referenced_indices); + + if (new_index > 0) + context_.AddTouchesAt(new_index, 0); + + return true; + } + return false; } diff --git a/net/spdy/hpack_decoder_test.cc b/net/spdy/hpack_decoder_test.cc index a444bed..5fa7377 100644 --- a/net/spdy/hpack_decoder_test.cc +++ b/net/spdy/hpack_decoder_test.cc @@ -117,10 +117,9 @@ TEST(HpackDecoderTest, LiteralHeaderNoIndexing) { HpackHeaderPairVector header_list; // First header with indexed name, second header with string literal // name. - EXPECT_TRUE(decoder.DecodeHeaderSet( - "\x44\x0c/sample/path\x40\x06:path2\x0e/sample/path/2", - &header_list)); - std::map<string, string> header_set(header_list.begin(), header_list.end()); + std::map<string, string> header_set = + DecodeUniqueHeaderSet( + &decoder, "\x44\x0c/sample/path\x40\x06:path2\x0e/sample/path/2"); std::map<string, string> expected_header_set; expected_header_set[":path"] = "/sample/path"; @@ -128,6 +127,45 @@ TEST(HpackDecoderTest, LiteralHeaderNoIndexing) { EXPECT_EQ(expected_header_set, header_set); } +// Decoding two valid encoded literal headers with incremental +// indexing and string literal names should work and add the headers +// to the reference set. +TEST(HpackDecoderTest, LiteralHeaderIncrementalIndexing) { + HpackDecoder decoder(kuint32max); + std::map<string, string> header_set = DecodeUniqueHeaderSet( + &decoder, + StringPiece("\x04\x0c/sample/path\x00\x06:path2\x0e/sample/path/2", 37)); + + std::map<string, string> expected_header_set; + expected_header_set[":path"] = "/sample/path"; + expected_header_set[":path2"] = "/sample/path/2"; + EXPECT_EQ(expected_header_set, header_set); + + // Decoding an empty string should just return the reference set. + std::map<string, string> header_set2 = DecodeUniqueHeaderSet(&decoder, ""); + EXPECT_EQ(expected_header_set, header_set2); +} + +// Decoding literal headers with invalid indices should fail +// gracefully. +TEST(HpackDecoderTest, LiteralHeaderInvalidIndices) { + HpackDecoder decoder(kuint32max); + + HpackHeaderPairVector header_list; + + // No indexing. + + // One more than the number of static table entries. + EXPECT_FALSE(decoder.DecodeHeaderSet(StringPiece("\x7d", 1), &header_list)); + EXPECT_FALSE(decoder.DecodeHeaderSet(StringPiece("\x40", 1), &header_list)); + + // Incremental indexing. + + // One more than the number of static table entries. + EXPECT_FALSE(decoder.DecodeHeaderSet(StringPiece("\x3d", 1), &header_list)); + EXPECT_FALSE(decoder.DecodeHeaderSet(StringPiece("\x00", 1), &header_list)); +} + // Round-tripping the header set from E.2.1 should work. TEST(HpackDecoderTest, BasicE21) { HpackEncoder encoder(kuint32max); @@ -149,9 +187,6 @@ TEST(HpackDecoderTest, BasicE21) { EXPECT_EQ(expected_header_set, header_set); } -// TODO(akalin): Add test to exercise emission of the reference set -// once we can decode opcodes that add to the reference set. - } // namespace } // namespace net |