| Index: net/spdy/spdy_framer_test.cc
|
| diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
|
| index 2a005bb946a6be1f56d64ed0ff4a7fb570576137..9c3ec4585805fdcf907f901413f116396d2eec99 100644
|
| --- a/net/spdy/spdy_framer_test.cc
|
| +++ b/net/spdy/spdy_framer_test.cc
|
| @@ -239,6 +239,8 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
|
| settings_ack_sent_(0),
|
| settings_ack_received_(0),
|
| continuation_count_(0),
|
| + altsvc_count_(0),
|
| + test_altsvc_ir_(0),
|
| last_window_update_stream_(0),
|
| last_window_update_delta_(0),
|
| last_push_promise_stream_(0),
|
| @@ -404,6 +406,23 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
|
| ++continuation_count_;
|
| }
|
|
|
| + virtual void OnAltSvc(SpdyStreamId stream_id,
|
| + uint32 max_age,
|
| + uint16 port,
|
| + StringPiece protocol_id,
|
| + StringPiece host,
|
| + StringPiece origin) OVERRIDE {
|
| + test_altsvc_ir_.set_stream_id(stream_id);
|
| + test_altsvc_ir_.set_max_age(max_age);
|
| + test_altsvc_ir_.set_port(port);
|
| + test_altsvc_ir_.set_protocol_id(protocol_id.as_string());
|
| + test_altsvc_ir_.set_host(host.as_string());
|
| + if (origin.length() > 0) {
|
| + test_altsvc_ir_.set_origin(origin.as_string());
|
| + }
|
| + ++altsvc_count_;
|
| + }
|
| +
|
| virtual void OnSendCompressedFrame(SpdyStreamId stream_id,
|
| SpdyFrameType type,
|
| size_t payload_len,
|
| @@ -474,6 +493,8 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
|
| int settings_ack_sent_;
|
| int settings_ack_received_;
|
| int continuation_count_;
|
| + int altsvc_count_;
|
| + SpdyAltSvcIR test_altsvc_ir_;
|
| SpdyStreamId last_window_update_stream_;
|
| uint32 last_window_update_delta_;
|
| SpdyStreamId last_push_promise_stream_;
|
| @@ -607,6 +628,7 @@ class SpdyFramerTest : public ::testing::TestWithParam<SpdyMajorVersion> {
|
| bool IsSpdy2() { return spdy_version_ == SPDY2; }
|
| bool IsSpdy3() { return spdy_version_ == SPDY3; }
|
| bool IsSpdy4() { return spdy_version_ == SPDY4; }
|
| + bool IsSpdy5() { return spdy_version_ == SPDY5; }
|
|
|
| // Version of SPDY protocol to be used.
|
| SpdyMajorVersion spdy_version_;
|
| @@ -2890,9 +2912,11 @@ TEST_P(SpdyFramerTest, SerializeBlocked) {
|
| SpdyFramer framer(spdy_version_);
|
|
|
| const char kDescription[] = "BLOCKED frame";
|
| + const char kType = static_cast<unsigned char>(
|
| + SpdyConstants::SerializeFrameType(spdy_version_, BLOCKED));
|
| const unsigned char kFrameData[] = {
|
| - 0x00, 0x00, 0x0a, 0x00,
|
| - 0x00, 0x00, 0x00, 0x00,
|
| + 0x00, 0x00, kType, 0x00,
|
| + 0x00, 0x00, 0x00, 0x00,
|
| };
|
| SpdyBlockedIR blocked_ir(0);
|
| scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(blocked_ir));
|
| @@ -2913,7 +2937,7 @@ TEST_P(SpdyFramerTest, CreateBlocked) {
|
| framer.SerializeBlocked(SpdyBlockedIR(kStreamId)));
|
| SpdyBlockedIR blocked_ir(kStreamId);
|
| scoped_ptr<SpdySerializedFrame> frame_created(
|
| - framer.SerializeFrame(blocked_ir));
|
| + framer.SerializeFrame(blocked_ir));
|
|
|
| CompareFrames(kDescription, *frame_serialized, *frame_created);
|
| }
|
| @@ -2946,6 +2970,36 @@ TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) {
|
| CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
|
| }
|
|
|
| +TEST_P(SpdyFramerTest, CreateAltSvc) {
|
| + if (spdy_version_ < SPDY4) {
|
| + return;
|
| + }
|
| +
|
| + SpdyFramer framer(spdy_version_);
|
| +
|
| + const char kDescription[] = "ALTSVC frame";
|
| + const char kType = static_cast<unsigned char>(
|
| + SpdyConstants::SerializeFrameType(spdy_version_, ALTSVC));
|
| + const unsigned char kFrameData[] = {
|
| + 0x00, 0x17, kType, 0x00,
|
| + 0x00, 0x00, 0x00, 0x03,
|
| + 0x00, 0x00, 0x00, 0x05,
|
| + 0x01, 0xbb, 0x00, 0x04, // Port = 443
|
| + 'p', 'i', 'd', '1', // Protocol-ID
|
| + 0x04, 'h', 'o', 's',
|
| + 't', 'o', 'r', 'i',
|
| + 'g', 'i', 'n',
|
| + };
|
| + SpdyAltSvcIR altsvc_ir(3);
|
| + altsvc_ir.set_max_age(5);
|
| + altsvc_ir.set_port(443);
|
| + altsvc_ir.set_protocol_id("pid1");
|
| + altsvc_ir.set_host("host");
|
| + altsvc_ir.set_origin("origin");
|
| + scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(altsvc_ir));
|
| + CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
|
| +}
|
| +
|
| TEST_P(SpdyFramerTest, ReadCompressedSynStreamHeaderBlock) {
|
| SpdyFramer framer(spdy_version_);
|
| SpdySynStreamIR syn_stream(1);
|
| @@ -4028,7 +4082,7 @@ TEST_P(SpdyFramerTest, ReadGarbageWithValidVersion) {
|
| TEST_P(SpdyFramerTest, SizesTest) {
|
| SpdyFramer framer(spdy_version_);
|
| EXPECT_EQ(8u, framer.GetDataFrameMinimumSize());
|
| - if (IsSpdy4()) {
|
| + if (IsSpdy4() || IsSpdy5()) {
|
| EXPECT_EQ(8u, framer.GetSynReplyMinimumSize());
|
| EXPECT_EQ(12u, framer.GetRstStreamMinimumSize());
|
| EXPECT_EQ(8u, framer.GetSettingsMinimumSize());
|
| @@ -4038,6 +4092,7 @@ TEST_P(SpdyFramerTest, SizesTest) {
|
| EXPECT_EQ(12u, framer.GetWindowUpdateSize());
|
| EXPECT_EQ(8u, framer.GetBlockedSize());
|
| EXPECT_EQ(12u, framer.GetPushPromiseMinimumSize());
|
| + EXPECT_EQ(17u, framer.GetAltSvcMinimumSize());
|
| EXPECT_EQ(8u, framer.GetFrameMinimumSize());
|
| EXPECT_EQ(16383u, framer.GetFrameMaximumSize());
|
| EXPECT_EQ(16375u, framer.GetDataFrameMaximumPayload());
|
| @@ -4085,9 +4140,12 @@ TEST_P(SpdyFramerTest, StateToStringTest) {
|
| EXPECT_STREQ("SPDY_SETTINGS_FRAME_PAYLOAD",
|
| SpdyFramer::StateToString(
|
| SpdyFramer::SPDY_SETTINGS_FRAME_PAYLOAD));
|
| + EXPECT_STREQ("SPDY_ALTSVC_FRAME_PAYLOAD",
|
| + SpdyFramer::StateToString(
|
| + SpdyFramer::SPDY_ALTSVC_FRAME_PAYLOAD));
|
| EXPECT_STREQ("UNKNOWN_STATE",
|
| SpdyFramer::StateToString(
|
| - SpdyFramer::SPDY_SETTINGS_FRAME_PAYLOAD + 1));
|
| + SpdyFramer::SPDY_ALTSVC_FRAME_PAYLOAD + 1));
|
| }
|
|
|
| TEST_P(SpdyFramerTest, ErrorCodeToStringTest) {
|
| @@ -4959,4 +5017,206 @@ TEST_P(SpdyFramerTest, OnBlocked) {
|
| << SpdyFramer::ErrorCodeToString(framer.error_code());
|
| }
|
|
|
| +TEST_P(SpdyFramerTest, OnAltSvc) {
|
| + if (spdy_version_ < SPDY4) {
|
| + return;
|
| + }
|
| +
|
| + const SpdyStreamId kStreamId = 1;
|
| +
|
| + testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
|
| + SpdyFramer framer(spdy_version_);
|
| + framer.set_visitor(&visitor);
|
| +
|
| + EXPECT_CALL(visitor, OnAltSvc(kStreamId,
|
| + 10,
|
| + 443,
|
| + StringPiece("pid"),
|
| + StringPiece("h1"),
|
| + StringPiece("o1")));
|
| +
|
| + SpdyAltSvcIR altsvc_ir(1);
|
| + altsvc_ir.set_max_age(10);
|
| + altsvc_ir.set_port(443);
|
| + altsvc_ir.set_protocol_id("pid");
|
| + altsvc_ir.set_host("h1");
|
| + altsvc_ir.set_origin("o1");
|
| + scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(altsvc_ir));
|
| + framer.ProcessInput(frame->data(), framer.GetAltSvcMinimumSize() +
|
| + altsvc_ir.protocol_id().length() +
|
| + altsvc_ir.host().length() +
|
| + altsvc_ir.origin().length());
|
| +
|
| + EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
|
| + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
|
| + << SpdyFramer::ErrorCodeToString(framer.error_code());
|
| +}
|
| +
|
| +TEST_P(SpdyFramerTest, OnAltSvcNoOrigin) {
|
| + if (spdy_version_ < SPDY4) {
|
| + return;
|
| + }
|
| +
|
| + const SpdyStreamId kStreamId = 1;
|
| +
|
| + testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
|
| + SpdyFramer framer(spdy_version_);
|
| + framer.set_visitor(&visitor);
|
| +
|
| + EXPECT_CALL(visitor, OnAltSvc(kStreamId,
|
| + 10,
|
| + 443,
|
| + StringPiece("pid"),
|
| + StringPiece("h1"),
|
| + StringPiece("")));
|
| +
|
| + SpdyAltSvcIR altsvc_ir(1);
|
| + altsvc_ir.set_max_age(10);
|
| + altsvc_ir.set_port(443);
|
| + altsvc_ir.set_protocol_id("pid");
|
| + altsvc_ir.set_host("h1");
|
| + scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(altsvc_ir));
|
| + framer.ProcessInput(frame->data(), framer.GetAltSvcMinimumSize() +
|
| + altsvc_ir.protocol_id().length() +
|
| + altsvc_ir.host().length());
|
| +
|
| + EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
|
| + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
|
| + << SpdyFramer::ErrorCodeToString(framer.error_code());
|
| +}
|
| +
|
| +TEST_P(SpdyFramerTest, OnAltSvcBadLengths) {
|
| + if (spdy_version_ < SPDY4) {
|
| + return;
|
| + }
|
| +
|
| + const char kType = static_cast<unsigned char>(
|
| + SpdyConstants::SerializeFrameType(spdy_version_, ALTSVC));
|
| + {
|
| + TestSpdyVisitor visitor(spdy_version_);
|
| + SpdyFramer framer(spdy_version_);
|
| + framer.set_visitor(&visitor);
|
| +
|
| + const unsigned char kFrameDataLargePIDLen[] = {
|
| + 0x00, 0x17, kType, 0x00,
|
| + 0x00, 0x00, 0x00, 0x03,
|
| + 0x00, 0x00, 0x00, 0x05,
|
| + 0x01, 0xbb, 0x00, 0x05, // Port = 443
|
| + 'p', 'i', 'd', '1', // Protocol-ID
|
| + 0x04, 'h', 'o', 's',
|
| + 't', 'o', 'r', 'i',
|
| + 'g', 'i', 'n',
|
| + };
|
| +
|
| + visitor.SimulateInFramer(kFrameDataLargePIDLen,
|
| + sizeof(kFrameDataLargePIDLen));
|
| + EXPECT_EQ(1, visitor.error_count_);
|
| + EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME,
|
| + visitor.framer_.error_code());
|
| + }
|
| +
|
| + {
|
| + TestSpdyVisitor visitor(spdy_version_);
|
| + SpdyFramer framer(spdy_version_);
|
| + framer.set_visitor(&visitor);
|
| + const unsigned char kFrameDataPIDLenLargerThanFrame[] = {
|
| + 0x00, 0x17, kType, 0x00,
|
| + 0x00, 0x00, 0x00, 0x03,
|
| + 0x00, 0x00, 0x00, 0x05,
|
| + 0x01, 0xbb, 0x00, 0x99, // Port = 443
|
| + 'p', 'i', 'd', '1', // Protocol-ID
|
| + 0x04, 'h', 'o', 's',
|
| + 't', 'o', 'r', 'i',
|
| + 'g', 'i', 'n',
|
| + };
|
| +
|
| + visitor.SimulateInFramer(kFrameDataPIDLenLargerThanFrame,
|
| + sizeof(kFrameDataPIDLenLargerThanFrame));
|
| + EXPECT_EQ(1, visitor.error_count_);
|
| + EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME,
|
| + visitor.framer_.error_code());
|
| + }
|
| +
|
| + {
|
| + TestSpdyVisitor visitor(spdy_version_);
|
| + SpdyFramer framer(spdy_version_);
|
| + framer.set_visitor(&visitor);
|
| +
|
| + const unsigned char kFrameDataLargeHostLen[] = {
|
| + 0x00, 0x17, kType, 0x00,
|
| + 0x00, 0x00, 0x00, 0x03,
|
| + 0x00, 0x00, 0x00, 0x05,
|
| + 0x01, 0xbb, 0x00, 0x04, // Port = 443
|
| + 'p', 'i', 'd', '1', // Protocol-ID
|
| + 0x0f, 'h', 'o', 's',
|
| + 't', 'o', 'r', 'i',
|
| + 'g', 'i', 'n',
|
| + };
|
| +
|
| + visitor.SimulateInFramer(kFrameDataLargeHostLen,
|
| + sizeof(kFrameDataLargeHostLen));
|
| + EXPECT_EQ(1, visitor.error_count_);
|
| + EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME,
|
| + visitor.framer_.error_code());
|
| + }
|
| +
|
| + {
|
| + TestSpdyVisitor visitor(spdy_version_);
|
| + SpdyFramer framer(spdy_version_);
|
| + framer.set_visitor(&visitor);
|
| + const unsigned char kFrameDataSmallPIDLen[] = {
|
| + 0x00, 0x17, kType, 0x00,
|
| + 0x00, 0x00, 0x00, 0x03,
|
| + 0x00, 0x00, 0x00, 0x05,
|
| + 0x01, 0xbb, 0x00, 0x01, // Port = 443
|
| + 'p', 'i', 'd', '1', // Protocol-ID
|
| + 0x04, 'h', 'o', 's',
|
| + 't', 'o', 'r', 'i',
|
| + 'g', 'i', 'n',
|
| + };
|
| +
|
| + visitor.SimulateInFramer(kFrameDataSmallPIDLen,
|
| + sizeof(kFrameDataSmallPIDLen));
|
| + EXPECT_EQ(1, visitor.error_count_);
|
| + EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME,
|
| + visitor.framer_.error_code());
|
| + }
|
| +}
|
| +
|
| +// Tests handling of ALTSVC frames delivered in small chunks.
|
| +TEST_P(SpdyFramerTest, ReadChunkedAltSvcFrame) {
|
| + if (spdy_version_ < SPDY4) {
|
| + return;
|
| + }
|
| + SpdyFramer framer(spdy_version_);
|
| + SpdyAltSvcIR altsvc_ir(1);
|
| + altsvc_ir.set_max_age(20);
|
| + altsvc_ir.set_port(443);
|
| + altsvc_ir.set_protocol_id("protocolid");
|
| + altsvc_ir.set_host("hostname");
|
| +
|
| + scoped_ptr<SpdyFrame> control_frame(framer.SerializeAltSvc(altsvc_ir));
|
| + TestSpdyVisitor visitor(spdy_version_);
|
| + visitor.use_compression_ = false;
|
| +
|
| + // Read data in small chunks.
|
| + size_t framed_data = 0;
|
| + size_t unframed_data = control_frame->size();
|
| + size_t kReadChunkSize = 5; // Read five bytes at a time.
|
| + while (unframed_data > 0) {
|
| + size_t to_read = min(kReadChunkSize, unframed_data);
|
| + visitor.SimulateInFramer(
|
| + reinterpret_cast<unsigned char*>(control_frame->data() + framed_data),
|
| + to_read);
|
| + unframed_data -= to_read;
|
| + framed_data += to_read;
|
| + }
|
| + EXPECT_EQ(0, visitor.error_count_);
|
| + EXPECT_EQ(1, visitor.altsvc_count_);
|
| + EXPECT_EQ(20u, visitor.test_altsvc_ir_.max_age());
|
| + EXPECT_EQ(443u, visitor.test_altsvc_ir_.port());
|
| + EXPECT_EQ("protocolid", visitor.test_altsvc_ir_.protocol_id());
|
| + EXPECT_EQ("hostname", visitor.test_altsvc_ir_.host());
|
| +}
|
| +
|
| } // namespace net
|
|
|