OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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_decoder3.h" | 5 #include "net/spdy/hpack/hpack_decoder3.h" |
6 | 6 |
7 // Tests of HpackDecoder3. | 7 // Tests of HpackDecoder3. |
8 | 8 |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include <string> | |
12 #include <tuple> | 11 #include <tuple> |
13 #include <utility> | 12 #include <utility> |
14 #include <vector> | 13 #include <vector> |
15 | 14 |
16 #include "base/logging.h" | 15 #include "base/logging.h" |
17 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
18 #include "net/http2/hpack/decoder/hpack_decoder_state.h" | 17 #include "net/http2/hpack/decoder/hpack_decoder_state.h" |
19 #include "net/http2/hpack/decoder/hpack_decoder_tables.h" | 18 #include "net/http2/hpack/decoder/hpack_decoder_tables.h" |
20 #include "net/http2/hpack/tools/hpack_block_builder.h" | 19 #include "net/http2/hpack/tools/hpack_block_builder.h" |
21 #include "net/http2/tools/http2_random.h" | 20 #include "net/http2/tools/http2_random.h" |
22 #include "net/spdy/hpack/hpack_constants.h" | 21 #include "net/spdy/hpack/hpack_constants.h" |
23 #include "net/spdy/hpack/hpack_encoder.h" | 22 #include "net/spdy/hpack/hpack_encoder.h" |
24 #include "net/spdy/hpack/hpack_huffman_table.h" | 23 #include "net/spdy/hpack/hpack_huffman_table.h" |
25 #include "net/spdy/hpack/hpack_output_stream.h" | 24 #include "net/spdy/hpack/hpack_output_stream.h" |
| 25 #include "net/spdy/platform/api/spdy_string.h" |
26 #include "net/spdy/spdy_test_utils.h" | 26 #include "net/spdy/spdy_test_utils.h" |
27 #include "testing/gmock/include/gmock/gmock.h" | 27 #include "testing/gmock/include/gmock/gmock.h" |
28 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
29 | 29 |
30 using std::string; | |
31 using ::testing::ElementsAre; | 30 using ::testing::ElementsAre; |
32 using ::testing::Pair; | 31 using ::testing::Pair; |
33 | 32 |
34 namespace net { | 33 namespace net { |
35 namespace test { | 34 namespace test { |
36 | 35 |
37 class HpackDecoderStatePeer { | 36 class HpackDecoderStatePeer { |
38 public: | 37 public: |
39 static HpackDecoderTables* GetDecoderTables(HpackDecoderState* state) { | 38 static HpackDecoderTables* GetDecoderTables(HpackDecoderState* state) { |
40 return &state->decoder_tables_; | 39 return &state->decoder_tables_; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 } | 166 } |
168 } | 167 } |
169 | 168 |
170 const SpdyHeaderBlock& DecodeBlockExpectingSuccess(SpdyStringPiece str) { | 169 const SpdyHeaderBlock& DecodeBlockExpectingSuccess(SpdyStringPiece str) { |
171 EXPECT_TRUE(DecodeHeaderBlock(str)); | 170 EXPECT_TRUE(DecodeHeaderBlock(str)); |
172 return decoded_block(); | 171 return decoded_block(); |
173 } | 172 } |
174 | 173 |
175 void expectEntry(size_t index, | 174 void expectEntry(size_t index, |
176 size_t size, | 175 size_t size, |
177 const string& name, | 176 const SpdyString& name, |
178 const string& value) { | 177 const SpdyString& value) { |
179 const HpackStringPair* entry = decoder_peer_.GetTableEntry(index); | 178 const HpackStringPair* entry = decoder_peer_.GetTableEntry(index); |
180 EXPECT_EQ(name, entry->name) << "index " << index; | 179 EXPECT_EQ(name, entry->name) << "index " << index; |
181 EXPECT_EQ(value, entry->value); | 180 EXPECT_EQ(value, entry->value); |
182 EXPECT_EQ(size, entry->size()); | 181 EXPECT_EQ(size, entry->size()); |
183 } | 182 } |
184 | 183 |
185 SpdyHeaderBlock MakeHeaderBlock( | 184 SpdyHeaderBlock MakeHeaderBlock( |
186 const std::vector<std::pair<string, string>>& headers) { | 185 const std::vector<std::pair<SpdyString, SpdyString>>& headers) { |
187 SpdyHeaderBlock result; | 186 SpdyHeaderBlock result; |
188 for (const auto& kv : headers) { | 187 for (const auto& kv : headers) { |
189 result.AppendValueOrAddHeader(kv.first, kv.second); | 188 result.AppendValueOrAddHeader(kv.first, kv.second); |
190 } | 189 } |
191 return result; | 190 return result; |
192 } | 191 } |
193 | 192 |
194 Http2Random random_; | 193 Http2Random random_; |
195 HpackHuffmanTable huffman_table_; | 194 HpackHuffmanTable huffman_table_; |
196 HpackDecoder3 decoder_; | 195 HpackDecoder3 decoder_; |
(...skipping 10 matching lines...) Expand all Loading... |
207 ::testing::Combine( | 206 ::testing::Combine( |
208 ::testing::Values(START_WITH_HANDLER, START_WITHOUT_HANDLER, NO_START), | 207 ::testing::Values(START_WITH_HANDLER, START_WITHOUT_HANDLER, NO_START), |
209 ::testing::Bool())); | 208 ::testing::Bool())); |
210 | 209 |
211 TEST_P(HpackDecoder3Test, AddHeaderDataWithHandleControlFrameHeadersData) { | 210 TEST_P(HpackDecoder3Test, AddHeaderDataWithHandleControlFrameHeadersData) { |
212 // The hpack decode buffer size is limited in size. This test verifies that | 211 // The hpack decode buffer size is limited in size. This test verifies that |
213 // adding encoded data under that limit is accepted, and data that exceeds the | 212 // adding encoded data under that limit is accepted, and data that exceeds the |
214 // limit is rejected. | 213 // limit is rejected. |
215 HandleControlFrameHeadersStart(); | 214 HandleControlFrameHeadersStart(); |
216 const size_t kMaxBufferSizeBytes = 50; | 215 const size_t kMaxBufferSizeBytes = 50; |
217 const string a_value = string(49, 'x'); | 216 const SpdyString a_value = SpdyString(49, 'x'); |
218 decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); | 217 decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); |
219 HpackBlockBuilder hbb; | 218 HpackBlockBuilder hbb; |
220 hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, | 219 hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, |
221 false, "a", false, a_value); | 220 false, "a", false, a_value); |
222 const string& s = hbb.buffer(); | 221 const SpdyString& s = hbb.buffer(); |
223 EXPECT_GT(s.size(), kMaxBufferSizeBytes); | 222 EXPECT_GT(s.size(), kMaxBufferSizeBytes); |
224 | 223 |
225 // Any one in input buffer must not exceed kMaxBufferSizeBytes. | 224 // Any one in input buffer must not exceed kMaxBufferSizeBytes. |
226 EXPECT_TRUE(HandleControlFrameHeadersData(s.substr(0, s.size() / 2))); | 225 EXPECT_TRUE(HandleControlFrameHeadersData(s.substr(0, s.size() / 2))); |
227 EXPECT_TRUE(HandleControlFrameHeadersData(s.substr(s.size() / 2))); | 226 EXPECT_TRUE(HandleControlFrameHeadersData(s.substr(s.size() / 2))); |
228 | 227 |
229 EXPECT_FALSE(HandleControlFrameHeadersData(s)); | 228 EXPECT_FALSE(HandleControlFrameHeadersData(s)); |
230 SpdyHeaderBlock expected_block = MakeHeaderBlock({{"a", a_value}}); | 229 SpdyHeaderBlock expected_block = MakeHeaderBlock({{"a", a_value}}); |
231 EXPECT_EQ(expected_block, decoded_block()); | 230 EXPECT_EQ(expected_block, decoded_block()); |
232 } | 231 } |
233 | 232 |
234 TEST_P(HpackDecoder3Test, NameTooLong) { | 233 TEST_P(HpackDecoder3Test, NameTooLong) { |
235 // Verify that a name longer than the allowed size generates an error. | 234 // Verify that a name longer than the allowed size generates an error. |
236 const size_t kMaxBufferSizeBytes = 50; | 235 const size_t kMaxBufferSizeBytes = 50; |
237 const string name = string(2 * kMaxBufferSizeBytes, 'x'); | 236 const SpdyString name = SpdyString(2 * kMaxBufferSizeBytes, 'x'); |
238 const string value = "abc"; | 237 const SpdyString value = "abc"; |
239 | 238 |
240 decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); | 239 decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); |
241 | 240 |
242 HpackBlockBuilder hbb; | 241 HpackBlockBuilder hbb; |
243 hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, | 242 hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, |
244 false, name, false, value); | 243 false, name, false, value); |
245 | 244 |
246 const size_t fragment_size = (3 * kMaxBufferSizeBytes) / 2; | 245 const size_t fragment_size = (3 * kMaxBufferSizeBytes) / 2; |
247 const string fragment = hbb.buffer().substr(0, fragment_size); | 246 const SpdyString fragment = hbb.buffer().substr(0, fragment_size); |
248 | 247 |
249 HandleControlFrameHeadersStart(); | 248 HandleControlFrameHeadersStart(); |
250 EXPECT_FALSE(HandleControlFrameHeadersData(fragment)); | 249 EXPECT_FALSE(HandleControlFrameHeadersData(fragment)); |
251 } | 250 } |
252 | 251 |
253 TEST_P(HpackDecoder3Test, HeaderTooLongToBuffer) { | 252 TEST_P(HpackDecoder3Test, HeaderTooLongToBuffer) { |
254 // Verify that a header longer than the allowed size generates an error if | 253 // Verify that a header longer than the allowed size generates an error if |
255 // it isn't all in one input buffer. | 254 // it isn't all in one input buffer. |
256 const string name = "some-key"; | 255 const SpdyString name = "some-key"; |
257 const string value = "some-value"; | 256 const SpdyString value = "some-value"; |
258 const size_t kMaxBufferSizeBytes = name.size() + value.size() - 2; | 257 const size_t kMaxBufferSizeBytes = name.size() + value.size() - 2; |
259 decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); | 258 decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); |
260 | 259 |
261 HpackBlockBuilder hbb; | 260 HpackBlockBuilder hbb; |
262 hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, | 261 hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, |
263 false, name, false, value); | 262 false, name, false, value); |
264 const size_t fragment_size = hbb.size() - 1; | 263 const size_t fragment_size = hbb.size() - 1; |
265 const string fragment = hbb.buffer().substr(0, fragment_size); | 264 const SpdyString fragment = hbb.buffer().substr(0, fragment_size); |
266 | 265 |
267 HandleControlFrameHeadersStart(); | 266 HandleControlFrameHeadersStart(); |
268 EXPECT_FALSE(HandleControlFrameHeadersData(fragment)); | 267 EXPECT_FALSE(HandleControlFrameHeadersData(fragment)); |
269 } | 268 } |
270 | 269 |
271 // Decode with incomplete data in buffer. | 270 // Decode with incomplete data in buffer. |
272 TEST_P(HpackDecoder3Test, DecodeWithIncompleteData) { | 271 TEST_P(HpackDecoder3Test, DecodeWithIncompleteData) { |
273 HandleControlFrameHeadersStart(); | 272 HandleControlFrameHeadersStart(); |
274 | 273 |
275 // No need to wait for more data. | 274 // No need to wait for more data. |
276 EXPECT_TRUE(HandleControlFrameHeadersData("\x82\x85\x82")); | 275 EXPECT_TRUE(HandleControlFrameHeadersData("\x82\x85\x82")); |
277 std::vector<std::pair<string, string>> expected_headers = { | 276 std::vector<std::pair<SpdyString, SpdyString>> expected_headers = { |
278 {":method", "GET"}, {":path", "/index.html"}, {":method", "GET"}}; | 277 {":method", "GET"}, {":path", "/index.html"}, {":method", "GET"}}; |
279 | 278 |
280 SpdyHeaderBlock expected_block1 = MakeHeaderBlock(expected_headers); | 279 SpdyHeaderBlock expected_block1 = MakeHeaderBlock(expected_headers); |
281 EXPECT_EQ(expected_block1, decoded_block()); | 280 EXPECT_EQ(expected_block1, decoded_block()); |
282 | 281 |
283 // Full and partial headers, won't add partial to the headers. | 282 // Full and partial headers, won't add partial to the headers. |
284 EXPECT_TRUE( | 283 EXPECT_TRUE( |
285 HandleControlFrameHeadersData("\x40\x03goo" | 284 HandleControlFrameHeadersData("\x40\x03goo" |
286 "\x03gar\xbe\x40\x04spam")); | 285 "\x03gar\xbe\x40\x04spam")); |
287 expected_headers.push_back({"goo", "gar"}); | 286 expected_headers.push_back({"goo", "gar"}); |
(...skipping 20 matching lines...) Expand all Loading... |
308 HandleControlFrameHeadersStart(); | 307 HandleControlFrameHeadersStart(); |
309 HandleControlFrameHeadersData(""); | 308 HandleControlFrameHeadersData(""); |
310 | 309 |
311 // All cookie crumbs are joined. | 310 // All cookie crumbs are joined. |
312 decoder_peer_.HandleHeaderRepresentation("cookie", " part 1"); | 311 decoder_peer_.HandleHeaderRepresentation("cookie", " part 1"); |
313 decoder_peer_.HandleHeaderRepresentation("cookie", "part 2 "); | 312 decoder_peer_.HandleHeaderRepresentation("cookie", "part 2 "); |
314 decoder_peer_.HandleHeaderRepresentation("cookie", "part3"); | 313 decoder_peer_.HandleHeaderRepresentation("cookie", "part3"); |
315 | 314 |
316 // Already-delimited headers are passed through. | 315 // Already-delimited headers are passed through. |
317 decoder_peer_.HandleHeaderRepresentation("passed-through", | 316 decoder_peer_.HandleHeaderRepresentation("passed-through", |
318 string("foo\0baz", 7)); | 317 SpdyString("foo\0baz", 7)); |
319 | 318 |
320 // Other headers are joined on \0. Case matters. | 319 // Other headers are joined on \0. Case matters. |
321 decoder_peer_.HandleHeaderRepresentation("joined", "not joined"); | 320 decoder_peer_.HandleHeaderRepresentation("joined", "not joined"); |
322 decoder_peer_.HandleHeaderRepresentation("joineD", "value 1"); | 321 decoder_peer_.HandleHeaderRepresentation("joineD", "value 1"); |
323 decoder_peer_.HandleHeaderRepresentation("joineD", "value 2"); | 322 decoder_peer_.HandleHeaderRepresentation("joineD", "value 2"); |
324 | 323 |
325 // Empty headers remain empty. | 324 // Empty headers remain empty. |
326 decoder_peer_.HandleHeaderRepresentation("empty", ""); | 325 decoder_peer_.HandleHeaderRepresentation("empty", ""); |
327 | 326 |
328 // Joined empty headers work as expected. | 327 // Joined empty headers work as expected. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 | 394 |
396 // Test a too-large indexed header. | 395 // Test a too-large indexed header. |
397 TEST_P(HpackDecoder3Test, InvalidIndexedHeader) { | 396 TEST_P(HpackDecoder3Test, InvalidIndexedHeader) { |
398 // High-bit set, and a prefix of one more than the number of static entries. | 397 // High-bit set, and a prefix of one more than the number of static entries. |
399 EXPECT_FALSE(DecodeHeaderBlock("\xbe")); | 398 EXPECT_FALSE(DecodeHeaderBlock("\xbe")); |
400 } | 399 } |
401 | 400 |
402 TEST_P(HpackDecoder3Test, ContextUpdateMaximumSize) { | 401 TEST_P(HpackDecoder3Test, ContextUpdateMaximumSize) { |
403 EXPECT_EQ(kDefaultHeaderTableSizeSetting, | 402 EXPECT_EQ(kDefaultHeaderTableSizeSetting, |
404 decoder_peer_.header_table_size_limit()); | 403 decoder_peer_.header_table_size_limit()); |
405 string input; | 404 SpdyString input; |
406 { | 405 { |
407 // Maximum-size update with size 126. Succeeds. | 406 // Maximum-size update with size 126. Succeeds. |
408 HpackOutputStream output_stream; | 407 HpackOutputStream output_stream; |
409 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); | 408 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
410 output_stream.AppendUint32(126); | 409 output_stream.AppendUint32(126); |
411 | 410 |
412 output_stream.TakeString(&input); | 411 output_stream.TakeString(&input); |
413 EXPECT_TRUE(DecodeHeaderBlock(SpdyStringPiece(input))); | 412 EXPECT_TRUE(DecodeHeaderBlock(SpdyStringPiece(input))); |
414 EXPECT_EQ(126u, decoder_peer_.header_table_size_limit()); | 413 EXPECT_EQ(126u, decoder_peer_.header_table_size_limit()); |
415 } | 414 } |
(...skipping 16 matching lines...) Expand all Loading... |
432 | 431 |
433 output_stream.TakeString(&input); | 432 output_stream.TakeString(&input); |
434 EXPECT_FALSE(DecodeHeaderBlock(SpdyStringPiece(input))); | 433 EXPECT_FALSE(DecodeHeaderBlock(SpdyStringPiece(input))); |
435 EXPECT_EQ(kDefaultHeaderTableSizeSetting, | 434 EXPECT_EQ(kDefaultHeaderTableSizeSetting, |
436 decoder_peer_.header_table_size_limit()); | 435 decoder_peer_.header_table_size_limit()); |
437 } | 436 } |
438 } | 437 } |
439 | 438 |
440 // Two HeaderTableSizeUpdates may appear at the beginning of the block | 439 // Two HeaderTableSizeUpdates may appear at the beginning of the block |
441 TEST_P(HpackDecoder3Test, TwoTableSizeUpdates) { | 440 TEST_P(HpackDecoder3Test, TwoTableSizeUpdates) { |
442 string input; | 441 SpdyString input; |
443 { | 442 { |
444 // Should accept two table size updates, update to second one | 443 // Should accept two table size updates, update to second one |
445 HpackOutputStream output_stream; | 444 HpackOutputStream output_stream; |
446 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); | 445 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
447 output_stream.AppendUint32(0); | 446 output_stream.AppendUint32(0); |
448 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); | 447 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
449 output_stream.AppendUint32(122); | 448 output_stream.AppendUint32(122); |
450 | 449 |
451 output_stream.TakeString(&input); | 450 output_stream.TakeString(&input); |
452 EXPECT_TRUE(DecodeHeaderBlock(SpdyStringPiece(input))); | 451 EXPECT_TRUE(DecodeHeaderBlock(SpdyStringPiece(input))); |
453 EXPECT_EQ(122u, decoder_peer_.header_table_size_limit()); | 452 EXPECT_EQ(122u, decoder_peer_.header_table_size_limit()); |
454 } | 453 } |
455 } | 454 } |
456 | 455 |
457 // Three HeaderTableSizeUpdates should result in an error | 456 // Three HeaderTableSizeUpdates should result in an error |
458 TEST_P(HpackDecoder3Test, ThreeTableSizeUpdatesError) { | 457 TEST_P(HpackDecoder3Test, ThreeTableSizeUpdatesError) { |
459 string input; | 458 SpdyString input; |
460 { | 459 { |
461 // Should reject three table size updates, update to second one | 460 // Should reject three table size updates, update to second one |
462 HpackOutputStream output_stream; | 461 HpackOutputStream output_stream; |
463 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); | 462 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
464 output_stream.AppendUint32(5); | 463 output_stream.AppendUint32(5); |
465 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); | 464 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
466 output_stream.AppendUint32(10); | 465 output_stream.AppendUint32(10); |
467 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); | 466 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
468 output_stream.AppendUint32(15); | 467 output_stream.AppendUint32(15); |
469 | 468 |
470 output_stream.TakeString(&input); | 469 output_stream.TakeString(&input); |
471 | 470 |
472 EXPECT_FALSE(DecodeHeaderBlock(SpdyStringPiece(input))); | 471 EXPECT_FALSE(DecodeHeaderBlock(SpdyStringPiece(input))); |
473 EXPECT_EQ(10u, decoder_peer_.header_table_size_limit()); | 472 EXPECT_EQ(10u, decoder_peer_.header_table_size_limit()); |
474 } | 473 } |
475 } | 474 } |
476 | 475 |
477 // HeaderTableSizeUpdates may only appear at the beginning of the block | 476 // HeaderTableSizeUpdates may only appear at the beginning of the block |
478 // Any other updates should result in an error | 477 // Any other updates should result in an error |
479 TEST_P(HpackDecoder3Test, TableSizeUpdateSecondError) { | 478 TEST_P(HpackDecoder3Test, TableSizeUpdateSecondError) { |
480 string input; | 479 SpdyString input; |
481 { | 480 { |
482 // Should reject a table size update appearing after a different entry | 481 // Should reject a table size update appearing after a different entry |
483 // The table size should remain as the default | 482 // The table size should remain as the default |
484 HpackOutputStream output_stream; | 483 HpackOutputStream output_stream; |
485 output_stream.AppendBytes("\x82\x85"); | 484 output_stream.AppendBytes("\x82\x85"); |
486 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); | 485 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
487 output_stream.AppendUint32(123); | 486 output_stream.AppendUint32(123); |
488 | 487 |
489 output_stream.TakeString(&input); | 488 output_stream.TakeString(&input); |
490 | 489 |
491 EXPECT_FALSE(DecodeHeaderBlock(SpdyStringPiece(input))); | 490 EXPECT_FALSE(DecodeHeaderBlock(SpdyStringPiece(input))); |
492 EXPECT_EQ(kDefaultHeaderTableSizeSetting, | 491 EXPECT_EQ(kDefaultHeaderTableSizeSetting, |
493 decoder_peer_.header_table_size_limit()); | 492 decoder_peer_.header_table_size_limit()); |
494 } | 493 } |
495 } | 494 } |
496 | 495 |
497 // HeaderTableSizeUpdates may only appear at the beginning of the block | 496 // HeaderTableSizeUpdates may only appear at the beginning of the block |
498 // Any other updates should result in an error | 497 // Any other updates should result in an error |
499 TEST_P(HpackDecoder3Test, TableSizeUpdateFirstThirdError) { | 498 TEST_P(HpackDecoder3Test, TableSizeUpdateFirstThirdError) { |
500 string input; | 499 SpdyString input; |
501 { | 500 { |
502 // Should reject the second table size update | 501 // Should reject the second table size update |
503 // if a different entry appears after the first update | 502 // if a different entry appears after the first update |
504 // The table size should update to the first but not the second | 503 // The table size should update to the first but not the second |
505 HpackOutputStream output_stream; | 504 HpackOutputStream output_stream; |
506 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); | 505 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
507 output_stream.AppendUint32(60); | 506 output_stream.AppendUint32(60); |
508 output_stream.AppendBytes("\x82\x85"); | 507 output_stream.AppendBytes("\x82\x85"); |
509 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); | 508 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
510 output_stream.AppendUint32(125); | 509 output_stream.AppendUint32(125); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 // 41 | == Literal indexed == | 580 // 41 | == Literal indexed == |
582 // | Indexed name (idx = 1) | 581 // | Indexed name (idx = 1) |
583 // | :authority | 582 // | :authority |
584 // 8c | Literal value (len = 12) | 583 // 8c | Literal value (len = 12) |
585 // | Huffman encoded: | 584 // | Huffman encoded: |
586 // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... | 585 // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... |
587 // | Decoded: | 586 // | Decoded: |
588 // | www.example.com | 587 // | www.example.com |
589 // | -> :authority: www.example.com | 588 // | -> :authority: www.example.com |
590 | 589 |
591 string first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4ff"); | 590 SpdyString first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4ff"); |
592 EXPECT_TRUE(DecodeHeaderBlock(first)); | 591 EXPECT_TRUE(DecodeHeaderBlock(first)); |
593 first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4"); | 592 first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4"); |
594 EXPECT_FALSE(DecodeHeaderBlock(first)); | 593 EXPECT_FALSE(DecodeHeaderBlock(first)); |
595 } | 594 } |
596 | 595 |
597 TEST_P(HpackDecoder3Test, HuffmanEOSError) { | 596 TEST_P(HpackDecoder3Test, HuffmanEOSError) { |
598 // Literal value, Huffman encoded, but with an additional ff byte at the end | 597 // Literal value, Huffman encoded, but with an additional ff byte at the end |
599 // of the string, i.e. an EOS that is longer than permitted. | 598 // of the string, i.e. an EOS that is longer than permitted. |
600 // | 599 // |
601 // 41 | == Literal indexed == | 600 // 41 | == Literal indexed == |
602 // | Indexed name (idx = 1) | 601 // | Indexed name (idx = 1) |
603 // | :authority | 602 // | :authority |
604 // 8d | Literal value (len = 13) | 603 // 8d | Literal value (len = 13) |
605 // | Huffman encoded: | 604 // | Huffman encoded: |
606 // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... | 605 // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... |
607 // | Decoded: | 606 // | Decoded: |
608 // | www.example.com | 607 // | www.example.com |
609 // | -> :authority: www.example.com | 608 // | -> :authority: www.example.com |
610 | 609 |
611 string first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4ff"); | 610 SpdyString first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4ff"); |
612 EXPECT_TRUE(DecodeHeaderBlock(first)); | 611 EXPECT_TRUE(DecodeHeaderBlock(first)); |
613 first = a2b_hex("418df1e3c2e5f23a6ba0ab90f4ffff"); | 612 first = a2b_hex("418df1e3c2e5f23a6ba0ab90f4ffff"); |
614 EXPECT_FALSE(DecodeHeaderBlock(first)); | 613 EXPECT_FALSE(DecodeHeaderBlock(first)); |
615 } | 614 } |
616 | 615 |
617 // Round-tripping the header set from RFC 7541 C.3.1 should work. | 616 // Round-tripping the header set from RFC 7541 C.3.1 should work. |
618 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1 | 617 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1 |
619 TEST_P(HpackDecoder3Test, BasicC31) { | 618 TEST_P(HpackDecoder3Test, BasicC31) { |
620 HpackEncoder encoder(ObtainHpackHuffmanTable()); | 619 HpackEncoder encoder(ObtainHpackHuffmanTable()); |
621 | 620 |
622 SpdyHeaderBlock expected_header_set; | 621 SpdyHeaderBlock expected_header_set; |
623 expected_header_set[":method"] = "GET"; | 622 expected_header_set[":method"] = "GET"; |
624 expected_header_set[":scheme"] = "http"; | 623 expected_header_set[":scheme"] = "http"; |
625 expected_header_set[":path"] = "/"; | 624 expected_header_set[":path"] = "/"; |
626 expected_header_set[":authority"] = "www.example.com"; | 625 expected_header_set[":authority"] = "www.example.com"; |
627 | 626 |
628 string encoded_header_set; | 627 SpdyString encoded_header_set; |
629 EXPECT_TRUE( | 628 EXPECT_TRUE( |
630 encoder.EncodeHeaderSet(expected_header_set, &encoded_header_set)); | 629 encoder.EncodeHeaderSet(expected_header_set, &encoded_header_set)); |
631 | 630 |
632 EXPECT_TRUE(DecodeHeaderBlock(encoded_header_set)); | 631 EXPECT_TRUE(DecodeHeaderBlock(encoded_header_set)); |
633 EXPECT_EQ(expected_header_set, decoded_block()); | 632 EXPECT_EQ(expected_header_set, decoded_block()); |
634 } | 633 } |
635 | 634 |
636 // RFC 7541, Section C.4: Request Examples with Huffman Coding | 635 // RFC 7541, Section C.4: Request Examples with Huffman Coding |
637 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.4 | 636 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.4 |
638 TEST_P(HpackDecoder3Test, SectionC4RequestHuffmanExamples) { | 637 TEST_P(HpackDecoder3Test, SectionC4RequestHuffmanExamples) { |
(...skipping 10 matching lines...) Expand all Loading... |
649 // | -> :path: / | 648 // | -> :path: / |
650 // 41 | == Literal indexed == | 649 // 41 | == Literal indexed == |
651 // | Indexed name (idx = 1) | 650 // | Indexed name (idx = 1) |
652 // | :authority | 651 // | :authority |
653 // 8c | Literal value (len = 12) | 652 // 8c | Literal value (len = 12) |
654 // | Huffman encoded: | 653 // | Huffman encoded: |
655 // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... | 654 // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... |
656 // | Decoded: | 655 // | Decoded: |
657 // | www.example.com | 656 // | www.example.com |
658 // | -> :authority: www.example.com | 657 // | -> :authority: www.example.com |
659 string first = a2b_hex("828684418cf1e3c2e5f23a6ba0ab90f4ff"); | 658 SpdyString first = a2b_hex("828684418cf1e3c2e5f23a6ba0ab90f4ff"); |
660 const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first); | 659 const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first); |
661 | 660 |
662 EXPECT_THAT(first_header_set, | 661 EXPECT_THAT(first_header_set, |
663 ElementsAre( | 662 ElementsAre( |
664 // clang-format off | 663 // clang-format off |
665 Pair(":method", "GET"), | 664 Pair(":method", "GET"), |
666 Pair(":scheme", "http"), | 665 Pair(":scheme", "http"), |
667 Pair(":path", "/"), | 666 Pair(":path", "/"), |
668 Pair(":authority", "www.example.com"))); | 667 Pair(":authority", "www.example.com"))); |
669 // clang-format on | 668 // clang-format on |
(...skipping 16 matching lines...) Expand all Loading... |
686 // 58 | == Literal indexed == | 685 // 58 | == Literal indexed == |
687 // | Indexed name (idx = 24) | 686 // | Indexed name (idx = 24) |
688 // | cache-control | 687 // | cache-control |
689 // 86 | Literal value (len = 8) | 688 // 86 | Literal value (len = 8) |
690 // | Huffman encoded: | 689 // | Huffman encoded: |
691 // a8eb 1064 9cbf | ...d.. | 690 // a8eb 1064 9cbf | ...d.. |
692 // | Decoded: | 691 // | Decoded: |
693 // | no-cache | 692 // | no-cache |
694 // | -> cache-control: no-cache | 693 // | -> cache-control: no-cache |
695 | 694 |
696 string second = a2b_hex("828684be5886a8eb10649cbf"); | 695 SpdyString second = a2b_hex("828684be5886a8eb10649cbf"); |
697 const SpdyHeaderBlock& second_header_set = | 696 const SpdyHeaderBlock& second_header_set = |
698 DecodeBlockExpectingSuccess(second); | 697 DecodeBlockExpectingSuccess(second); |
699 | 698 |
700 EXPECT_THAT(second_header_set, | 699 EXPECT_THAT(second_header_set, |
701 ElementsAre( | 700 ElementsAre( |
702 // clang-format off | 701 // clang-format off |
703 Pair(":method", "GET"), | 702 Pair(":method", "GET"), |
704 Pair(":scheme", "http"), | 703 Pair(":scheme", "http"), |
705 Pair(":path", "/"), | 704 Pair(":path", "/"), |
706 Pair(":authority", "www.example.com"), | 705 Pair(":authority", "www.example.com"), |
(...skipping 21 matching lines...) Expand all Loading... |
728 // | Huffman encoded: | 727 // | Huffman encoded: |
729 // 25a8 49e9 5ba9 7d7f | %.I.[.}. | 728 // 25a8 49e9 5ba9 7d7f | %.I.[.}. |
730 // | Decoded: | 729 // | Decoded: |
731 // | custom-key | 730 // | custom-key |
732 // 89 | Literal value (len = 12) | 731 // 89 | Literal value (len = 12) |
733 // | Huffman encoded: | 732 // | Huffman encoded: |
734 // 25a8 49e9 5bb8 e8b4 bf | %.I.[.... | 733 // 25a8 49e9 5bb8 e8b4 bf | %.I.[.... |
735 // | Decoded: | 734 // | Decoded: |
736 // | custom-value | 735 // | custom-value |
737 // | -> custom-key: custom-value | 736 // | -> custom-key: custom-value |
738 string third = a2b_hex("828785bf408825a849e95ba97d7f8925a849e95bb8e8b4bf"); | 737 SpdyString third = |
| 738 a2b_hex("828785bf408825a849e95ba97d7f8925a849e95bb8e8b4bf"); |
739 const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third); | 739 const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third); |
740 | 740 |
741 EXPECT_THAT( | 741 EXPECT_THAT( |
742 third_header_set, | 742 third_header_set, |
743 ElementsAre( | 743 ElementsAre( |
744 // clang-format off | 744 // clang-format off |
745 Pair(":method", "GET"), | 745 Pair(":method", "GET"), |
746 Pair(":scheme", "https"), | 746 Pair(":scheme", "https"), |
747 Pair(":path", "/index.html"), | 747 Pair(":path", "/index.html"), |
748 Pair(":authority", "www.example.com"), | 748 Pair(":authority", "www.example.com"), |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 // | location | 797 // | location |
798 // 91 | Literal value (len = 23) | 798 // 91 | Literal value (len = 23) |
799 // | Huffman encoded: | 799 // | Huffman encoded: |
800 // 9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C | 800 // 9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C |
801 // d3 | . | 801 // d3 | . |
802 // | Decoded: | 802 // | Decoded: |
803 // | https://www.example.com | 803 // | https://www.example.com |
804 // | -> location: https://www.e | 804 // | -> location: https://www.e |
805 // | xample.com | 805 // | xample.com |
806 | 806 |
807 string first = a2b_hex( | 807 SpdyString first = a2b_hex( |
808 "488264025885aec3771a4b6196d07abe" | 808 "488264025885aec3771a4b6196d07abe" |
809 "941054d444a8200595040b8166e082a6" | 809 "941054d444a8200595040b8166e082a6" |
810 "2d1bff6e919d29ad171863c78f0b97c8" | 810 "2d1bff6e919d29ad171863c78f0b97c8" |
811 "e9ae82ae43d3"); | 811 "e9ae82ae43d3"); |
812 const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first); | 812 const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first); |
813 | 813 |
814 EXPECT_THAT(first_header_set, | 814 EXPECT_THAT(first_header_set, |
815 ElementsAre( | 815 ElementsAre( |
816 // clang-format off | 816 // clang-format off |
817 Pair(":status", "302"), | 817 Pair(":status", "302"), |
(...skipping 22 matching lines...) Expand all Loading... |
840 // | idx = 65 | 840 // | idx = 65 |
841 // | -> cache-control: private | 841 // | -> cache-control: private |
842 // c0 | == Indexed - Add == | 842 // c0 | == Indexed - Add == |
843 // | idx = 64 | 843 // | idx = 64 |
844 // | -> date: Mon, 21 Oct 2013 | 844 // | -> date: Mon, 21 Oct 2013 |
845 // | 20:13:21 GMT | 845 // | 20:13:21 GMT |
846 // bf | == Indexed - Add == | 846 // bf | == Indexed - Add == |
847 // | idx = 63 | 847 // | idx = 63 |
848 // | -> location: | 848 // | -> location: |
849 // | https://www.example.com | 849 // | https://www.example.com |
850 string second = a2b_hex("4883640effc1c0bf"); | 850 SpdyString second = a2b_hex("4883640effc1c0bf"); |
851 const SpdyHeaderBlock& second_header_set = | 851 const SpdyHeaderBlock& second_header_set = |
852 DecodeBlockExpectingSuccess(second); | 852 DecodeBlockExpectingSuccess(second); |
853 | 853 |
854 EXPECT_THAT(second_header_set, | 854 EXPECT_THAT(second_header_set, |
855 ElementsAre( | 855 ElementsAre( |
856 // clang-format off | 856 // clang-format off |
857 Pair(":status", "307"), | 857 Pair(":status", "307"), |
858 Pair("cache-control", "private"), | 858 Pair("cache-control", "private"), |
859 Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), | 859 Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), |
860 Pair("location", "https://www.example.com"))); | 860 Pair("location", "https://www.example.com"))); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
912 // | Decoded: | 912 // | Decoded: |
913 // | foo=ASDJKHQKBZXOQWEOPIUAXQ | 913 // | foo=ASDJKHQKBZXOQWEOPIUAXQ |
914 // | WEOIU; max-age=3600; versi | 914 // | WEOIU; max-age=3600; versi |
915 // | on=1 | 915 // | on=1 |
916 // | - evict: location: | 916 // | - evict: location: |
917 // | https://www.example.com | 917 // | https://www.example.com |
918 // | - evict: :status: 307 | 918 // | - evict: :status: 307 |
919 // | -> set-cookie: foo=ASDJKHQ | 919 // | -> set-cookie: foo=ASDJKHQ |
920 // | KBZXOQWEOPIUAXQWEOIU; | 920 // | KBZXOQWEOPIUAXQWEOIU; |
921 // | max-age=3600; version=1 | 921 // | max-age=3600; version=1 |
922 string third = a2b_hex( | 922 SpdyString third = a2b_hex( |
923 "88c16196d07abe941054d444a8200595" | 923 "88c16196d07abe941054d444a8200595" |
924 "040b8166e084a62d1bffc05a839bd9ab" | 924 "040b8166e084a62d1bffc05a839bd9ab" |
925 "77ad94e7821dd7f2e6c7b335dfdfcd5b" | 925 "77ad94e7821dd7f2e6c7b335dfdfcd5b" |
926 "3960d5af27087f3672c1ab270fb5291f" | 926 "3960d5af27087f3672c1ab270fb5291f" |
927 "9587316065c003ed4ee5b1063d5007"); | 927 "9587316065c003ed4ee5b1063d5007"); |
928 const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third); | 928 const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third); |
929 | 929 |
930 EXPECT_THAT(third_header_set, | 930 EXPECT_THAT(third_header_set, |
931 ElementsAre( | 931 ElementsAre( |
932 // clang-format off | 932 // clang-format off |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 SpdyHeaderBlock expected_header_set; | 993 SpdyHeaderBlock expected_header_set; |
994 expected_header_set.AppendValueOrAddHeader(name, value1); | 994 expected_header_set.AppendValueOrAddHeader(name, value1); |
995 expected_header_set.AppendValueOrAddHeader(name, value1); | 995 expected_header_set.AppendValueOrAddHeader(name, value1); |
996 expected_header_set.AppendValueOrAddHeader(name, value2); | 996 expected_header_set.AppendValueOrAddHeader(name, value2); |
997 expected_header_set.AppendValueOrAddHeader(name, value2); | 997 expected_header_set.AppendValueOrAddHeader(name, value2); |
998 expected_header_set.AppendValueOrAddHeader(name, value3); | 998 expected_header_set.AppendValueOrAddHeader(name, value3); |
999 expected_header_set.AppendValueOrAddHeader(name, value3); | 999 expected_header_set.AppendValueOrAddHeader(name, value3); |
1000 | 1000 |
1001 // SpdyHeaderBlock stores these 6 strings as '\0' separated values. | 1001 // SpdyHeaderBlock stores these 6 strings as '\0' separated values. |
1002 // Make sure that is what happened. | 1002 // Make sure that is what happened. |
1003 string joined_values = expected_header_set[name].as_string(); | 1003 SpdyString joined_values = expected_header_set[name].as_string(); |
1004 EXPECT_EQ(joined_values.size(), | 1004 EXPECT_EQ(joined_values.size(), |
1005 2 * value1.size() + 2 * value2.size() + 2 * value3.size() + 5); | 1005 2 * value1.size() + 2 * value2.size() + 2 * value3.size() + 5); |
1006 | 1006 |
1007 EXPECT_EQ(expected_header_set, decoded_block()); | 1007 EXPECT_EQ(expected_header_set, decoded_block()); |
1008 } | 1008 } |
1009 | 1009 |
1010 } // namespace | 1010 } // namespace |
1011 } // namespace test | 1011 } // namespace test |
1012 } // namespace net | 1012 } // namespace net |
OLD | NEW |