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

Side by Side Diff: net/http2/hpack/huffman/http2_hpack_huffman_decoder_test.cc

Issue 2554683003: Revert of Add new HTTP/2 and HPACK decoder in net/http2/. (Closed)
Patch Set: Created 4 years 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
OLDNEW
(Empty)
1 // Copyright 2016 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/http2/hpack/huffman/http2_hpack_huffman_decoder.h"
6
7 // Tests of HpackHuffmanDecoder and HuffmanBitBuffer.
8
9 #include <iostream>
10 #include <string>
11
12 #include "base/bind.h"
13 #include "base/bind_helpers.h"
14 #include "base/macros.h"
15 #include "base/strings/string_piece.h"
16 #include "net/http2/decoder/decode_buffer.h"
17 #include "net/http2/decoder/decode_status.h"
18 #include "net/http2/tools/failure.h"
19 #include "net/http2/tools/random_decoder_test.h"
20 #include "net/spdy/spdy_test_utils.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 using ::testing::AssertionResult;
24 using ::testing::AssertionSuccess;
25 using base::StringPiece;
26 using std::string;
27
28 namespace net {
29 namespace test {
30 namespace {
31
32 TEST(HuffmanBitBufferTest, Reset) {
33 HuffmanBitBuffer bb;
34 EXPECT_TRUE(bb.IsEmpty());
35 EXPECT_TRUE(bb.InputProperlyTerminated());
36 EXPECT_EQ(bb.count(), 0u);
37 EXPECT_EQ(bb.free_count(), 64u);
38 EXPECT_EQ(bb.value(), 0u);
39 }
40
41 TEST(HuffmanBitBufferTest, AppendBytesAligned) {
42 string s;
43 s.push_back('\x11');
44 s.push_back('\x22');
45 s.push_back('\x33');
46 StringPiece sp(s);
47
48 HuffmanBitBuffer bb;
49 sp.remove_prefix(bb.AppendBytes(sp));
50 EXPECT_TRUE(sp.empty());
51 EXPECT_FALSE(bb.IsEmpty()) << bb;
52 EXPECT_FALSE(bb.InputProperlyTerminated());
53 EXPECT_EQ(bb.count(), 24u) << bb;
54 EXPECT_EQ(bb.free_count(), 40u) << bb;
55 EXPECT_EQ(bb.value(), HuffmanAccumulator(0x112233) << 40) << bb;
56
57 s.clear();
58 s.push_back('\x44');
59 sp = s;
60
61 sp.remove_prefix(bb.AppendBytes(sp));
62 EXPECT_TRUE(sp.empty());
63 EXPECT_EQ(bb.count(), 32u) << bb;
64 EXPECT_EQ(bb.free_count(), 32u) << bb;
65 EXPECT_EQ(bb.value(), HuffmanAccumulator(0x11223344) << 32) << bb;
66
67 s.clear();
68 s.push_back('\x55');
69 s.push_back('\x66');
70 s.push_back('\x77');
71 s.push_back('\x88');
72 s.push_back('\x99');
73 sp = s;
74
75 sp.remove_prefix(bb.AppendBytes(sp));
76 EXPECT_EQ(sp.size(), 1u);
77 EXPECT_EQ('\x99', sp[0]);
78 EXPECT_EQ(bb.count(), 64u) << bb;
79 EXPECT_EQ(bb.free_count(), 0u) << bb;
80 EXPECT_EQ(bb.value(), HuffmanAccumulator(0x1122334455667788LL)) << bb;
81
82 sp.remove_prefix(bb.AppendBytes(sp));
83 EXPECT_EQ(sp.size(), 1u);
84 EXPECT_EQ('\x99', sp[0]);
85 EXPECT_EQ(bb.count(), 64u) << bb;
86 EXPECT_EQ(bb.free_count(), 0u) << bb;
87 EXPECT_EQ(bb.value(), HuffmanAccumulator(0x1122334455667788LL)) << bb;
88 }
89
90 TEST(HuffmanBitBufferTest, ConsumeBits) {
91 string s;
92 s.push_back('\x11');
93 s.push_back('\x22');
94 s.push_back('\x33');
95 StringPiece sp(s);
96
97 HuffmanBitBuffer bb;
98 sp.remove_prefix(bb.AppendBytes(sp));
99 EXPECT_TRUE(sp.empty());
100
101 bb.ConsumeBits(1);
102 EXPECT_EQ(bb.count(), 23u) << bb;
103 EXPECT_EQ(bb.free_count(), 41u) << bb;
104 EXPECT_EQ(bb.value(), HuffmanAccumulator(0x112233) << 41) << bb;
105
106 bb.ConsumeBits(20);
107 EXPECT_EQ(bb.count(), 3u) << bb;
108 EXPECT_EQ(bb.free_count(), 61u) << bb;
109 EXPECT_EQ(bb.value(), HuffmanAccumulator(0x3) << 61) << bb;
110 }
111
112 TEST(HuffmanBitBufferTest, AppendBytesUnaligned) {
113 string s;
114 s.push_back('\x11');
115 s.push_back('\x22');
116 s.push_back('\x33');
117 s.push_back('\x44');
118 s.push_back('\x55');
119 s.push_back('\x66');
120 s.push_back('\x77');
121 s.push_back('\x88');
122 s.push_back('\x99');
123 s.push_back('\xaa');
124 s.push_back('\xbb');
125 s.push_back('\xcc');
126 s.push_back('\xdd');
127 StringPiece sp(s);
128
129 HuffmanBitBuffer bb;
130 sp.remove_prefix(bb.AppendBytes(sp));
131 EXPECT_EQ(sp.size(), 5u);
132 EXPECT_FALSE(bb.InputProperlyTerminated());
133
134 bb.ConsumeBits(15);
135 EXPECT_EQ(bb.count(), 49u) << bb;
136 EXPECT_EQ(bb.free_count(), 15u) << bb;
137
138 HuffmanAccumulator expected(0x1122334455667788);
139 expected <<= 15;
140 EXPECT_EQ(bb.value(), expected);
141
142 sp.remove_prefix(bb.AppendBytes(sp));
143 EXPECT_EQ(sp.size(), 4u);
144 EXPECT_EQ(bb.count(), 57u) << bb;
145 EXPECT_EQ(bb.free_count(), 7u) << bb;
146
147 expected |= (HuffmanAccumulator(0x99) << 7);
148 EXPECT_EQ(bb.value(), expected) << bb << std::hex
149 << "\n actual: " << bb.value()
150 << "\n expected: " << expected;
151 }
152
153 enum class DecoderChoice { IF_TREE, SHORT_CODE };
154
155 class HpackHuffmanDecoderTest
156 : public RandomDecoderTest,
157 public ::testing::WithParamInterface<DecoderChoice> {
158 protected:
159 HpackHuffmanDecoderTest() {
160 // The decoder may return true, and its accumulator may be empty, at
161 // many boundaries while decoding, and yet the whole string hasn't
162 // been decoded.
163 stop_decode_on_done_ = false;
164 }
165
166 DecodeStatus StartDecoding(DecodeBuffer* b) override {
167 input_bytes_seen_ = 0;
168 output_buffer_.clear();
169 decoder_.Reset();
170 return ResumeDecoding(b);
171 }
172
173 DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
174 input_bytes_seen_ += b->Remaining();
175 StringPiece sp(b->cursor(), b->Remaining());
176 if (DecodeFragment(sp)) {
177 b->AdvanceCursor(b->Remaining());
178 // Successfully decoded (or buffered) the bytes in StringPiece.
179 EXPECT_LE(input_bytes_seen_, input_bytes_expected_);
180 // Have we reached the end of the encoded string?
181 if (input_bytes_expected_ == input_bytes_seen_) {
182 if (decoder_.InputProperlyTerminated()) {
183 return DecodeStatus::kDecodeDone;
184 } else {
185 return DecodeStatus::kDecodeError;
186 }
187 }
188 return DecodeStatus::kDecodeInProgress;
189 }
190 return DecodeStatus::kDecodeError;
191 }
192
193 bool DecodeFragment(StringPiece sp) {
194 switch (GetParam()) {
195 case DecoderChoice::IF_TREE:
196 return decoder_.DecodeWithIfTreeAndStruct(sp, &output_buffer_);
197 case DecoderChoice::SHORT_CODE:
198 return decoder_.DecodeShortCodesFirst(sp, &output_buffer_);
199 }
200
201 NOTREACHED();
202 return false;
203 }
204
205 AssertionResult ValidatorForHuffmanDecodeAndValidateSeveralWays(
206 StringPiece expected_plain) {
207 VERIFY_EQ(output_buffer_.size(), expected_plain.size());
208 VERIFY_EQ(output_buffer_, expected_plain);
209 return AssertionSuccess();
210 }
211
212 AssertionResult HuffmanDecodeAndValidateSeveralWays(
213 StringPiece encoded,
214 StringPiece expected_plain) {
215 input_bytes_expected_ = encoded.size();
216 DecodeBuffer db(encoded);
217 bool return_non_zero_on_first = false;
218 return DecodeAndValidateSeveralWays(
219 &db, return_non_zero_on_first,
220 ValidateDoneAndEmpty(
221 base::Bind(&HpackHuffmanDecoderTest::
222 ValidatorForHuffmanDecodeAndValidateSeveralWays,
223 base::Unretained(this), expected_plain)));
224 }
225
226 HpackHuffmanDecoder decoder_;
227 string output_buffer_;
228 size_t input_bytes_seen_;
229 size_t input_bytes_expected_;
230 };
231 INSTANTIATE_TEST_CASE_P(AllDecoders,
232 HpackHuffmanDecoderTest,
233 ::testing::Values(DecoderChoice::IF_TREE,
234 DecoderChoice::SHORT_CODE));
235
236 TEST_P(HpackHuffmanDecoderTest, SpecRequestExamples) {
237 HpackHuffmanDecoder decoder;
238 string test_table[] = {
239 a2b_hex("f1e3c2e5f23a6ba0ab90f4ff"),
240 "www.example.com",
241 a2b_hex("a8eb10649cbf"),
242 "no-cache",
243 a2b_hex("25a849e95ba97d7f"),
244 "custom-key",
245 a2b_hex("25a849e95bb8e8b4bf"),
246 "custom-value",
247 };
248 for (size_t i = 0; i != arraysize(test_table); i += 2) {
249 const string& huffman_encoded(test_table[i]);
250 const string& plain_string(test_table[i + 1]);
251 string buffer;
252 decoder.Reset();
253 EXPECT_TRUE(decoder.Decode(huffman_encoded, &buffer)) << decoder;
254 EXPECT_TRUE(decoder.InputProperlyTerminated()) << decoder;
255 EXPECT_EQ(buffer, plain_string);
256 }
257 }
258
259 TEST_P(HpackHuffmanDecoderTest, SpecResponseExamples) {
260 HpackHuffmanDecoder decoder;
261 // clang-format off
262 string test_table[] = {
263 a2b_hex("6402"),
264 "302",
265 a2b_hex("aec3771a4b"),
266 "private",
267 a2b_hex("d07abe941054d444a8200595040b8166"
268 "e082a62d1bff"),
269 "Mon, 21 Oct 2013 20:13:21 GMT",
270 a2b_hex("9d29ad171863c78f0b97c8e9ae82ae43"
271 "d3"),
272 "https://www.example.com",
273 a2b_hex("94e7821dd7f2e6c7b335dfdfcd5b3960"
274 "d5af27087f3672c1ab270fb5291f9587"
275 "316065c003ed4ee5b1063d5007"),
276 "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
277 };
278 // clang-format on
279 for (size_t i = 0; i != arraysize(test_table); i += 2) {
280 const string& huffman_encoded(test_table[i]);
281 const string& plain_string(test_table[i + 1]);
282 string buffer;
283 decoder.Reset();
284 EXPECT_TRUE(decoder.Decode(huffman_encoded, &buffer)) << decoder;
285 EXPECT_TRUE(decoder.InputProperlyTerminated()) << decoder;
286 EXPECT_EQ(buffer, plain_string);
287 }
288 }
289
290 } // namespace
291 } // namespace test
292 } // namespace net
OLDNEW
« no previous file with comments | « net/http2/hpack/huffman/http2_hpack_huffman_decoder.cc ('k') | net/http2/hpack/tools/hpack_block_builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698