OLD | NEW |
---|---|
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_decoder.h" | 5 #include "net/spdy/hpack_decoder.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 | 92 |
93 void expectEntry(size_t index, size_t size, const string& name, | 93 void expectEntry(size_t index, size_t size, const string& name, |
94 const string& value) { | 94 const string& value) { |
95 HpackEntry* entry = decoder_peer_.header_table()->GetByIndex(index); | 95 HpackEntry* entry = decoder_peer_.header_table()->GetByIndex(index); |
96 EXPECT_EQ(name, entry->name()) << "index " << index; | 96 EXPECT_EQ(name, entry->name()) << "index " << index; |
97 EXPECT_EQ(value, entry->value()); | 97 EXPECT_EQ(value, entry->value()); |
98 EXPECT_EQ(size, entry->Size()); | 98 EXPECT_EQ(size, entry->Size()); |
99 EXPECT_EQ(index, decoder_peer_.header_table()->IndexOf(entry)); | 99 EXPECT_EQ(index, decoder_peer_.header_table()->IndexOf(entry)); |
100 } | 100 } |
101 | 101 |
102 void expectStaticEntry(size_t index) { | |
103 HpackEntry* entry = decoder_peer_.header_table()->GetByIndex(index); | |
104 EXPECT_TRUE(entry->IsStatic()) << "index " << index; | |
105 } | |
106 | |
107 HpackDecoder decoder_; | 102 HpackDecoder decoder_; |
108 test::HpackDecoderPeer decoder_peer_; | 103 test::HpackDecoderPeer decoder_peer_; |
109 }; | 104 }; |
110 | 105 |
111 TEST_F(HpackDecoderTest, HandleControlFrameHeadersData) { | 106 TEST_F(HpackDecoderTest, HandleControlFrameHeadersData) { |
112 // Strings under threshold are concatenated in the buffer. | 107 // Strings under threshold are concatenated in the buffer. |
113 EXPECT_TRUE(decoder_.HandleControlFrameHeadersData( | 108 EXPECT_TRUE(decoder_.HandleControlFrameHeadersData( |
114 0, "small string one", 16)); | 109 0, "small string one", 16)); |
115 EXPECT_TRUE(decoder_.HandleControlFrameHeadersData( | 110 EXPECT_TRUE(decoder_.HandleControlFrameHeadersData( |
116 0, "small string two", 16)); | 111 0, "small string two", 16)); |
117 // A string which would push the buffer over the threshold is refused. | 112 // A string which would push the buffer over the threshold is refused. |
118 EXPECT_FALSE(decoder_.HandleControlFrameHeadersData( | 113 EXPECT_FALSE(decoder_.HandleControlFrameHeadersData( |
119 0, "fails", kMaxDecodeBufferSize - 32 + 1)); | 114 0, "fails", kMaxDecodeBufferSize - 32 + 1)); |
120 | 115 |
121 EXPECT_EQ(decoder_peer_.headers_block_buffer(), | 116 EXPECT_EQ(decoder_peer_.headers_block_buffer(), |
122 "small string onesmall string two"); | 117 "small string onesmall string two"); |
123 } | 118 } |
124 | 119 |
125 TEST_F(HpackDecoderTest, HandleControlFrameHeadersComplete) { | 120 TEST_F(HpackDecoderTest, HandleControlFrameHeadersComplete) { |
126 // Decode a block which toggles two static headers into the reference set. | 121 // Decode a header block. Since there is no reference set, these header |
122 // fields should not show up in the next block unless explicitly encoded. | |
Johnny
2014/08/06 15:04:49
Can probably just strike all mentions of "referenc
Bence
2014/08/06 20:20:22
Should I also remove the next line?
EXPECT_TRUE(De
Johnny
2014/08/07 17:02:22
I'd probably move "\x82\x86" (corrected for the ri
Bence
2014/08/08 13:57:56
Done.
| |
127 EXPECT_TRUE(DecodeHeaderBlock("\x82\x86")); | 123 EXPECT_TRUE(DecodeHeaderBlock("\x82\x86")); |
128 | 124 |
129 decoder_peer_.set_cookie_value("foobar=baz"); | 125 decoder_peer_.set_cookie_value("foobar=baz"); |
130 | 126 |
131 // Headers in the reference set should be emitted. | |
132 // Incremental cookie buffer should be emitted and cleared. | 127 // Incremental cookie buffer should be emitted and cleared. |
133 decoder_.HandleControlFrameHeadersData(0, NULL, 0); | 128 decoder_.HandleControlFrameHeadersData(0, NULL, 0); |
134 decoder_.HandleControlFrameHeadersComplete(0); | 129 decoder_.HandleControlFrameHeadersComplete(0); |
135 | 130 |
136 EXPECT_THAT(decoded_block(), ElementsAre( | 131 EXPECT_THAT(decoded_block(), ElementsAre( |
137 Pair(":method", "GET"), | |
138 Pair(":path", "/index.html"), | |
139 Pair("cookie", "foobar=baz"))); | 132 Pair("cookie", "foobar=baz"))); |
140 EXPECT_EQ(decoder_peer_.cookie_value(), ""); | 133 EXPECT_EQ(decoder_peer_.cookie_value(), ""); |
141 } | 134 } |
142 | 135 |
143 TEST_F(HpackDecoderTest, HandleHeaderRepresentation) { | 136 TEST_F(HpackDecoderTest, HandleHeaderRepresentation) { |
144 // All cookie crumbs are joined. | 137 // All cookie crumbs are joined. |
145 decoder_peer_.HandleHeaderRepresentation("cookie", " part 1"); | 138 decoder_peer_.HandleHeaderRepresentation("cookie", " part 1"); |
146 decoder_peer_.HandleHeaderRepresentation("cookie", "part 2 "); | 139 decoder_peer_.HandleHeaderRepresentation("cookie", "part 2 "); |
147 decoder_peer_.HandleHeaderRepresentation("cookie", "part3"); | 140 decoder_peer_.HandleHeaderRepresentation("cookie", "part3"); |
148 | 141 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
212 // Decoding an encoded name with an invalid index should fail. | 205 // Decoding an encoded name with an invalid index should fail. |
213 TEST_F(HpackDecoderTest, DecodeNextNameInvalidIndex) { | 206 TEST_F(HpackDecoderTest, DecodeNextNameInvalidIndex) { |
214 // One more than the number of static table entries. | 207 // One more than the number of static table entries. |
215 HpackInputStream input_stream(kLiteralBound, "\x3e"); | 208 HpackInputStream input_stream(kLiteralBound, "\x3e"); |
216 | 209 |
217 StringPiece string_piece; | 210 StringPiece string_piece; |
218 EXPECT_FALSE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); | 211 EXPECT_FALSE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); |
219 } | 212 } |
220 | 213 |
221 // Decoding an indexed header should toggle the index's presence in | 214 // Decoding an indexed header should toggle the index's presence in |
222 // the reference set, making a copy of static table entries if | 215 // the reference set, making a copy of static table entries if |
Johnny
2014/08/06 15:04:50
Comment update.
Bence
2014/08/06 20:20:22
Done.
| |
223 // necessary. It should also emit the header if toggled on (and only | 216 // necessary. It should also emit the header if toggled on (and only |
224 // as many times as it was toggled on). | 217 // as many times as it was toggled on). |
225 TEST_F(HpackDecoderTest, IndexedHeaderBasic) { | 218 TEST_F(HpackDecoderTest, IndexedHeaderBasic) { |
226 // Toggle on static table entry #2 (and make a copy at index #1), | 219 // Reference static table entries #2 and #5. |
227 // then toggle on static table entry #5 (which is now #6 because of | |
228 // the copy of #2). | |
229 std::map<string, string> header_set1 = | 220 std::map<string, string> header_set1 = |
230 DecodeBlockExpectingSuccess("\x82\x86"); | 221 DecodeBlockExpectingSuccess("\x82\x85"); |
231 std::map<string, string> expected_header_set1; | 222 std::map<string, string> expected_header_set1; |
232 expected_header_set1[":method"] = "GET"; | 223 expected_header_set1[":method"] = "GET"; |
233 expected_header_set1[":path"] = "/index.html"; | 224 expected_header_set1[":path"] = "/index.html"; |
234 EXPECT_EQ(expected_header_set1, header_set1); | 225 EXPECT_EQ(expected_header_set1, header_set1); |
235 | 226 |
236 std::map<string, string> expected_header_set2; | 227 // Reference static table entry #2. |
237 expected_header_set2[":path"] = "/index.html"; | |
238 // Toggle off the copy of static table entry #5. | |
239 std::map<string, string> header_set2 = | 228 std::map<string, string> header_set2 = |
240 DecodeBlockExpectingSuccess("\x82"); | 229 DecodeBlockExpectingSuccess("\x82"); |
230 std::map<string, string> expected_header_set2; | |
231 expected_header_set2[":method"] = "GET"; | |
241 EXPECT_EQ(expected_header_set2, header_set2); | 232 EXPECT_EQ(expected_header_set2, header_set2); |
242 } | 233 } |
243 | 234 |
244 // Test a too-large indexed header. | 235 // Test a too-large indexed header. |
245 TEST_F(HpackDecoderTest, InvalidIndexedHeader) { | 236 TEST_F(HpackDecoderTest, InvalidIndexedHeader) { |
246 // High-bit set, and a prefix of one more than the number of static entries. | 237 // High-bit set, and a prefix of one more than the number of static entries. |
247 EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\xbe", 1))); | 238 EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\xbe", 1))); |
248 } | 239 } |
249 | 240 |
250 TEST_F(HpackDecoderTest, ContextUpdateMaximumSize) { | 241 TEST_F(HpackDecoderTest, ContextUpdateMaximumSize) { |
251 EXPECT_EQ(kDefaultHeaderTableSizeSetting, | 242 EXPECT_EQ(kDefaultHeaderTableSizeSetting, |
252 decoder_peer_.header_table()->max_size()); | 243 decoder_peer_.header_table()->max_size()); |
253 string input; | 244 string input; |
254 { | 245 { |
255 // Maximum-size update with size 126. Succeeds. | 246 // Maximum-size update with size 126. Succeeds. |
256 HpackOutputStream output_stream; | 247 HpackOutputStream output_stream; |
257 output_stream.AppendPrefix(kEncodingContextOpcode); | 248 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
258 output_stream.AppendPrefix(kEncodingContextNewMaximumSize); | |
259 output_stream.AppendUint32(126); | 249 output_stream.AppendUint32(126); |
260 | 250 |
261 output_stream.TakeString(&input); | 251 output_stream.TakeString(&input); |
262 EXPECT_TRUE(DecodeHeaderBlock(StringPiece(input))); | 252 EXPECT_TRUE(DecodeHeaderBlock(StringPiece(input))); |
263 EXPECT_EQ(126u, decoder_peer_.header_table()->max_size()); | 253 EXPECT_EQ(126u, decoder_peer_.header_table()->max_size()); |
264 } | 254 } |
265 { | 255 { |
266 // Maximum-size update with kDefaultHeaderTableSizeSetting. Succeeds. | 256 // Maximum-size update with kDefaultHeaderTableSizeSetting. Succeeds. |
267 HpackOutputStream output_stream; | 257 HpackOutputStream output_stream; |
268 output_stream.AppendPrefix(kEncodingContextOpcode); | 258 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
269 output_stream.AppendPrefix(kEncodingContextNewMaximumSize); | |
270 output_stream.AppendUint32(kDefaultHeaderTableSizeSetting); | 259 output_stream.AppendUint32(kDefaultHeaderTableSizeSetting); |
271 | 260 |
272 output_stream.TakeString(&input); | 261 output_stream.TakeString(&input); |
273 EXPECT_TRUE(DecodeHeaderBlock(StringPiece(input))); | 262 EXPECT_TRUE(DecodeHeaderBlock(StringPiece(input))); |
274 EXPECT_EQ(kDefaultHeaderTableSizeSetting, | 263 EXPECT_EQ(kDefaultHeaderTableSizeSetting, |
275 decoder_peer_.header_table()->max_size()); | 264 decoder_peer_.header_table()->max_size()); |
276 } | 265 } |
277 { | 266 { |
278 // Maximum-size update with kDefaultHeaderTableSizeSetting + 1. Fails. | 267 // Maximum-size update with kDefaultHeaderTableSizeSetting + 1. Fails. |
279 HpackOutputStream output_stream; | 268 HpackOutputStream output_stream; |
280 output_stream.AppendPrefix(kEncodingContextOpcode); | 269 output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); |
281 output_stream.AppendPrefix(kEncodingContextNewMaximumSize); | |
282 output_stream.AppendUint32(kDefaultHeaderTableSizeSetting + 1); | 270 output_stream.AppendUint32(kDefaultHeaderTableSizeSetting + 1); |
283 | 271 |
284 output_stream.TakeString(&input); | 272 output_stream.TakeString(&input); |
285 EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); | 273 EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); |
286 EXPECT_EQ(kDefaultHeaderTableSizeSetting, | 274 EXPECT_EQ(kDefaultHeaderTableSizeSetting, |
287 decoder_peer_.header_table()->max_size()); | 275 decoder_peer_.header_table()->max_size()); |
288 } | 276 } |
289 } | 277 } |
290 | 278 |
291 TEST_F(HpackDecoderTest, ContextUpdateClearReferenceSet) { | |
292 // Toggle on a couple of headers. | |
293 std::map<string, string> header_set1 = | |
294 DecodeBlockExpectingSuccess("\x82\x86"); | |
295 std::map<string, string> expected_header_set1; | |
296 expected_header_set1[":method"] = "GET"; | |
297 expected_header_set1[":path"] = "/index.html"; | |
298 EXPECT_EQ(expected_header_set1, header_set1); | |
299 | |
300 // Send a context update to clear the reference set. | |
301 std::map<string, string> header_set2 = | |
302 DecodeBlockExpectingSuccess("\x30"); | |
303 std::map<string, string> expected_header_set2; | |
304 EXPECT_EQ(expected_header_set2, header_set2); | |
305 } | |
306 | |
307 // Decoding two valid encoded literal headers with no indexing should | 279 // Decoding two valid encoded literal headers with no indexing should |
308 // work. | 280 // work. |
309 TEST_F(HpackDecoderTest, LiteralHeaderNoIndexing) { | 281 TEST_F(HpackDecoderTest, LiteralHeaderNoIndexing) { |
310 // First header with indexed name, second header with string literal | 282 // First header with indexed name, second header with string literal |
311 // name. | 283 // name. |
312 const char input[] = "\x04\x0c/sample/path\x00\x06:path2\x0e/sample/path/2"; | 284 const char input[] = "\x04\x0c/sample/path\x00\x06:path2\x0e/sample/path/2"; |
313 std::map<string, string> header_set = | 285 std::map<string, string> header_set = |
314 DecodeBlockExpectingSuccess(StringPiece(input, arraysize(input) - 1)); | 286 DecodeBlockExpectingSuccess(StringPiece(input, arraysize(input) - 1)); |
315 | 287 |
316 std::map<string, string> expected_header_set; | 288 std::map<string, string> expected_header_set; |
317 expected_header_set[":path"] = "/sample/path"; | 289 expected_header_set[":path"] = "/sample/path"; |
318 expected_header_set[":path2"] = "/sample/path/2"; | 290 expected_header_set[":path2"] = "/sample/path/2"; |
319 EXPECT_EQ(expected_header_set, header_set); | 291 EXPECT_EQ(expected_header_set, header_set); |
320 } | 292 } |
321 | 293 |
322 // Decoding two valid encoded literal headers with incremental | 294 // Decoding two valid encoded literal headers with incremental |
323 // indexing and string literal names should work and add the headers | 295 // indexing and string literal names should work. |
324 // to the reference set. | |
325 TEST_F(HpackDecoderTest, LiteralHeaderIncrementalIndexing) { | 296 TEST_F(HpackDecoderTest, LiteralHeaderIncrementalIndexing) { |
326 const char input[] = "\x44\x0c/sample/path\x40\x06:path2\x0e/sample/path/2"; | 297 const char input[] = "\x44\x0c/sample/path\x40\x06:path2\x0e/sample/path/2"; |
327 std::map<string, string> header_set = | 298 std::map<string, string> header_set = |
328 DecodeBlockExpectingSuccess(StringPiece(input, arraysize(input) - 1)); | 299 DecodeBlockExpectingSuccess(StringPiece(input, arraysize(input) - 1)); |
329 | 300 |
330 std::map<string, string> expected_header_set; | 301 std::map<string, string> expected_header_set; |
331 expected_header_set[":path"] = "/sample/path"; | 302 expected_header_set[":path"] = "/sample/path"; |
332 expected_header_set[":path2"] = "/sample/path/2"; | 303 expected_header_set[":path2"] = "/sample/path/2"; |
333 EXPECT_EQ(expected_header_set, header_set); | 304 EXPECT_EQ(expected_header_set, header_set); |
334 | |
335 // Decoding an empty string should just return the reference set. | |
336 std::map<string, string> header_set2 = DecodeBlockExpectingSuccess(""); | |
337 EXPECT_EQ(expected_header_set, header_set2); | |
338 } | 305 } |
339 | 306 |
340 TEST_F(HpackDecoderTest, LiteralHeaderWithIndexingInvalidNameIndex) { | 307 TEST_F(HpackDecoderTest, LiteralHeaderWithIndexingInvalidNameIndex) { |
341 decoder_.ApplyHeaderTableSizeSetting(0); | 308 decoder_.ApplyHeaderTableSizeSetting(0); |
342 | 309 |
343 // Name is the last static index. Works. | 310 // Name is the last static index. Works. |
344 EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x7d\x03ooo"))); | 311 EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x7d\x03ooo"))); |
345 // Name is one beyond the last static index. Fails. | 312 // Name is one beyond the last static index. Fails. |
346 EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x7e\x03ooo"))); | 313 EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x7e\x03ooo"))); |
347 } | 314 } |
(...skipping 23 matching lines...) Expand all Loading... | |
371 expected_header_set[":authority"] = "www.example.com"; | 338 expected_header_set[":authority"] = "www.example.com"; |
372 | 339 |
373 string encoded_header_set; | 340 string encoded_header_set; |
374 EXPECT_TRUE(encoder.EncodeHeaderSet( | 341 EXPECT_TRUE(encoder.EncodeHeaderSet( |
375 expected_header_set, &encoded_header_set)); | 342 expected_header_set, &encoded_header_set)); |
376 | 343 |
377 EXPECT_TRUE(DecodeHeaderBlock(encoded_header_set)); | 344 EXPECT_TRUE(DecodeHeaderBlock(encoded_header_set)); |
378 EXPECT_EQ(expected_header_set, decoded_block()); | 345 EXPECT_EQ(expected_header_set, decoded_block()); |
379 } | 346 } |
380 | 347 |
381 TEST_F(HpackDecoderTest, SectionD3RequestHuffmanExamples) { | 348 TEST_F(HpackDecoderTest, SectionD4RequestHuffmanExamples) { |
382 std::map<string, string> header_set; | 349 std::map<string, string> header_set; |
383 | 350 |
384 // 82 | == Indexed - Add == | 351 // 82 | == Indexed - Add == |
385 // | idx = 2 | 352 // | idx = 2 |
386 // | -> :method: GET | 353 // | -> :method: GET |
387 // 87 | == Indexed - Add == | |
388 // | idx = 7 | |
389 // | -> :scheme: http | |
390 // 86 | == Indexed - Add == | 354 // 86 | == Indexed - Add == |
391 // | idx = 6 | 355 // | idx = 6 |
356 // | -> :scheme: http | |
357 // 84 | == Indexed - Add == | |
358 // | idx = 4 | |
392 // | -> :path: / | 359 // | -> :path: / |
393 // 44 | == Literal indexed == | 360 // 41 | == Literal indexed == |
394 // | Indexed name (idx = 4) | 361 // | Indexed name (idx = 1) |
395 // | :authority | 362 // | :authority |
396 // 8c | Literal value (len = 15) | 363 // 8c | Literal value (len = 15) |
397 // | Huffman encoded: | 364 // | Huffman encoded: |
398 // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... | 365 // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... |
399 // | Decoded: | 366 // | Decoded: |
400 // | www.example.com | 367 // | www.example.com |
401 // | -> :authority: www.example.com | 368 // | -> :authority: www.example.com |
402 string first = a2b_hex("828786448cf1e3c2e5f23a6ba0ab90f4" | 369 string first = a2b_hex("828684418cf1e3c2e5f23a6ba0ab90f4" |
403 "ff"); | 370 "ff"); |
404 header_set = DecodeBlockExpectingSuccess(first); | 371 header_set = DecodeBlockExpectingSuccess(first); |
405 | 372 |
406 EXPECT_THAT(header_set, ElementsAre( | 373 EXPECT_THAT(header_set, ElementsAre( |
407 Pair(":authority", "www.example.com"), | 374 Pair(":authority", "www.example.com"), |
408 Pair(":method", "GET"), | 375 Pair(":method", "GET"), |
409 Pair(":path", "/"), | 376 Pair(":path", "/"), |
410 Pair(":scheme", "http"))); | 377 Pair(":scheme", "http"))); |
411 | 378 |
412 expectEntry(1, 57, ":authority", "www.example.com"); | 379 expectEntry(62, 57, ":authority", "www.example.com"); |
413 expectEntry(2, 38, ":path", "/"); | 380 EXPECT_EQ(57u, decoder_peer_.header_table()->size()); |
414 expectEntry(3, 43, ":scheme", "http"); | |
415 expectEntry(4, 42, ":method", "GET"); | |
416 expectStaticEntry(5); | |
417 EXPECT_EQ(180u, decoder_peer_.header_table()->size()); | |
418 | 381 |
419 // 5c | == Literal indexed == | 382 // 82 | == Indexed - Add == |
420 // | Indexed name (idx = 28) | 383 // | idx = 2 |
384 // | -> :method: GET | |
385 // 86 | == Indexed - Add == | |
386 // | idx = 6 | |
387 // | -> :scheme: http | |
388 // 84 | == Indexed - Add == | |
389 // | idx = 4 | |
390 // | -> :path: / | |
391 // be | == Indexed - Add == | |
392 // | idx = 62 | |
393 // | -> :authority: www.example\ | |
394 // | .com | |
395 // 58 | == Literal indexed == | |
396 // | Indexed name (idx = 24) | |
421 // | cache-control | 397 // | cache-control |
422 // 86 | Literal value (len = 8) | 398 // 86 | Literal value (len = 8) |
423 // | Huffman encoded: | 399 // | Huffman encoded: |
424 // a8eb 1064 9cbf | ...d.. | 400 // a8eb 1064 9cbf | ...d.. |
425 // | Decoded: | 401 // | Decoded: |
426 // | no-cache | 402 // | no-cache |
427 // | -> cache-control: no-cache | 403 // | -> cache-control: no-cache |
428 string second = a2b_hex("5c86a8eb10649cbf"); | 404 |
405 string second = a2b_hex("828684be5886a8eb10649cbf"); | |
429 header_set = DecodeBlockExpectingSuccess(second); | 406 header_set = DecodeBlockExpectingSuccess(second); |
430 | 407 |
431 EXPECT_THAT(header_set, ElementsAre( | 408 EXPECT_THAT(header_set, ElementsAre( |
432 Pair(":authority", "www.example.com"), | 409 Pair(":authority", "www.example.com"), |
433 Pair(":method", "GET"), | 410 Pair(":method", "GET"), |
434 Pair(":path", "/"), | 411 Pair(":path", "/"), |
435 Pair(":scheme", "http"), | 412 Pair(":scheme", "http"), |
436 Pair("cache-control", "no-cache"))); | 413 Pair("cache-control", "no-cache"))); |
437 | 414 |
438 expectEntry(1, 53, "cache-control", "no-cache"); | 415 expectEntry(62, 53, "cache-control", "no-cache"); |
439 expectEntry(2, 57, ":authority", "www.example.com"); | 416 expectEntry(63, 57, ":authority", "www.example.com"); |
440 expectEntry(3, 38, ":path", "/"); | 417 EXPECT_EQ(110u, decoder_peer_.header_table()->size()); |
441 expectEntry(4, 43, ":scheme", "http"); | |
442 expectEntry(5, 42, ":method", "GET"); | |
443 expectStaticEntry(6); | |
444 EXPECT_EQ(233u, decoder_peer_.header_table()->size()); | |
445 | 418 |
446 // 30 | == Empty reference set == | 419 // 82 | == Indexed - Add == |
447 // | idx = 0 | 420 // | idx = 2 |
448 // | flag = 1 | 421 // | -> :method: GET |
422 // 87 | == Indexed - Add == | |
423 // | idx = 7 | |
424 // | -> :scheme: https | |
449 // 85 | == Indexed - Add == | 425 // 85 | == Indexed - Add == |
450 // | idx = 5 | 426 // | idx = 5 |
451 // | -> :method: GET | |
452 // 8c | == Indexed - Add == | |
453 // | idx = 12 | |
454 // | -> :scheme: https | |
455 // 8b | == Indexed - Add == | |
456 // | idx = 11 | |
457 // | -> :path: /index.html | 427 // | -> :path: /index.html |
458 // 84 | == Indexed - Add == | 428 // bf | == Indexed - Add == |
459 // | idx = 4 | 429 // | idx = 63 |
460 // | -> :authority: www.example.com | 430 // | -> :authority: www.example\ |
431 // | .com | |
461 // 40 | == Literal indexed == | 432 // 40 | == Literal indexed == |
462 // 88 | Literal name (len = 10) | 433 // 88 | Literal name (len = 10) |
463 // | Huffman encoded: | 434 // | Huffman encoded: |
464 // 25a8 49e9 5ba9 7d7f | %.I.[.}. | 435 // 25a8 49e9 5ba9 7d7f | %.I.[.}. |
465 // | Decoded: | 436 // | Decoded: |
466 // | custom-key | 437 // | custom-key |
467 // 89 | Literal value (len = 12) | 438 // 89 | Literal value (len = 12) |
468 // | Huffman encoded: | 439 // | Huffman encoded: |
469 // 25a8 49e9 5bb8 e8b4 bf | %.I.[.... | 440 // 25a8 49e9 5bb8 e8b4 bf | %.I.[.... |
470 // | Decoded: | 441 // | Decoded: |
471 // | custom-value | 442 // | custom-value |
472 // | -> custom-key: custom-value | 443 // | -> custom-key: custom-value |
473 string third = a2b_hex("30858c8b84408825a849e95ba97d7f89" | 444 string third = a2b_hex("828785bf408825a849e95ba97d7f89" |
474 "25a849e95bb8e8b4bf"); | 445 "25a849e95bb8e8b4bf"); |
475 header_set = DecodeBlockExpectingSuccess(third); | 446 header_set = DecodeBlockExpectingSuccess(third); |
476 | 447 |
477 EXPECT_THAT(header_set, ElementsAre( | 448 EXPECT_THAT(header_set, ElementsAre( |
478 Pair(":authority", "www.example.com"), | 449 Pair(":authority", "www.example.com"), |
479 Pair(":method", "GET"), | 450 Pair(":method", "GET"), |
480 Pair(":path", "/index.html"), | 451 Pair(":path", "/index.html"), |
481 Pair(":scheme", "https"), | 452 Pair(":scheme", "https"), |
482 Pair("custom-key", "custom-value"))); | 453 Pair("custom-key", "custom-value"))); |
483 | 454 |
484 expectEntry(1, 54, "custom-key", "custom-value"); | 455 expectEntry(62, 54, "custom-key", "custom-value"); |
485 expectEntry(2, 48, ":path", "/index.html"); | 456 expectEntry(63, 53, "cache-control", "no-cache"); |
486 expectEntry(3, 44, ":scheme", "https"); | 457 expectEntry(64, 57, ":authority", "www.example.com"); |
487 expectEntry(4, 53, "cache-control", "no-cache"); | 458 EXPECT_EQ(164u, decoder_peer_.header_table()->size()); |
488 expectEntry(5, 57, ":authority", "www.example.com"); | |
489 expectEntry(6, 38, ":path", "/"); | |
490 expectEntry(7, 43, ":scheme", "http"); | |
491 expectEntry(8, 42, ":method", "GET"); | |
492 expectStaticEntry(9); | |
493 EXPECT_EQ(379u, decoder_peer_.header_table()->size()); | |
494 } | 459 } |
495 | 460 |
496 TEST_F(HpackDecoderTest, SectionD5ResponseHuffmanExamples) { | 461 TEST_F(HpackDecoderTest, SectionD6ResponseHuffmanExamples) { |
497 std::map<string, string> header_set; | 462 std::map<string, string> header_set; |
498 decoder_.ApplyHeaderTableSizeSetting(256); | 463 decoder_.ApplyHeaderTableSizeSetting(256); |
499 | 464 |
500 // 48 | == Literal indexed == | 465 // 48 | == Literal indexed == |
501 // | Indexed name (idx = 8) | 466 // | Indexed name (idx = 8) |
502 // | :status | 467 // | :status |
503 // 82 | Literal value (len = 3) | 468 // 82 | Literal value (len = 3) |
504 // | Huffman encoded: | 469 // | Huffman encoded: |
505 // 6402 | d. | 470 // 6402 | d. |
506 // | Decoded: | 471 // | Decoded: |
507 // | 302 | 472 // | 302 |
508 // | -> :status: 302 | 473 // | -> :status: 302 |
509 // 59 | == Literal indexed == | 474 // 58 | == Literal indexed == |
510 // | Indexed name (idx = 25) | 475 // | Indexed name (idx = 24) |
511 // | cache-control | 476 // | cache-control |
512 // 85 | Literal value (len = 7) | 477 // 85 | Literal value (len = 7) |
513 // | Huffman encoded: | 478 // | Huffman encoded: |
514 // aec3 771a 4b | ..w.K | 479 // aec3 771a 4b | ..w.K |
515 // | Decoded: | 480 // | Decoded: |
516 // | private | 481 // | private |
517 // | -> cache-control: private | 482 // | -> cache-control: private |
518 // 63 | == Literal indexed == | 483 // 61 | == Literal indexed == |
519 // | Indexed name (idx = 35) | 484 // | Indexed name (idx = 33) |
520 // | date | 485 // | date |
521 // 96 | Literal value (len = 29) | 486 // 96 | Literal value (len = 29) |
522 // | Huffman encoded: | 487 // | Huffman encoded: |
523 // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f | 488 // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f |
524 // e082 a62d 1bff | ...-.. | 489 // e082 a62d 1bff | ...-.. |
525 // | Decoded: | 490 // | Decoded: |
526 // | Mon, 21 Oct 2013 20:13:21 | 491 // | Mon, 21 Oct 2013 20:13:21 |
527 // | GMT | 492 // | GMT |
528 // | -> date: Mon, 21 Oct 2013 | 493 // | -> date: Mon, 21 Oct 2013 |
529 // | 20:13:21 GMT | 494 // | 20:13:21 GMT |
530 // 71 | == Literal indexed == | 495 // 6e | == Literal indexed == |
531 // | Indexed name (idx = 49) | 496 // | Indexed name (idx = 46) |
532 // | location | 497 // | location |
533 // 91 | Literal value (len = 23) | 498 // 91 | Literal value (len = 23) |
534 // | Huffman encoded: | 499 // | Huffman encoded: |
535 // 9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C | 500 // 9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C |
536 // d3 | . | 501 // d3 | . |
537 // | Decoded: | 502 // | Decoded: |
538 // | https://www.example.com | 503 // | https://www.example.com |
539 // | -> location: https://www.e | 504 // | -> location: https://www.e |
540 // | xample.com | 505 // | xample.com |
541 string first = a2b_hex("488264025985aec3771a4b6396d07abe" | 506 |
Johnny
2014/08/06 15:04:50
nit: examples have inconsistent newlines here.
Bence
2014/08/06 20:20:22
Done.
| |
507 string first = a2b_hex("488264025885aec3771a4b6196d07abe" | |
542 "941054d444a8200595040b8166e082a6" | 508 "941054d444a8200595040b8166e082a6" |
543 "2d1bff71919d29ad171863c78f0b97c8" | 509 "2d1bff6e919d29ad171863c78f0b97c8" |
544 "e9ae82ae43d3"); | 510 "e9ae82ae43d3"); |
545 header_set = DecodeBlockExpectingSuccess(first); | 511 header_set = DecodeBlockExpectingSuccess(first); |
546 | 512 |
547 EXPECT_THAT(header_set, ElementsAre( | 513 EXPECT_THAT(header_set, ElementsAre( |
548 Pair(":status", "302"), | 514 Pair(":status", "302"), |
549 Pair("cache-control", "private"), | 515 Pair("cache-control", "private"), |
550 Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), | 516 Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), |
551 Pair("location", "https://www.example.com"))); | 517 Pair("location", "https://www.example.com"))); |
552 | 518 |
553 expectEntry(1, 63, "location", "https://www.example.com"); | 519 expectEntry(62, 63, "location", "https://www.example.com"); |
554 expectEntry(2, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT"); | 520 expectEntry(63, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT"); |
555 expectEntry(3, 52, "cache-control", "private"); | 521 expectEntry(64, 52, "cache-control", "private"); |
556 expectEntry(4, 42, ":status", "302"); | 522 expectEntry(65, 42, ":status", "302"); |
557 expectStaticEntry(5); | |
558 EXPECT_EQ(222u, decoder_peer_.header_table()->size()); | 523 EXPECT_EQ(222u, decoder_peer_.header_table()->size()); |
559 | 524 |
560 // 8c | == Indexed - Add == | 525 // 48 | == Literal indexed == |
561 // | idx = 12 | 526 // | Indexed name (idx = 8) |
527 // | :status | |
528 // 83 | Literal value (len = 3) | |
529 // | Huffman encoded: | |
530 // 640e ff | d.. | |
531 // | Decoded: | |
532 // | 307 | |
562 // | - evict: :status: 302 | 533 // | - evict: :status: 302 |
563 // | -> :status: 200 | 534 // | -> :status: 307 |
564 string second = a2b_hex("8c"); | 535 // c1 | == Indexed - Add == |
536 // | idx = 65 | |
537 // | -> cache-control: private | |
538 // c0 | == Indexed - Add == | |
539 // | idx = 64 | |
540 // | -> date: Mon, 21 Oct 2013 \ | |
541 // | 20:13:21 GMT | |
542 // bf | == Indexed - Add == | |
543 // | idx = 63 | |
544 // | -> location: https://www.e\ | |
545 // | xample.com | |
546 string second = a2b_hex("4883640effc1c0bf"); | |
565 header_set = DecodeBlockExpectingSuccess(second); | 547 header_set = DecodeBlockExpectingSuccess(second); |
566 | 548 |
567 EXPECT_THAT(header_set, ElementsAre( | 549 EXPECT_THAT(header_set, ElementsAre( |
568 Pair(":status", "200"), | 550 Pair(":status", "307"), |
569 Pair("cache-control", "private"), | 551 Pair("cache-control", "private"), |
570 Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), | 552 Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), |
571 Pair("location", "https://www.example.com"))); | 553 Pair("location", "https://www.example.com"))); |
572 | 554 |
573 expectEntry(1, 42, ":status", "200"); | 555 expectEntry(62, 42, ":status", "307"); |
574 expectEntry(2, 63, "location", "https://www.example.com"); | 556 expectEntry(63, 63, "location", "https://www.example.com"); |
575 expectEntry(3, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT"); | 557 expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT"); |
576 expectEntry(4, 52, "cache-control", "private"); | 558 expectEntry(65, 52, "cache-control", "private"); |
577 expectStaticEntry(5); | |
578 EXPECT_EQ(222u, decoder_peer_.header_table()->size()); | 559 EXPECT_EQ(222u, decoder_peer_.header_table()->size()); |
579 | 560 |
580 // 84 | == Indexed - Remove == | 561 // 88 | == Indexed - Add == |
581 // | idx = 4 | 562 // | idx = 8 |
563 // | -> :status: 200 | |
564 // c1 | == Indexed - Add == | |
565 // | idx = 65 | |
582 // | -> cache-control: private | 566 // | -> cache-control: private |
583 // 84 | == Indexed - Add == | 567 // 61 | == Literal indexed == |
584 // | idx = 4 | 568 // | Indexed name (idx = 33) |
585 // | -> cache-control: private | |
586 // 43 | == Literal indexed == | |
587 // | Indexed name (idx = 3) | |
588 // | date | 569 // | date |
589 // 96 | Literal value (len = 29) | 570 // 96 | Literal value (len = 22) |
590 // | Huffman encoded: | 571 // | Huffman encoded: |
591 // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f | 572 // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f |
592 // e084 a62d 1bff | ...-.. | 573 // e084 a62d 1bff | ...-.. |
593 // | Decoded: | 574 // | Decoded: |
594 // | Mon, 21 Oct 2013 20:13:22 | 575 // | Mon, 21 Oct 2013 20:13:22 \ |
595 // | GMT | 576 // | GMT |
596 // | - evict: cache-control: pr | 577 // | - evict: cache-control: pr\ |
597 // | ivate | 578 // | ivate |
598 // | -> date: Mon, 21 Oct 2013 | 579 // | -> date: Mon, 21 Oct 2013 \ |
599 // | 20:13:22 GMT | 580 // | 20:13:22 GMT |
600 // 5e | == Literal indexed == | 581 // c0 | == Indexed - Add == |
601 // | Indexed name (idx = 30) | 582 // | idx = 64 |
583 // | -> location: https://www.e\ | |
584 // | xample.com | |
585 // 5a | == Literal indexed == | |
586 // | Indexed name (idx = 26) | |
602 // | content-encoding | 587 // | content-encoding |
603 // 83 | Literal value (len = 4) | 588 // 83 | Literal value (len = 3) |
604 // | Huffman encoded: | 589 // | Huffman encoded: |
605 // 9bd9 ab | ... | 590 // 9bd9 ab | ... |
606 // | Decoded: | 591 // | Decoded: |
607 // | gzip | 592 // | gzip |
608 // | - evict: date: Mon, 21 Oct | 593 // | - evict: date: Mon, 21 Oct\ |
609 // | 2013 20:13:21 GMT | 594 // | 2013 20:13:21 GMT |
610 // | -> content-encoding: gzip | 595 // | -> content-encoding: gzip |
611 // 84 | == Indexed - Remove == | 596 // 77 | == Literal indexed == |
612 // | idx = 4 | 597 // | Indexed name (idx = 55) |
613 // | -> location: https://www.e | |
614 // | xample.com | |
615 // 84 | == Indexed - Add == | |
616 // | idx = 4 | |
617 // | -> location: https://www.e | |
618 // | xample.com | |
619 // 83 | == Indexed - Remove == | |
620 // | idx = 3 | |
621 // | -> :status: 200 | |
622 // 83 | == Indexed - Add == | |
623 // | idx = 3 | |
624 // | -> :status: 200 | |
625 // 7b | == Literal indexed == | |
626 // | Indexed name (idx = 59) | |
627 // | set-cookie | 598 // | set-cookie |
628 // ad | Literal value (len = 56) | 599 // ad | Literal value (len = 45) |
629 // | Huffman encoded: | 600 // | Huffman encoded: |
630 // 94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 | .........5...[9` | 601 // 94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 | .........5...[9` |
631 // d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 | ..'..6r..'..)... | 602 // d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 | ..'..6r..'..)... |
632 // 3160 65c0 03ed 4ee5 b106 3d50 07 | 1`e...N...=P. | 603 // 3160 65c0 03ed 4ee5 b106 3d50 07 | 1`e...N...=P. |
633 // | Decoded: | 604 // | Decoded: |
634 // | foo=ASDJKHQKBZXOQWEOPIUAXQ | 605 // | foo=ASDJKHQKBZXOQWEOPIUAXQ\ |
635 // | WEOIU; max-age=3600; versi | 606 // | WEOIU; max-age=3600; versi\ |
636 // | on=1 | 607 // | on=1 |
637 // | - evict: location: https:/ | 608 // | - evict: location: https:/\ |
638 // | /www.example.com | 609 // | /www.example.com |
639 // | - evict: :status: 200 | 610 // | - evict: :status: 307 |
640 // | -> set-cookie: foo=ASDJKHQ | 611 // | -> set-cookie: foo=ASDJKHQ\ |
641 // | KBZXOQWEOPIUAXQWEOIU; ma | 612 // | KBZXOQWEOPIUAXQWEOIU; ma\ |
642 // | x-age=3600; version=1 | 613 // | x-age=3600; version=1 |
643 string third = a2b_hex("84844396d07abe941054d444a8200595" | 614 string third = a2b_hex("88c16196d07abe941054d444a8200595" |
644 "040b8166e084a62d1bff5e839bd9ab84" | 615 "040b8166e084a62d1bffc05a839bd9ab" |
645 "8483837bad94e7821dd7f2e6c7b335df" | 616 "77ad94e7821dd7f2e6c7b335dfdfcd5b" |
646 "dfcd5b3960d5af27087f3672c1ab270f" | 617 "3960d5af27087f3672c1ab270fb5291f" |
647 "b5291f9587316065c003ed4ee5b1063d" | 618 "9587316065c003ed4ee5b1063d5007"); |
648 "5007"); | |
649 header_set = DecodeBlockExpectingSuccess(third); | 619 header_set = DecodeBlockExpectingSuccess(third); |
650 | 620 |
651 EXPECT_THAT(header_set, ElementsAre( | 621 EXPECT_THAT(header_set, ElementsAre( |
652 Pair(":status", "200"), | 622 Pair(":status", "200"), |
653 Pair("cache-control", "private"), | 623 Pair("cache-control", "private"), |
654 Pair("content-encoding", "gzip"), | 624 Pair("content-encoding", "gzip"), |
655 Pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"), | 625 Pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"), |
656 Pair("location", "https://www.example.com"), | 626 Pair("location", "https://www.example.com"), |
657 Pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;" | 627 Pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;" |
658 " max-age=3600; version=1"))); | 628 " max-age=3600; version=1"))); |
659 | 629 |
660 expectEntry(1, 98, "set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;" | 630 expectEntry(62, 98, "set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;" |
661 " max-age=3600; version=1"); | 631 " max-age=3600; version=1"); |
662 expectEntry(2, 52, "content-encoding", "gzip"); | 632 expectEntry(63, 52, "content-encoding", "gzip"); |
663 expectEntry(3, 65, "date", "Mon, 21 Oct 2013 20:13:22 GMT"); | 633 expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:22 GMT"); |
664 expectStaticEntry(4); | |
665 EXPECT_EQ(215u, decoder_peer_.header_table()->size()); | 634 EXPECT_EQ(215u, decoder_peer_.header_table()->size()); |
666 } | 635 } |
667 | 636 |
668 } // namespace | 637 } // namespace |
669 | 638 |
670 } // namespace net | 639 } // namespace net |
OLD | NEW |