| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <iostream> | 6 #include <iostream> |
| 7 | 7 |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "net/spdy/spdy_framer.h" | 9 #include "net/spdy/spdy_framer.h" |
| 10 #include "net/spdy/spdy_protocol.h" | 10 #include "net/spdy/spdy_protocol.h" |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 public: | 289 public: |
| 290 virtual void TearDown() {} | 290 virtual void TearDown() {} |
| 291 | 291 |
| 292 protected: | 292 protected: |
| 293 void CompareFrame(const std::string& description, | 293 void CompareFrame(const std::string& description, |
| 294 const SpdyFrame& actual_frame, | 294 const SpdyFrame& actual_frame, |
| 295 const unsigned char* expected, | 295 const unsigned char* expected, |
| 296 const int expected_len) { | 296 const int expected_len) { |
| 297 const unsigned char* actual = | 297 const unsigned char* actual = |
| 298 reinterpret_cast<const unsigned char*>(actual_frame.data()); | 298 reinterpret_cast<const unsigned char*>(actual_frame.data()); |
| 299 int actual_len = actual_frame.length() + SpdyFrame::size(); | 299 int actual_len = actual_frame.length() + SpdyFrame::kHeaderSize; |
| 300 CompareCharArraysWithHexError( | 300 CompareCharArraysWithHexError( |
| 301 description, actual, actual_len, expected, expected_len); | 301 description, actual, actual_len, expected, expected_len); |
| 302 } | 302 } |
| 303 }; | 303 }; |
| 304 | 304 |
| 305 | 305 |
| 306 TEST(SpdyFrameBuilderTest, WriteLimits) { | 306 TEST(SpdyFrameBuilderTest, WriteLimits) { |
| 307 SpdyFrameBuilder builder(kLengthMask + 4); | 307 SpdyFrameBuilder builder(kLengthMask + 4); |
| 308 // length field should fail. | 308 // length field should fail. |
| 309 EXPECT_FALSE(builder.WriteBytes(reinterpret_cast<const void*>(0x1), | 309 EXPECT_FALSE(builder.WriteBytes(reinterpret_cast<const void*>(0x1), |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 frame.WriteUInt32(0); // Associated stream id | 392 frame.WriteUInt32(0); // Associated stream id |
| 393 frame.WriteUInt16(0); // Priority. | 393 frame.WriteUInt16(0); // Priority. |
| 394 | 394 |
| 395 frame.WriteUInt16(2); // Number of headers. | 395 frame.WriteUInt16(2); // Number of headers. |
| 396 SpdyHeaderBlock::iterator it; | 396 SpdyHeaderBlock::iterator it; |
| 397 frame.WriteString("gamma"); | 397 frame.WriteString("gamma"); |
| 398 frame.WriteString("gamma"); | 398 frame.WriteString("gamma"); |
| 399 frame.WriteString("alpha"); | 399 frame.WriteString("alpha"); |
| 400 frame.WriteString("alpha"); | 400 frame.WriteString("alpha"); |
| 401 // write the length | 401 // write the length |
| 402 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::size()); | 402 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize); |
| 403 | 403 |
| 404 SpdyHeaderBlock new_headers; | 404 SpdyHeaderBlock new_headers; |
| 405 scoped_ptr<SpdyFrame> control_frame(frame.take()); | 405 scoped_ptr<SpdyFrame> control_frame(frame.take()); |
| 406 SpdySynStreamControlFrame syn_frame(control_frame->data(), false); | 406 SpdySynStreamControlFrame syn_frame(control_frame->data(), false); |
| 407 std::string serialized_headers(syn_frame.header_block(), | 407 std::string serialized_headers(syn_frame.header_block(), |
| 408 syn_frame.header_block_len()); | 408 syn_frame.header_block_len()); |
| 409 SpdyFramer framer; | 409 SpdyFramer framer; |
| 410 framer.set_enable_compression(false); | 410 framer.set_enable_compression(false); |
| 411 EXPECT_TRUE(framer.ParseHeaderBlock(control_frame.get(), &new_headers)); | 411 EXPECT_TRUE(framer.ParseHeaderBlock(control_frame.get(), &new_headers)); |
| 412 } | 412 } |
| 413 | 413 |
| 414 TEST_F(SpdyFramerTest, WrongNumberOfHeaders) { | 414 TEST_F(SpdyFramerTest, WrongNumberOfHeaders) { |
| 415 SpdyFrameBuilder frame1; | 415 SpdyFrameBuilder frame1; |
| 416 SpdyFrameBuilder frame2; | 416 SpdyFrameBuilder frame2; |
| 417 | 417 |
| 418 // a frame with smaller number of actual headers | 418 // a frame with smaller number of actual headers |
| 419 frame1.WriteUInt16(kControlFlagMask | 1); | 419 frame1.WriteUInt16(kControlFlagMask | 1); |
| 420 frame1.WriteUInt16(SYN_STREAM); | 420 frame1.WriteUInt16(SYN_STREAM); |
| 421 frame1.WriteUInt32(0); // Placeholder for the length. | 421 frame1.WriteUInt32(0); // Placeholder for the length. |
| 422 frame1.WriteUInt32(3); // stream_id | 422 frame1.WriteUInt32(3); // stream_id |
| 423 frame1.WriteUInt16(0); // Priority. | 423 frame1.WriteUInt16(0); // Priority. |
| 424 | 424 |
| 425 frame1.WriteUInt16(1); // Wrong number of headers (underflow) | 425 frame1.WriteUInt16(1); // Wrong number of headers (underflow) |
| 426 frame1.WriteString("gamma"); | 426 frame1.WriteString("gamma"); |
| 427 frame1.WriteString("gamma"); | 427 frame1.WriteString("gamma"); |
| 428 frame1.WriteString("alpha"); | 428 frame1.WriteString("alpha"); |
| 429 frame1.WriteString("alpha"); | 429 frame1.WriteString("alpha"); |
| 430 // write the length | 430 // write the length |
| 431 frame1.WriteUInt32ToOffset(4, frame1.length() - SpdyFrame::size()); | 431 frame1.WriteUInt32ToOffset(4, frame1.length() - SpdyFrame::kHeaderSize); |
| 432 | 432 |
| 433 // a frame with larger number of actual headers | 433 // a frame with larger number of actual headers |
| 434 frame2.WriteUInt16(kControlFlagMask | 1); | 434 frame2.WriteUInt16(kControlFlagMask | 1); |
| 435 frame2.WriteUInt16(SYN_STREAM); | 435 frame2.WriteUInt16(SYN_STREAM); |
| 436 frame2.WriteUInt32(0); // Placeholder for the length. | 436 frame2.WriteUInt32(0); // Placeholder for the length. |
| 437 frame2.WriteUInt32(3); // stream_id | 437 frame2.WriteUInt32(3); // stream_id |
| 438 frame2.WriteUInt16(0); // Priority. | 438 frame2.WriteUInt16(0); // Priority. |
| 439 | 439 |
| 440 frame2.WriteUInt16(100); // Wrong number of headers (overflow) | 440 frame2.WriteUInt16(100); // Wrong number of headers (overflow) |
| 441 frame2.WriteString("gamma"); | 441 frame2.WriteString("gamma"); |
| 442 frame2.WriteString("gamma"); | 442 frame2.WriteString("gamma"); |
| 443 frame2.WriteString("alpha"); | 443 frame2.WriteString("alpha"); |
| 444 frame2.WriteString("alpha"); | 444 frame2.WriteString("alpha"); |
| 445 // write the length | 445 // write the length |
| 446 frame2.WriteUInt32ToOffset(4, frame2.length() - SpdyFrame::size()); | 446 frame2.WriteUInt32ToOffset(4, frame2.length() - SpdyFrame::kHeaderSize); |
| 447 | 447 |
| 448 SpdyHeaderBlock new_headers; | 448 SpdyHeaderBlock new_headers; |
| 449 scoped_ptr<SpdyFrame> syn_frame1(frame1.take()); | 449 scoped_ptr<SpdyFrame> syn_frame1(frame1.take()); |
| 450 scoped_ptr<SpdyFrame> syn_frame2(frame2.take()); | 450 scoped_ptr<SpdyFrame> syn_frame2(frame2.take()); |
| 451 SpdyFramer framer; | 451 SpdyFramer framer; |
| 452 framer.set_enable_compression(false); | 452 framer.set_enable_compression(false); |
| 453 EXPECT_FALSE(framer.ParseHeaderBlock(syn_frame1.get(), &new_headers)); | 453 EXPECT_FALSE(framer.ParseHeaderBlock(syn_frame1.get(), &new_headers)); |
| 454 EXPECT_FALSE(framer.ParseHeaderBlock(syn_frame2.get(), &new_headers)); | 454 EXPECT_FALSE(framer.ParseHeaderBlock(syn_frame2.get(), &new_headers)); |
| 455 } | 455 } |
| 456 | 456 |
| 457 TEST_F(SpdyFramerTest, DuplicateHeader) { | 457 TEST_F(SpdyFramerTest, DuplicateHeader) { |
| 458 // Frame builder with plentiful buffer size. | 458 // Frame builder with plentiful buffer size. |
| 459 SpdyFrameBuilder frame(1024); | 459 SpdyFrameBuilder frame(1024); |
| 460 | 460 |
| 461 frame.WriteUInt16(kControlFlagMask | 1); | 461 frame.WriteUInt16(kControlFlagMask | 1); |
| 462 frame.WriteUInt16(SYN_STREAM); | 462 frame.WriteUInt16(SYN_STREAM); |
| 463 frame.WriteUInt32(0); // Placeholder for the length. | 463 frame.WriteUInt32(0); // Placeholder for the length. |
| 464 frame.WriteUInt32(3); // stream_id | 464 frame.WriteUInt32(3); // stream_id |
| 465 frame.WriteUInt32(0); // associated stream id | 465 frame.WriteUInt32(0); // associated stream id |
| 466 frame.WriteUInt16(0); // Priority. | 466 frame.WriteUInt16(0); // Priority. |
| 467 | 467 |
| 468 frame.WriteUInt16(2); // Number of headers. | 468 frame.WriteUInt16(2); // Number of headers. |
| 469 SpdyHeaderBlock::iterator it; | 469 SpdyHeaderBlock::iterator it; |
| 470 frame.WriteString("name"); | 470 frame.WriteString("name"); |
| 471 frame.WriteString("value1"); | 471 frame.WriteString("value1"); |
| 472 frame.WriteString("name"); | 472 frame.WriteString("name"); |
| 473 frame.WriteString("value2"); | 473 frame.WriteString("value2"); |
| 474 // write the length | 474 // write the length |
| 475 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::size()); | 475 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize); |
| 476 | 476 |
| 477 SpdyHeaderBlock new_headers; | 477 SpdyHeaderBlock new_headers; |
| 478 scoped_ptr<SpdyFrame> control_frame(frame.take()); | 478 scoped_ptr<SpdyFrame> control_frame(frame.take()); |
| 479 SpdySynStreamControlFrame syn_frame(control_frame->data(), false); | 479 SpdySynStreamControlFrame syn_frame(control_frame->data(), false); |
| 480 std::string serialized_headers(syn_frame.header_block(), | 480 std::string serialized_headers(syn_frame.header_block(), |
| 481 syn_frame.header_block_len()); | 481 syn_frame.header_block_len()); |
| 482 SpdyFramer framer; | 482 SpdyFramer framer; |
| 483 framer.set_enable_compression(false); | 483 framer.set_enable_compression(false); |
| 484 // This should fail because duplicate headers are verboten by the spec. | 484 // This should fail because duplicate headers are verboten by the spec. |
| 485 EXPECT_FALSE(framer.ParseHeaderBlock(control_frame.get(), &new_headers)); | 485 EXPECT_FALSE(framer.ParseHeaderBlock(control_frame.get(), &new_headers)); |
| 486 } | 486 } |
| 487 | 487 |
| 488 TEST_F(SpdyFramerTest, MultiValueHeader) { | 488 TEST_F(SpdyFramerTest, MultiValueHeader) { |
| 489 // Frame builder with plentiful buffer size. | 489 // Frame builder with plentiful buffer size. |
| 490 SpdyFrameBuilder frame(1024); | 490 SpdyFrameBuilder frame(1024); |
| 491 | 491 |
| 492 frame.WriteUInt16(kControlFlagMask | 1); | 492 frame.WriteUInt16(kControlFlagMask | 1); |
| 493 frame.WriteUInt16(SYN_STREAM); | 493 frame.WriteUInt16(SYN_STREAM); |
| 494 frame.WriteUInt32(0); // Placeholder for the length. | 494 frame.WriteUInt32(0); // Placeholder for the length. |
| 495 frame.WriteUInt32(3); // stream_id | 495 frame.WriteUInt32(3); // stream_id |
| 496 frame.WriteUInt32(0); // associated stream id | 496 frame.WriteUInt32(0); // associated stream id |
| 497 frame.WriteUInt16(0); // Priority. | 497 frame.WriteUInt16(0); // Priority. |
| 498 | 498 |
| 499 frame.WriteUInt16(1); // Number of headers. | 499 frame.WriteUInt16(1); // Number of headers. |
| 500 SpdyHeaderBlock::iterator it; | 500 SpdyHeaderBlock::iterator it; |
| 501 frame.WriteString("name"); | 501 frame.WriteString("name"); |
| 502 std::string value("value1\0value2"); | 502 std::string value("value1\0value2"); |
| 503 frame.WriteString(value); | 503 frame.WriteString(value); |
| 504 // write the length | 504 // write the length |
| 505 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::size()); | 505 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize); |
| 506 | 506 |
| 507 SpdyHeaderBlock new_headers; | 507 SpdyHeaderBlock new_headers; |
| 508 scoped_ptr<SpdyFrame> control_frame(frame.take()); | 508 scoped_ptr<SpdyFrame> control_frame(frame.take()); |
| 509 SpdySynStreamControlFrame syn_frame(control_frame->data(), false); | 509 SpdySynStreamControlFrame syn_frame(control_frame->data(), false); |
| 510 std::string serialized_headers(syn_frame.header_block(), | 510 std::string serialized_headers(syn_frame.header_block(), |
| 511 syn_frame.header_block_len()); | 511 syn_frame.header_block_len()); |
| 512 SpdyFramer framer; | 512 SpdyFramer framer; |
| 513 framer.set_enable_compression(false); | 513 framer.set_enable_compression(false); |
| 514 EXPECT_TRUE(framer.ParseHeaderBlock(control_frame.get(), &new_headers)); | 514 EXPECT_TRUE(framer.ParseHeaderBlock(control_frame.get(), &new_headers)); |
| 515 EXPECT_TRUE(new_headers.find("name") != new_headers.end()); | 515 EXPECT_TRUE(new_headers.find("name") != new_headers.end()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 | 567 |
| 568 // Decompress the first frame | 568 // Decompress the first frame |
| 569 scoped_ptr<SpdyFrame> frame3(framer.DecompressFrame(*frame1.get())); | 569 scoped_ptr<SpdyFrame> frame3(framer.DecompressFrame(*frame1.get())); |
| 570 | 570 |
| 571 // Decompress the second frame | 571 // Decompress the second frame |
| 572 scoped_ptr<SpdyFrame> frame4(framer.DecompressFrame(*frame2.get())); | 572 scoped_ptr<SpdyFrame> frame4(framer.DecompressFrame(*frame2.get())); |
| 573 | 573 |
| 574 // Expect frames 3 & 4 to be the same. | 574 // Expect frames 3 & 4 to be the same. |
| 575 EXPECT_EQ(0, | 575 EXPECT_EQ(0, |
| 576 memcmp(frame3->data(), frame4->data(), | 576 memcmp(frame3->data(), frame4->data(), |
| 577 SpdyFrame::size() + frame3->length())); | 577 SpdyFrame::kHeaderSize + frame3->length())); |
| 578 | 578 |
| 579 // Expect frames 3 to be the same as a uncompressed frame created | 579 // Expect frames 3 to be the same as a uncompressed frame created |
| 580 // from scratch. | 580 // from scratch. |
| 581 scoped_ptr<SpdySynStreamControlFrame> | 581 scoped_ptr<SpdySynStreamControlFrame> |
| 582 uncompressed_frame(framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, | 582 uncompressed_frame(framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, |
| 583 false, &headers)); | 583 false, &headers)); |
| 584 EXPECT_EQ(frame3->length(), uncompressed_frame->length()); | 584 EXPECT_EQ(frame3->length(), uncompressed_frame->length()); |
| 585 EXPECT_EQ(0, | 585 EXPECT_EQ(0, |
| 586 memcmp(frame3->data(), uncompressed_frame->data(), | 586 memcmp(frame3->data(), uncompressed_frame->data(), |
| 587 SpdyFrame::size() + uncompressed_frame->length())); | 587 SpdyFrame::kHeaderSize + uncompressed_frame->length())); |
| 588 } | 588 } |
| 589 | 589 |
| 590 TEST_F(SpdyFramerTest, DecompressUncompressedFrame) { | 590 TEST_F(SpdyFramerTest, DecompressUncompressedFrame) { |
| 591 SpdyHeaderBlock headers; | 591 SpdyHeaderBlock headers; |
| 592 headers["server"] = "SpdyServer 1.0"; | 592 headers["server"] = "SpdyServer 1.0"; |
| 593 headers["date"] = "Mon 12 Jan 2009 12:12:12 PST"; | 593 headers["date"] = "Mon 12 Jan 2009 12:12:12 PST"; |
| 594 headers["status"] = "200"; | 594 headers["status"] = "200"; |
| 595 headers["version"] = "HTTP/1.1"; | 595 headers["version"] = "HTTP/1.1"; |
| 596 headers["content-type"] = "text/html"; | 596 headers["content-type"] = "text/html"; |
| 597 headers["content-length"] = "12"; | 597 headers["content-length"] = "12"; |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 send_framer.CreateDataFrame( | 874 send_framer.CreateDataFrame( |
| 875 1, bytes, arraysize(bytes), | 875 1, bytes, arraysize(bytes), |
| 876 DATA_FLAG_FIN)); | 876 DATA_FLAG_FIN)); |
| 877 EXPECT_TRUE(send_frame.get() != NULL); | 877 EXPECT_TRUE(send_frame.get() != NULL); |
| 878 | 878 |
| 879 // Run the inputs through the framer. | 879 // Run the inputs through the framer. |
| 880 TestSpdyVisitor visitor; | 880 TestSpdyVisitor visitor; |
| 881 visitor.use_compression_ = true; | 881 visitor.use_compression_ = true; |
| 882 const unsigned char* data; | 882 const unsigned char* data; |
| 883 data = reinterpret_cast<const unsigned char*>(syn_frame->data()); | 883 data = reinterpret_cast<const unsigned char*>(syn_frame->data()); |
| 884 visitor.SimulateInFramer(data, syn_frame->length() + SpdyFrame::size()); | 884 visitor.SimulateInFramer(data, syn_frame->length() + SpdyFrame::kHeaderSize); |
| 885 data = reinterpret_cast<const unsigned char*>(send_frame->data()); | 885 data = reinterpret_cast<const unsigned char*>(send_frame->data()); |
| 886 visitor.SimulateInFramer(data, send_frame->length() + SpdyFrame::size()); | 886 visitor.SimulateInFramer(data, send_frame->length() + SpdyFrame::kHeaderSize); |
| 887 | 887 |
| 888 EXPECT_EQ(0, visitor.error_count_); | 888 EXPECT_EQ(0, visitor.error_count_); |
| 889 EXPECT_EQ(1, visitor.syn_frame_count_); | 889 EXPECT_EQ(1, visitor.syn_frame_count_); |
| 890 EXPECT_EQ(0, visitor.syn_reply_frame_count_); | 890 EXPECT_EQ(0, visitor.syn_reply_frame_count_); |
| 891 EXPECT_EQ(0, visitor.headers_frame_count_); | 891 EXPECT_EQ(0, visitor.headers_frame_count_); |
| 892 EXPECT_EQ(arraysize(bytes), static_cast<unsigned>(visitor.data_bytes_)); | 892 EXPECT_EQ(arraysize(bytes), static_cast<unsigned>(visitor.data_bytes_)); |
| 893 EXPECT_EQ(0, visitor.fin_frame_count_); | 893 EXPECT_EQ(0, visitor.fin_frame_count_); |
| 894 EXPECT_EQ(0, visitor.fin_flag_count_); | 894 EXPECT_EQ(0, visitor.fin_flag_count_); |
| 895 EXPECT_EQ(1, visitor.zero_length_data_frame_count_); | 895 EXPECT_EQ(1, visitor.zero_length_data_frame_count_); |
| 896 // EXPECT_EQ(1, visitor.data_frame_count_); | 896 // EXPECT_EQ(1, visitor.data_frame_count_); |
| (...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1786 // to make sure we don't crash. | 1786 // to make sure we don't crash. |
| 1787 if (frame.get() != NULL) { | 1787 if (frame.get() != NULL) { |
| 1788 // Now that same header block should decompress just fine. | 1788 // Now that same header block should decompress just fine. |
| 1789 SpdyHeaderBlock new_headers; | 1789 SpdyHeaderBlock new_headers; |
| 1790 decompress_framer.ParseHeaderBlock(frame.get(), &new_headers); | 1790 decompress_framer.ParseHeaderBlock(frame.get(), &new_headers); |
| 1791 } | 1791 } |
| 1792 } | 1792 } |
| 1793 } | 1793 } |
| 1794 | 1794 |
| 1795 } // namespace | 1795 } // namespace |
| OLD | NEW |