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

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

Issue 2570513003: This change removes HpackEncoder::EncodeHeaderSetWithoutCompression() and the corresponding progres… (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
« no previous file with comments | « net/spdy/hpack/hpack_encoder.cc ('k') | net/spdy/spdy_framer.cc » ('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_encoder.h" 5 #include "net/spdy/hpack/hpack_encoder.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 9
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
11 #include "net/base/arena.h" 11 #include "net/base/arena.h"
12 #include "net/spdy/hpack/hpack_huffman_table.h"
12 #include "testing/gmock/include/gmock/gmock.h" 13 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
14 15
15 namespace net { 16 namespace net {
16 17
17 using base::StringPiece; 18 using base::StringPiece;
18 using std::string; 19 using std::string;
19 using std::vector; 20 using std::vector;
20 using std::pair; 21 using std::pair;
21 using testing::ElementsAre; 22 using testing::ElementsAre;
(...skipping 12 matching lines...) Expand all
34 HpackHeaderTable* table_; 35 HpackHeaderTable* table_;
35 }; 36 };
36 37
37 class HpackEncoderPeer { 38 class HpackEncoderPeer {
38 public: 39 public:
39 typedef HpackEncoder::Representation Representation; 40 typedef HpackEncoder::Representation Representation;
40 typedef HpackEncoder::Representations Representations; 41 typedef HpackEncoder::Representations Representations;
41 42
42 explicit HpackEncoderPeer(HpackEncoder* encoder) : encoder_(encoder) {} 43 explicit HpackEncoderPeer(HpackEncoder* encoder) : encoder_(encoder) {}
43 44
45 bool compression_enabled() const { return encoder_->enable_compression_; }
44 HpackHeaderTable* table() { return &encoder_->header_table_; } 46 HpackHeaderTable* table() { return &encoder_->header_table_; }
45 HpackHeaderTablePeer table_peer() { return HpackHeaderTablePeer(table()); } 47 HpackHeaderTablePeer table_peer() { return HpackHeaderTablePeer(table()); }
46 void set_allow_huffman_compression(bool allow) { 48 const HpackHuffmanTable& huffman_table() const {
47 encoder_->allow_huffman_compression_ = allow; 49 return encoder_->huffman_table_;
48 } 50 }
49 void EmitString(StringPiece str) { encoder_->EmitString(str); } 51 void EmitString(StringPiece str) { encoder_->EmitString(str); }
50 void TakeString(string* out) { encoder_->output_stream_.TakeString(out); } 52 void TakeString(string* out) { encoder_->output_stream_.TakeString(out); }
51 static void CookieToCrumbs(StringPiece cookie, 53 static void CookieToCrumbs(StringPiece cookie,
52 std::vector<StringPiece>* out) { 54 std::vector<StringPiece>* out) {
53 Representations tmp; 55 Representations tmp;
54 HpackEncoder::CookieToCrumbs(std::make_pair("", cookie), &tmp); 56 HpackEncoder::CookieToCrumbs(std::make_pair("", cookie), &tmp);
55 57
56 out->clear(); 58 out->clear();
57 for (size_t i = 0; i != tmp.size(); ++i) { 59 for (size_t i = 0; i != tmp.size(); ++i) {
(...skipping 10 matching lines...) Expand all
68 for (size_t i = 0; i != tmp.size(); ++i) { 70 for (size_t i = 0; i != tmp.size(); ++i) {
69 out->push_back(tmp[i].second); 71 out->push_back(tmp[i].second);
70 } 72 }
71 } 73 }
72 74
73 // TODO(dahollings): Remove or clean up these methods when deprecating 75 // TODO(dahollings): Remove or clean up these methods when deprecating
74 // non-incremental encoding path. 76 // non-incremental encoding path.
75 static bool EncodeHeaderSet(HpackEncoder* encoder, 77 static bool EncodeHeaderSet(HpackEncoder* encoder,
76 const SpdyHeaderBlock& header_set, 78 const SpdyHeaderBlock& header_set,
77 string* output, 79 string* output,
78 bool use_compression,
79 bool use_incremental) { 80 bool use_incremental) {
80 if (use_incremental) { 81 if (use_incremental) {
81 return EncodeIncremental(encoder, header_set, output, use_compression); 82 return EncodeIncremental(encoder, header_set, output);
82 } else { 83 } else {
83 return use_compression ? encoder->EncodeHeaderSet(header_set, output) 84 return encoder->EncodeHeaderSet(header_set, output);
84 : encoder->EncodeHeaderSetWithoutCompression(
85 header_set, output);
86 } 85 }
87 } 86 }
88 87
89 static bool EncodeIncremental(HpackEncoder* encoder, 88 static bool EncodeIncremental(HpackEncoder* encoder,
90 const SpdyHeaderBlock& header_set, 89 const SpdyHeaderBlock& header_set,
91 string* output, 90 string* output) {
92 bool use_compression) {
93 std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoderator = 91 std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoderator =
94 encoder->EncodeHeaderSet(header_set, use_compression); 92 encoder->EncodeHeaderSet(header_set);
95 string output_buffer; 93 string output_buffer;
96 encoderator->Next(base::RandInt(0, 15), &output_buffer); 94 encoderator->Next(base::RandInt(0, 15), &output_buffer);
97 while (encoderator->HasNext()) { 95 while (encoderator->HasNext()) {
98 string second_buffer; 96 string second_buffer;
99 encoderator->Next(base::RandInt(0, 15), &second_buffer); 97 encoderator->Next(base::RandInt(0, 15), &second_buffer);
100 output_buffer.append(second_buffer); 98 output_buffer.append(second_buffer);
101 } 99 }
102 *output = std::move(output_buffer); 100 *output = std::move(output_buffer);
103 return true; 101 return true;
104 } 102 }
(...skipping 25 matching lines...) Expand all
130 128
131 // Populate dynamic entries into the table fixture. For simplicity each 129 // Populate dynamic entries into the table fixture. For simplicity each
132 // entry has name.size() + value.size() == 10. 130 // entry has name.size() + value.size() == 10.
133 key_1_ = peer_.table()->TryAddEntry("key1", "value1"); 131 key_1_ = peer_.table()->TryAddEntry("key1", "value1");
134 key_2_ = peer_.table()->TryAddEntry("key2", "value2"); 132 key_2_ = peer_.table()->TryAddEntry("key2", "value2");
135 cookie_a_ = peer_.table()->TryAddEntry("cookie", "a=bb"); 133 cookie_a_ = peer_.table()->TryAddEntry("cookie", "a=bb");
136 cookie_c_ = peer_.table()->TryAddEntry("cookie", "c=dd"); 134 cookie_c_ = peer_.table()->TryAddEntry("cookie", "c=dd");
137 135
138 // No further insertions may occur without evictions. 136 // No further insertions may occur without evictions.
139 peer_.table()->SetMaxSize(peer_.table()->size()); 137 peer_.table()->SetMaxSize(peer_.table()->size());
140
141 // Disable Huffman coding by default. Most tests don't care about it.
142 peer_.set_allow_huffman_compression(false);
143 } 138 }
144 139
145 void SaveHeaders(StringPiece name, StringPiece value) { 140 void SaveHeaders(StringPiece name, StringPiece value) {
146 StringPiece n(headers_storage_.Memdup(name.data(), name.size()), 141 StringPiece n(headers_storage_.Memdup(name.data(), name.size()),
147 name.size()); 142 name.size());
148 StringPiece v(headers_storage_.Memdup(value.data(), value.size()), 143 StringPiece v(headers_storage_.Memdup(value.data(), value.size()),
149 value.size()); 144 value.size());
150 headers_observed_.push_back(make_pair(n, v)); 145 headers_observed_.push_back(make_pair(n, v));
151 } 146 }
152 147
153 void ExpectIndex(size_t index) { 148 void ExpectIndex(size_t index) {
154 expected_.AppendPrefix(kIndexedOpcode); 149 expected_.AppendPrefix(kIndexedOpcode);
155 expected_.AppendUint32(index); 150 expected_.AppendUint32(index);
156 } 151 }
157 void ExpectIndexedLiteral(const HpackEntry* key_entry, StringPiece value) { 152 void ExpectIndexedLiteral(const HpackEntry* key_entry, StringPiece value) {
158 expected_.AppendPrefix(kLiteralIncrementalIndexOpcode); 153 expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
159 expected_.AppendUint32(IndexOf(key_entry)); 154 expected_.AppendUint32(IndexOf(key_entry));
160 expected_.AppendPrefix(kStringLiteralIdentityEncoded); 155 ExpectString(&expected_, value);
161 expected_.AppendUint32(value.size());
162 expected_.AppendBytes(value);
163 } 156 }
164 void ExpectIndexedLiteral(StringPiece name, StringPiece value) { 157 void ExpectIndexedLiteral(StringPiece name, StringPiece value) {
165 expected_.AppendPrefix(kLiteralIncrementalIndexOpcode); 158 expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
166 expected_.AppendUint32(0); 159 expected_.AppendUint32(0);
167 expected_.AppendPrefix(kStringLiteralIdentityEncoded); 160 ExpectString(&expected_, name);
168 expected_.AppendUint32(name.size()); 161 ExpectString(&expected_, value);
169 expected_.AppendBytes(name);
170 expected_.AppendPrefix(kStringLiteralIdentityEncoded);
171 expected_.AppendUint32(value.size());
172 expected_.AppendBytes(value);
173 } 162 }
174 void ExpectNonIndexedLiteral(StringPiece name, StringPiece value) { 163 void ExpectNonIndexedLiteral(StringPiece name, StringPiece value) {
175 expected_.AppendPrefix(kLiteralNoIndexOpcode); 164 expected_.AppendPrefix(kLiteralNoIndexOpcode);
176 expected_.AppendUint32(0); 165 expected_.AppendUint32(0);
177 expected_.AppendPrefix(kStringLiteralIdentityEncoded); 166 ExpectString(&expected_, name);
178 expected_.AppendUint32(name.size()); 167 ExpectString(&expected_, value);
179 expected_.AppendBytes(name); 168 }
180 expected_.AppendPrefix(kStringLiteralIdentityEncoded); 169 void ExpectString(HpackOutputStream* stream, StringPiece str) {
181 expected_.AppendUint32(value.size()); 170 const HpackHuffmanTable& huffman_table = peer_.huffman_table();
182 expected_.AppendBytes(value); 171 size_t encoded_size = peer_.compression_enabled()
172 ? huffman_table.EncodedSize(str)
173 : str.size();
174 if (encoded_size < str.size()) {
175 expected_.AppendPrefix(kStringLiteralHuffmanEncoded);
176 expected_.AppendUint32(encoded_size);
177 huffman_table.EncodeString(str, stream);
178 } else {
179 expected_.AppendPrefix(kStringLiteralIdentityEncoded);
180 expected_.AppendUint32(str.size());
181 expected_.AppendBytes(str);
182 }
183 } 183 }
184 void ExpectHeaderTableSizeUpdate(uint32_t size) { 184 void ExpectHeaderTableSizeUpdate(uint32_t size) {
185 expected_.AppendPrefix(kHeaderTableSizeUpdateOpcode); 185 expected_.AppendPrefix(kHeaderTableSizeUpdateOpcode);
186 expected_.AppendUint32(size); 186 expected_.AppendUint32(size);
187 } 187 }
188 void CompareWithExpectedEncoding(const SpdyHeaderBlock& header_set) { 188 void CompareWithExpectedEncoding(const SpdyHeaderBlock& header_set) {
189 string expected_out, actual_out; 189 string expected_out, actual_out;
190 expected_.TakeString(&expected_out); 190 expected_.TakeString(&expected_out);
191 EXPECT_TRUE(test::HpackEncoderPeer::EncodeHeaderSet( 191 EXPECT_TRUE(test::HpackEncoderPeer::EncodeHeaderSet(
192 &encoder_, header_set, &actual_out, true, use_incremental_)); 192 &encoder_, header_set, &actual_out, use_incremental_));
193 EXPECT_EQ(expected_out, actual_out);
194 }
195 void CompareWithExpectedEncodingWithoutCompression(
196 const SpdyHeaderBlock& header_set) {
197 string expected_out, actual_out;
198 expected_.TakeString(&expected_out);
199 EXPECT_TRUE(test::HpackEncoderPeer::EncodeHeaderSet(
200 &encoder_, header_set, &actual_out, false, use_incremental_));
201 EXPECT_EQ(expected_out, actual_out); 193 EXPECT_EQ(expected_out, actual_out);
202 } 194 }
203 size_t IndexOf(const HpackEntry* entry) { 195 size_t IndexOf(const HpackEntry* entry) {
204 return peer_.table()->IndexOf(entry); 196 return peer_.table()->IndexOf(entry);
205 } 197 }
206 198
207 HpackEncoder encoder_; 199 HpackEncoder encoder_;
208 test::HpackEncoderPeer peer_; 200 test::HpackEncoderPeer peer_;
209 201
210 const HpackEntry* static_; 202 const HpackEntry* static_;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 ExpectIndex(IndexOf(cookie_a_)); 302 ExpectIndex(IndexOf(cookie_a_));
311 ExpectIndex(IndexOf(cookie_c_)); 303 ExpectIndex(IndexOf(cookie_c_));
312 ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "e=ff"); 304 ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "e=ff");
313 305
314 SpdyHeaderBlock headers; 306 SpdyHeaderBlock headers;
315 headers["cookie"] = "a=bb; c=dd; e=ff"; 307 headers["cookie"] = "a=bb; c=dd; e=ff";
316 CompareWithExpectedEncoding(headers); 308 CompareWithExpectedEncoding(headers);
317 } 309 }
318 310
319 TEST_P(HpackEncoderTest, StringsDynamicallySelectHuffmanCoding) { 311 TEST_P(HpackEncoderTest, StringsDynamicallySelectHuffmanCoding) {
320 peer_.set_allow_huffman_compression(true);
321
322 // Compactable string. Uses Huffman coding. 312 // Compactable string. Uses Huffman coding.
323 peer_.EmitString("feedbeef"); 313 peer_.EmitString("feedbeef");
324 expected_.AppendPrefix(kStringLiteralHuffmanEncoded); 314 expected_.AppendPrefix(kStringLiteralHuffmanEncoded);
325 expected_.AppendUint32(6); 315 expected_.AppendUint32(6);
326 expected_.AppendBytes("\x94\xA5\x92\x32\x96_"); 316 expected_.AppendBytes("\x94\xA5\x92\x32\x96_");
327 317
328 // Non-compactable. Uses identity coding. 318 // Non-compactable. Uses identity coding.
329 peer_.EmitString("@@@@@@"); 319 peer_.EmitString("@@@@@@");
330 expected_.AppendPrefix(kStringLiteralIdentityEncoded); 320 expected_.AppendPrefix(kStringLiteralIdentityEncoded);
331 expected_.AppendUint32(6); 321 expected_.AppendUint32(6);
332 expected_.AppendBytes("@@@@@@"); 322 expected_.AppendBytes("@@@@@@");
333 323
334 string expected_out, actual_out; 324 string expected_out, actual_out;
335 expected_.TakeString(&expected_out); 325 expected_.TakeString(&expected_out);
336 peer_.TakeString(&actual_out); 326 peer_.TakeString(&actual_out);
337 EXPECT_EQ(expected_out, actual_out); 327 EXPECT_EQ(expected_out, actual_out);
338 } 328 }
339 329
340 TEST_P(HpackEncoderTest, EncodingWithoutCompression) { 330 TEST_P(HpackEncoderTest, EncodingWithoutCompression) {
341 encoder_.SetHeaderListener([this](StringPiece name, StringPiece value) { 331 encoder_.SetHeaderListener([this](StringPiece name, StringPiece value) {
342 this->SaveHeaders(name, value); 332 this->SaveHeaders(name, value);
343 }); 333 });
344 334 encoder_.DisableCompression();
345 // Implementation should internally disable.
346 peer_.set_allow_huffman_compression(true);
347 335
348 ExpectNonIndexedLiteral(":path", "/index.html"); 336 ExpectNonIndexedLiteral(":path", "/index.html");
349 ExpectNonIndexedLiteral("cookie", "foo=bar; baz=bing"); 337 ExpectNonIndexedLiteral("cookie", "foo=bar");
338 ExpectNonIndexedLiteral("cookie", "baz=bing");
350 ExpectNonIndexedLiteral("hello", "goodbye"); 339 ExpectNonIndexedLiteral("hello", "goodbye");
351 340
352 SpdyHeaderBlock headers; 341 SpdyHeaderBlock headers;
353 headers[":path"] = "/index.html"; 342 headers[":path"] = "/index.html";
354 headers["cookie"] = "foo=bar; baz=bing"; 343 headers["cookie"] = "foo=bar; baz=bing";
355 headers["hello"] = "goodbye"; 344 headers["hello"] = "goodbye";
356 345
357 CompareWithExpectedEncodingWithoutCompression(headers); 346 CompareWithExpectedEncoding(headers);
358 347
359 EXPECT_THAT(headers_observed_, 348 EXPECT_THAT(
360 ElementsAre(Pair(":path", "/index.html"), 349 headers_observed_,
361 Pair("cookie", "foo=bar; baz=bing"), 350 ElementsAre(Pair(":path", "/index.html"), Pair("cookie", "foo=bar"),
362 Pair("hello", "goodbye"))); 351 Pair("cookie", "baz=bing"), Pair("hello", "goodbye")));
363 } 352 }
364 353
365 TEST_P(HpackEncoderTest, MultipleEncodingPasses) { 354 TEST_P(HpackEncoderTest, MultipleEncodingPasses) {
366 encoder_.SetHeaderListener([this](StringPiece name, StringPiece value) { 355 encoder_.SetHeaderListener([this](StringPiece name, StringPiece value) {
367 this->SaveHeaders(name, value); 356 this->SaveHeaders(name, value);
368 }); 357 });
369 358
370 // Pass 1. 359 // Pass 1.
371 { 360 {
372 SpdyHeaderBlock headers; 361 SpdyHeaderBlock headers;
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 CompareWithExpectedEncoding(headers); 579 CompareWithExpectedEncoding(headers);
591 580
592 HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front(); 581 HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
593 EXPECT_EQ(new_entry->name(), "key3"); 582 EXPECT_EQ(new_entry->name(), "key3");
594 EXPECT_EQ(new_entry->value(), "value3"); 583 EXPECT_EQ(new_entry->value(), "value3");
595 } 584 }
596 585
597 } // namespace 586 } // namespace
598 587
599 } // namespace net 588 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/hpack/hpack_encoder.cc ('k') | net/spdy/spdy_framer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698