Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / net / spdy / hpack_decoder_test.cc
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
3 // found in the LICENSE file.
4
5 #include "net/spdy/hpack_decoder.h"
6
7 #include <map>
8 #include <string>
9
10 #include "base/basictypes.h"
11 #include "base/strings/string_piece.h"
12 #include "net/spdy/hpack_encoder.h"
13 #include "net/spdy/hpack_input_stream.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace net {
17
18 namespace {
19
20 using base::StringPiece;
21 using std::string;
22
23 // Decoding an encoded name with a valid string literal should work.
24 TEST(HpackDecoderTest, DecodeNextNameLiteral) {
25   HpackDecoder decoder(kuint32max);
26   HpackInputStream input_stream(kuint32max, StringPiece("\x00\x04name", 6));
27
28   StringPiece string_piece;
29   EXPECT_TRUE(decoder.DecodeNextNameForTest(&input_stream, &string_piece));
30   EXPECT_EQ("name", string_piece);
31   EXPECT_FALSE(input_stream.HasMoreData());
32 }
33
34 // Decoding an encoded name with a valid index should work.
35 TEST(HpackDecoderTest, DecodeNextNameIndexed) {
36   HpackDecoder decoder(kuint32max);
37   HpackInputStream input_stream(kuint32max, "\x01");
38
39   StringPiece string_piece;
40   EXPECT_TRUE(decoder.DecodeNextNameForTest(&input_stream, &string_piece));
41   EXPECT_EQ(":authority", string_piece);
42   EXPECT_FALSE(input_stream.HasMoreData());
43 }
44
45 // Decoding an encoded name with an invalid index should fail.
46 TEST(HpackDecoderTest, DecodeNextNameInvalidIndex) {
47   // One more than the number of static table entries.
48   HpackDecoder decoder(kuint32max);
49   HpackInputStream input_stream(kuint32max, "\x3d");
50
51   StringPiece string_piece;
52   EXPECT_FALSE(decoder.DecodeNextNameForTest(&input_stream, &string_piece));
53 }
54
55 // Utility function to decode a string into a header set, assuming
56 // that the emitted headers have unique names.
57 std::map<string, string> DecodeUniqueHeaderSet(
58     HpackDecoder* decoder, StringPiece str) {
59   HpackHeaderPairVector header_list;
60   EXPECT_TRUE(decoder->DecodeHeaderSet(str, &header_list));
61   std::map<string, string> header_set(
62       header_list.begin(), header_list.end());
63   // Make sure |header_list| has no duplicates.
64   EXPECT_EQ(header_set.size(), header_list.size());
65   return header_set;
66 }
67
68 // Decoding an indexed header should toggle the index's presence in
69 // the reference set, making a copy of static table entries if
70 // necessary. It should also emit the header if toggled on (and only
71 // as many times as it was toggled on).
72 TEST(HpackDecoderTest, IndexedHeaderBasic) {
73   HpackDecoder decoder(kuint32max);
74
75   // Toggle on static table entry #2 (and make a copy at index #1),
76   // then toggle on static table entry #5 (which is now #6 because of
77   // the copy of #2).
78   std::map<string, string> header_set1 =
79       DecodeUniqueHeaderSet(&decoder, "\x82\x86");
80   std::map<string, string> expected_header_set1;
81   expected_header_set1[":method"] = "GET";
82   expected_header_set1[":path"] = "/index.html";
83   EXPECT_EQ(expected_header_set1, header_set1);
84
85   std::map<string, string> expected_header_set2;
86   expected_header_set2[":path"] = "/index.html";
87   // Toggle off the copy of static table entry #5.
88   std::map<string, string> header_set2 =
89       DecodeUniqueHeaderSet(&decoder, "\x82");
90   EXPECT_EQ(expected_header_set2, header_set2);
91 }
92
93 // Decoding an indexed header with index 0 should clear the reference
94 // set.
95 TEST(HpackDecoderTest, IndexedHeaderZero) {
96   HpackDecoder decoder(kuint32max);
97
98   // Toggle on a couple of headers.
99   std::map<string, string> header_set1 =
100       DecodeUniqueHeaderSet(&decoder, "\x82\x86");
101   std::map<string, string> expected_header_set1;
102   expected_header_set1[":method"] = "GET";
103   expected_header_set1[":path"] = "/index.html";
104   EXPECT_EQ(expected_header_set1, header_set1);
105
106   // Toggle index 0 to clear the reference set.
107   std::map<string, string> header_set2 =
108       DecodeUniqueHeaderSet(&decoder, "\x80");
109   std::map<string, string> expected_header_set2;
110   EXPECT_EQ(expected_header_set2, header_set2);
111 }
112
113 // Decoding two valid encoded literal headers with no indexing should
114 // work.
115 TEST(HpackDecoderTest, LiteralHeaderNoIndexing) {
116   HpackDecoder decoder(kuint32max);
117   HpackHeaderPairVector header_list;
118   // First header with indexed name, second header with string literal
119   // name.
120   std::map<string, string> header_set =
121       DecodeUniqueHeaderSet(
122           &decoder, "\x44\x0c/sample/path\x40\x06:path2\x0e/sample/path/2");
123
124   std::map<string, string> expected_header_set;
125   expected_header_set[":path"] = "/sample/path";
126   expected_header_set[":path2"] = "/sample/path/2";
127   EXPECT_EQ(expected_header_set, header_set);
128 }
129
130 // Decoding two valid encoded literal headers with incremental
131 // indexing and string literal names should work and add the headers
132 // to the reference set.
133 TEST(HpackDecoderTest, LiteralHeaderIncrementalIndexing) {
134   HpackDecoder decoder(kuint32max);
135   std::map<string, string> header_set = DecodeUniqueHeaderSet(
136       &decoder,
137       StringPiece("\x04\x0c/sample/path\x00\x06:path2\x0e/sample/path/2", 37));
138
139   std::map<string, string> expected_header_set;
140   expected_header_set[":path"] = "/sample/path";
141   expected_header_set[":path2"] = "/sample/path/2";
142   EXPECT_EQ(expected_header_set, header_set);
143
144   // Decoding an empty string should just return the reference set.
145   std::map<string, string> header_set2 = DecodeUniqueHeaderSet(&decoder, "");
146   EXPECT_EQ(expected_header_set, header_set2);
147 }
148
149 // Decoding literal headers with invalid indices should fail
150 // gracefully.
151 TEST(HpackDecoderTest, LiteralHeaderInvalidIndices) {
152   HpackDecoder decoder(kuint32max);
153
154   HpackHeaderPairVector header_list;
155
156   // No indexing.
157
158   // One more than the number of static table entries.
159   EXPECT_FALSE(decoder.DecodeHeaderSet(StringPiece("\x7d", 1), &header_list));
160   EXPECT_FALSE(decoder.DecodeHeaderSet(StringPiece("\x40", 1), &header_list));
161
162   // Incremental indexing.
163
164   // One more than the number of static table entries.
165   EXPECT_FALSE(decoder.DecodeHeaderSet(StringPiece("\x3d", 1), &header_list));
166   EXPECT_FALSE(decoder.DecodeHeaderSet(StringPiece("\x00", 1), &header_list));
167 }
168
169 // Round-tripping the header set from E.2.1 should work.
170 TEST(HpackDecoderTest, BasicE21) {
171   HpackEncoder encoder(kuint32max);
172
173   std::map<string, string> expected_header_set;
174   expected_header_set[":method"] = "GET";
175   expected_header_set[":scheme"] = "http";
176   expected_header_set[":path"] = "/";
177   expected_header_set[":authority"] = "www.example.com";
178
179   string encoded_header_set;
180   EXPECT_TRUE(encoder.EncodeHeaderSet(
181       expected_header_set, &encoded_header_set));
182
183   HpackDecoder decoder(kuint32max);
184   HpackHeaderPairVector header_list;
185   EXPECT_TRUE(decoder.DecodeHeaderSet(encoded_header_set, &header_list));
186   std::map<string, string> header_set(header_list.begin(), header_list.end());
187   EXPECT_EQ(expected_header_set, header_set);
188 }
189
190 }  // namespace
191
192 }  // namespace net