summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjgraettinger@chromium.org <jgraettinger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-06 01:32:20 +0000
committerjgraettinger@chromium.org <jgraettinger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-06 01:32:20 +0000
commitfd5cc39ee5bd39f691eb82d00e1c50312e88b151 (patch)
tree2416eabe70e68dc09b134e79bf53800ec713a2bf
parent248533d5e55935461905f771fcd1e49b1f21aba6 (diff)
downloadchromium_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.h4
-rw-r--r--net/spdy/hpack_decoder.cc24
-rw-r--r--net/spdy/hpack_decoder_test.cc49
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