| Index: net/spdy/spdy_framer_test.cc
|
| diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
|
| index 30db38db5d3ebd0538f1431d59252f7b74bd0f3d..739d8085f8cf8c0e600d2e11220d2847b5eb8d53 100644
|
| --- a/net/spdy/spdy_framer_test.cc
|
| +++ b/net/spdy/spdy_framer_test.cc
|
| @@ -1535,6 +1535,39 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
|
| }
|
|
|
| {
|
| + const char kDescription[] = "'hello' data frame with padding, no FIN";
|
| + const unsigned char kV3FrameData[] = { // Also applies for V2.
|
| + 0x00, 0x00, 0x00, 0x01,
|
| + 0x00, 0x00, 0x00, 0x05,
|
| + 'h', 'e', 'l', 'l',
|
| + 'o'
|
| + };
|
| +
|
| + const unsigned char kV4FrameData[] = {
|
| + 0x00, 0x15, 0x00, 0x10, // Length = 13. PAD_LOW set.
|
| + 0x00, 0x00, 0x00, 0x01,
|
| + 0x07, // Pad Low field.
|
| + 'h', 'e', 'l', 'l', // Data
|
| + 'o',
|
| + '0', '0', '0', '0', // Padding
|
| + '0', '0', '0'
|
| + };
|
| + const char bytes[] = "hello";
|
| +
|
| + SpdyDataIR data_ir(1, StringPiece(bytes, strlen(bytes)));
|
| + // 7 zeros and the pad low field make the overal padding to be 8 bytes.
|
| + data_ir.set_padding_len(8);
|
| + scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
|
| + if (IsSpdy4()) {
|
| + CompareFrame(
|
| + kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
|
| + } else {
|
| + CompareFrame(
|
| + kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
|
| + }
|
| + }
|
| +
|
| + {
|
| const char kDescription[] = "Data frame with negative data byte, no FIN";
|
| const unsigned char kV3FrameData[] = { // Also applies for V2.
|
| 0x00, 0x00, 0x00, 0x01,
|
| @@ -3290,6 +3323,75 @@ TEST_P(SpdyFramerTest, ProcessSettingsAckFrame) {
|
| EXPECT_EQ(1, visitor.settings_ack_received_);
|
| }
|
|
|
| +
|
| +TEST_P(SpdyFramerTest, ProcessDataFrameWithPadding) {
|
| + if (spdy_version_ < 4) {
|
| + return;
|
| + }
|
| +
|
| + const int kPaddingLen = 512; // So we get two bytes for padding length field.
|
| + const char data_payload[] = "hello";
|
| +
|
| + testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
|
| + SpdyFramer framer(spdy_version_);
|
| + framer.set_visitor(&visitor);
|
| +
|
| + SpdyDataIR data_ir(1, StringPiece(data_payload, strlen(data_payload)));
|
| + data_ir.set_padding_len(kPaddingLen);
|
| + scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
|
| + ASSERT_TRUE(frame.get() != NULL);
|
| +
|
| + int bytes_consumed = 0;
|
| +
|
| + // Send the frame header.
|
| + EXPECT_CALL(visitor, OnDataFrameHeader(1,
|
| + kPaddingLen + strlen(data_payload),
|
| + false));
|
| + CHECK_EQ(8u, framer.ProcessInput(frame->data(), 8));
|
| + CHECK_EQ(framer.state(), SpdyFramer::SPDY_READ_PADDING_LENGTH);
|
| + CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
|
| + bytes_consumed += 8;
|
| +
|
| + // Send the first byte of the padding length field.
|
| + CHECK_EQ(1u, framer.ProcessInput(frame->data() + bytes_consumed, 1));
|
| + CHECK_EQ(framer.state(), SpdyFramer::SPDY_READ_PADDING_LENGTH);
|
| + CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
|
| + bytes_consumed += 1;
|
| +
|
| + // Send the second byte of the padding length field.
|
| + CHECK_EQ(1u, framer.ProcessInput(frame->data() + bytes_consumed, 1));
|
| + CHECK_EQ(framer.state(), SpdyFramer::SPDY_FORWARD_STREAM_FRAME);
|
| + CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
|
| + bytes_consumed += 1;
|
| +
|
| + // Send the first two bytes of the data payload.
|
| + EXPECT_CALL(visitor, OnStreamFrameData(1, _, 2, false));
|
| + CHECK_EQ(2u, framer.ProcessInput(frame->data() + bytes_consumed, 2));
|
| + CHECK_EQ(framer.state(), SpdyFramer::SPDY_FORWARD_STREAM_FRAME);
|
| + CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
|
| + bytes_consumed += 2;
|
| +
|
| + // Send the rest three bytes of the data payload.
|
| + EXPECT_CALL(visitor, OnStreamFrameData(1, _, 3, false));
|
| + CHECK_EQ(3u, framer.ProcessInput(frame->data() + bytes_consumed, 3));
|
| + CHECK_EQ(framer.state(), SpdyFramer::SPDY_CONSUME_PADDING);
|
| + CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
|
| + bytes_consumed += 3;
|
| +
|
| + // Send the first 100 bytes of the padding payload.
|
| + EXPECT_CALL(visitor, OnStreamFrameData(1, NULL, 100, false));
|
| + CHECK_EQ(100u, framer.ProcessInput(frame->data() + bytes_consumed, 100));
|
| + CHECK_EQ(framer.state(), SpdyFramer::SPDY_CONSUME_PADDING);
|
| + CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
|
| + bytes_consumed += 100;
|
| +
|
| + // Send rest of the padding payload.
|
| + EXPECT_CALL(visitor, OnStreamFrameData(1, NULL, 410, false));
|
| + CHECK_EQ(412u, framer.ProcessInput(frame->data() + bytes_consumed, 412));
|
| + CHECK_EQ(framer.state(), SpdyFramer::SPDY_READING_COMMON_HEADER);
|
| + CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
|
| +}
|
| +
|
| TEST_P(SpdyFramerTest, ReadWindowUpdate) {
|
| SpdyFramer framer(spdy_version_);
|
| scoped_ptr<SpdyFrame> control_frame(
|
| @@ -3892,7 +3994,11 @@ TEST_P(SpdyFramerTest, CatchProbableHttpResponse) {
|
| }
|
| }
|
|
|
| -TEST_P(SpdyFramerTest, DataFrameFlags) {
|
| +TEST_P(SpdyFramerTest, DataFrameFlagsV2V3) {
|
| + if (spdy_version_ >= 4) {
|
| + return;
|
| + }
|
| +
|
| for (int flags = 0; flags < 256; ++flags) {
|
| SCOPED_TRACE(testing::Message() << "Flags " << flags);
|
|
|
| @@ -3928,6 +4034,55 @@ TEST_P(SpdyFramerTest, DataFrameFlags) {
|
| }
|
| }
|
|
|
| +TEST_P(SpdyFramerTest, DataFrameFlagsV4) {
|
| + if (spdy_version_ < 4) {
|
| + return;
|
| + }
|
| +
|
| + uint8 valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT |
|
| + DATA_FLAG_PAD_LOW | DATA_FLAG_PAD_HIGH;
|
| +
|
| + for (int flags = 0; flags < 256; ++flags) {
|
| + SCOPED_TRACE(testing::Message() << "Flags " << flags);
|
| +
|
| + testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
|
| + SpdyFramer framer(spdy_version_);
|
| + framer.set_visitor(&visitor);
|
| +
|
| + net::SpdyDataIR data_ir(1, StringPiece("hello", 5));
|
| + scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
|
| + SetFrameFlags(frame.get(), flags, spdy_version_);
|
| +
|
| + if (flags & ~valid_data_flags) {
|
| + EXPECT_CALL(visitor, OnError(_));
|
| + } else {
|
| + EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, flags & DATA_FLAG_FIN));
|
| + if ((flags & DATA_FLAG_PAD_LOW) || (flags & DATA_FLAG_PAD_HIGH)) {
|
| + // Expect Error since we don't set pad_high and pad_low in payload.
|
| + EXPECT_CALL(visitor, OnError(_));
|
| + } else {
|
| + EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5, false));
|
| + if (flags & DATA_FLAG_FIN) {
|
| + EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true));
|
| + }
|
| + }
|
| + }
|
| +
|
| + framer.ProcessInput(frame->data(), frame->size());
|
| + if ((flags & ~valid_data_flags) || (flags & DATA_FLAG_PAD_LOW) ||
|
| + (flags & DATA_FLAG_PAD_HIGH)) {
|
| + EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
|
| + EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS,
|
| + framer.error_code())
|
| + << SpdyFramer::ErrorCodeToString(framer.error_code());
|
| + } else {
|
| + EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
|
| + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
|
| + << SpdyFramer::ErrorCodeToString(framer.error_code());
|
| + }
|
| + }
|
| +}
|
| +
|
| TEST_P(SpdyFramerTest, SynStreamFrameFlags) {
|
| for (int flags = 0; flags < 256; ++flags) {
|
| SCOPED_TRACE(testing::Message() << "Flags " << flags);
|
|
|