Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Unified Diff: net/spdy/spdy_framer_test.cc

Issue 246073007: SPDY & HPACK: Land recent internal changes (through 65328503) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase on upstream change: Expanded FRAME_TOO_LARGE/FRAME_SIZE_ERROR comment. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_framer.cc ('k') | net/spdy/spdy_protocol.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_framer_test.cc
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index 039f4de87093b7ed6bfd315f5d838cb68b326be1..8542835b67fdc00e256998568be205f6c14f5de7 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -11,6 +11,7 @@
#include "net/spdy/hpack_output_stream.h"
#include "net/spdy/mock_spdy_framer_visitor.h"
#include "net/spdy/spdy_frame_builder.h"
+#include "net/spdy/spdy_frame_reader.h"
#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_protocol.h"
#include "net/spdy/spdy_test_utils.h"
@@ -221,6 +222,8 @@ class SpdyFramerTestUtil {
class TestSpdyVisitor : public SpdyFramerVisitorInterface,
public SpdyFramerDebugVisitorInterface {
public:
+ // This is larger than our max frame size because header blocks that
+ // are too long can spill over into CONTINUATION frames.
static const size_t kDefaultHeaderBufferSize = 16 * 1024 * 1024;
explicit TestSpdyVisitor(SpdyMajorVersion version)
@@ -230,6 +233,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
syn_frame_count_(0),
syn_reply_frame_count_(0),
headers_frame_count_(0),
+ push_promise_frame_count_(0),
goaway_count_(0),
setting_count_(0),
settings_ack_sent_(0),
@@ -260,13 +264,13 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
virtual void OnError(SpdyFramer* f) OVERRIDE {
LOG(INFO) << "SpdyFramer Error: "
<< SpdyFramer::ErrorCodeToString(f->error_code());
- error_count_++;
+ ++error_count_;
}
virtual void OnDataFrameHeader(SpdyStreamId stream_id,
size_t length,
bool fin) OVERRIDE {
- data_frame_count_++;
+ ++data_frame_count_;
header_stream_id_ = stream_id;
}
@@ -300,7 +304,9 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
CHECK(header_buffer_valid_);
size_t parsed_length = framer_.ParseHeaderBlockInBuffer(
header_buffer_.get(), header_buffer_length_, &headers_);
- DCHECK_EQ(header_buffer_length_, parsed_length);
+ LOG_IF(DFATAL, header_buffer_length_ != parsed_length)
+ << "Check failed: header_buffer_length_ == parsed_length "
+ << "(" << header_buffer_length_ << " vs. " << parsed_length << ")";
return true;
}
const size_t available = header_buffer_size_ - header_buffer_length_;
@@ -318,24 +324,24 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
SpdyPriority priority,
bool fin,
bool unidirectional) OVERRIDE {
- syn_frame_count_++;
+ ++syn_frame_count_;
InitHeaderStreaming(SYN_STREAM, stream_id);
if (fin) {
- fin_flag_count_++;
+ ++fin_flag_count_;
}
}
virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE {
- syn_reply_frame_count_++;
+ ++syn_reply_frame_count_;
InitHeaderStreaming(SYN_REPLY, stream_id);
if (fin) {
- fin_flag_count_++;
+ ++fin_flag_count_;
}
}
virtual void OnRstStream(SpdyStreamId stream_id,
SpdyRstStreamStatus status) OVERRIDE {
- fin_frame_count_++;
+ ++fin_frame_count_;
}
virtual bool OnRstStreamFrameData(const char* rst_stream_data,
@@ -349,17 +355,17 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
virtual void OnSetting(SpdySettingsIds id,
uint8 flags,
uint32 value) OVERRIDE {
- setting_count_++;
+ ++setting_count_;
}
virtual void OnSettingsAck() OVERRIDE {
- DCHECK_GE(4, framer_.protocol_version());
- settings_ack_received_++;
+ DCHECK_LT(SPDY3, framer_.protocol_version());
+ ++settings_ack_received_;
}
virtual void OnSettingsEnd() OVERRIDE {
- if (framer_.protocol_version() < 4) { return; }
- settings_ack_sent_++;
+ if (framer_.protocol_version() <= SPDY3) { return; }
+ ++settings_ack_sent_;
}
virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {
@@ -368,14 +374,14 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
SpdyGoAwayStatus status) OVERRIDE {
- goaway_count_++;
+ ++goaway_count_;
}
virtual void OnHeaders(SpdyStreamId stream_id, bool fin, bool end) OVERRIDE {
- headers_frame_count_++;
+ ++headers_frame_count_;
InitHeaderStreaming(HEADERS, stream_id);
if (fin) {
- fin_flag_count_++;
+ ++fin_flag_count_;
}
}
@@ -388,13 +394,14 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
virtual void OnPushPromise(SpdyStreamId stream_id,
SpdyStreamId promised_stream_id,
bool end) OVERRIDE {
+ ++push_promise_frame_count_;
InitHeaderStreaming(PUSH_PROMISE, stream_id);
last_push_promise_stream_ = stream_id;
last_push_promise_promised_stream_ = promised_stream_id;
}
virtual void OnContinuation(SpdyStreamId stream_id, bool end) OVERRIDE {
- continuation_count_++;
+ ++continuation_count_;
}
virtual void OnSendCompressedFrame(SpdyStreamId stream_id,
@@ -461,6 +468,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
int syn_frame_count_;
int syn_reply_frame_count_;
int headers_frame_count_;
+ int push_promise_frame_count_;
int goaway_count_;
int setting_count_;
int settings_ack_sent_;
@@ -492,12 +500,39 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
SpdyHeaderBlock headers_;
};
-// Retrieves serialized headers from SYN_STREAM frame.
-// Does not check that the given frame is a SYN_STREAM.
+// Retrieves serialized headers from a HEADERS or SYN_STREAM frame.
base::StringPiece GetSerializedHeaders(const SpdyFrame* frame,
const SpdyFramer& framer) {
- return base::StringPiece(frame->data() + framer.GetSynStreamMinimumSize(),
- frame->size() - framer.GetSynStreamMinimumSize());
+ SpdyFrameReader reader(frame->data(), frame->size());
+ reader.Seek(2); // Seek past the frame length.
+ SpdyFrameType frame_type;
+ if (framer.protocol_version() > SPDY3) {
+ uint8 serialized_type;
+ reader.ReadUInt8(&serialized_type);
+ frame_type = SpdyConstants::ParseFrameType(framer.protocol_version(),
+ serialized_type);
+ DCHECK_EQ(HEADERS, frame_type);
+ uint8 flags;
+ reader.ReadUInt8(&flags);
+ if (flags & HEADERS_FLAG_PRIORITY) {
+ frame_type = SYN_STREAM;
+ }
+ } else {
+ uint16 serialized_type;
+ reader.ReadUInt16(&serialized_type);
+ frame_type = SpdyConstants::ParseFrameType(framer.protocol_version(),
+ serialized_type);
+ DCHECK(frame_type == HEADERS ||
+ frame_type == SYN_STREAM) << frame_type;
+ }
+
+ if (frame_type == SYN_STREAM) {
+ return StringPiece(frame->data() + framer.GetSynStreamMinimumSize(),
+ frame->size() - framer.GetSynStreamMinimumSize());
+ } else {
+ return StringPiece(frame->data() + framer.GetHeadersMinimumSize(),
+ frame->size() - framer.GetHeadersMinimumSize());
+ }
}
} // namespace test
@@ -517,7 +552,8 @@ class SpdyFramerTest : public ::testing::TestWithParam<SpdyMajorVersion> {
protected:
virtual void SetUp() {
spdy_version_ = GetParam();
- spdy_version_ch_ = static_cast<unsigned char>(spdy_version_);
+ spdy_version_ch_ = static_cast<unsigned char>(
+ SpdyConstants::SerializeMajorVersion(spdy_version_));
}
void CompareFrame(const string& description,
@@ -673,7 +709,7 @@ TEST_P(SpdyFramerTest, HeadersWithStreamIdZero) {
// Test that if we receive a PUSH_PROMISE with stream ID zero, we signal an
// error (but don't crash).
TEST_P(SpdyFramerTest, PushPromiseWithStreamIdZero) {
- if (spdy_version_ < SPDY4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -698,7 +734,7 @@ TEST_P(SpdyFramerTest, PushPromiseWithStreamIdZero) {
// Test that if we receive a PUSH_PROMISE with promised stream ID zero, we
// signal an error (but don't crash).
TEST_P(SpdyFramerTest, PushPromiseWithPromisedStreamIdZero) {
- if (spdy_version_ < SPDY4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -721,7 +757,7 @@ TEST_P(SpdyFramerTest, PushPromiseWithPromisedStreamIdZero) {
}
TEST_P(SpdyFramerTest, DuplicateHeader) {
- if (spdy_version_ >= 4) {
+ if (spdy_version_ > SPDY3) {
// TODO(jgraettinger): Punting on this because we haven't determined
// whether duplicate HPACK headers other than Cookie are an error.
// If they are, this will need to be updated to use HpackOutputStream.
@@ -729,14 +765,14 @@ TEST_P(SpdyFramerTest, DuplicateHeader) {
}
SpdyFramer framer(spdy_version_);
// Frame builder with plentiful buffer size.
- SpdyFrameBuilder frame(1024);
- if (spdy_version_ < 4) {
+ SpdyFrameBuilder frame(1024, spdy_version_);
+ if (spdy_version_ <= SPDY3) {
frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE);
frame.WriteUInt32(3); // stream_id
frame.WriteUInt32(0); // associated stream id
frame.WriteUInt16(0); // Priority.
} else {
- frame.WriteFramePrefix(framer, HEADERS, HEADERS_FLAG_PRIORITY, 3);
+ frame.BeginNewFrame(framer, HEADERS, HEADERS_FLAG_PRIORITY, 3);
frame.WriteUInt32(framer.GetHighestPriority());
}
@@ -770,17 +806,17 @@ TEST_P(SpdyFramerTest, DuplicateHeader) {
TEST_P(SpdyFramerTest, MultiValueHeader) {
SpdyFramer framer(spdy_version_);
// Frame builder with plentiful buffer size.
- SpdyFrameBuilder frame(1024);
- if (spdy_version_ < 4) {
+ SpdyFrameBuilder frame(1024, spdy_version_);
+ if (spdy_version_ <= SPDY3) {
frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE);
frame.WriteUInt32(3); // stream_id
frame.WriteUInt32(0); // associated stream id
frame.WriteUInt16(0); // Priority.
} else {
- frame.WriteFramePrefix(framer,
- HEADERS,
- HEADERS_FLAG_PRIORITY | HEADERS_FLAG_END_HEADERS,
- 3);
+ frame.BeginNewFrame(framer,
+ HEADERS,
+ HEADERS_FLAG_PRIORITY | HEADERS_FLAG_END_HEADERS,
+ 3);
frame.WriteUInt32(framer.GetHighestPriority());
}
@@ -789,11 +825,13 @@ TEST_P(SpdyFramerTest, MultiValueHeader) {
frame.WriteUInt16(1); // Number of headers.
frame.WriteString("name");
frame.WriteString(value);
- } else if (spdy_version_ >= 4) {
- HpackOutputStream output_stream(1024);
- output_stream.AppendLiteralHeaderNoIndexingWithName("name", value);
+ } else if (spdy_version_ > SPDY3) {
+ // TODO(jgraettinger): If this pattern appears again, move to test class.
+ std::map<string, string> header_set;
+ header_set["name"] = value;
string buffer;
- output_stream.TakeString(&buffer);
+ HpackEncoder encoder(ObtainHpackHuffmanTable());
+ encoder.EncodeHeaderSetWithoutCompression(header_set, &buffer);
frame.WriteBytes(&buffer[0], buffer.size());
} else {
frame.WriteUInt32(1); // Number of headers.
@@ -817,7 +855,7 @@ TEST_P(SpdyFramerTest, MultiValueHeader) {
}
TEST_P(SpdyFramerTest, BasicCompression) {
- if (spdy_version_ >= 4) {
+ if (spdy_version_ > SPDY3) {
// Deflate compression doesn't apply to HPACK.
return;
}
@@ -962,7 +1000,7 @@ TEST_P(SpdyFramerTest, Basic) {
0x80, spdy_version_ch_, 0x00, 0x03, // RST_STREAM on Stream #1
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, // RST_STREAM_CANCEL
0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
0x00, 0x00, 0x00, 0x00,
@@ -970,7 +1008,7 @@ TEST_P(SpdyFramerTest, Basic) {
0x80, spdy_version_ch_, 0x00, 0x03, // RST_STREAM on Stream #3
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, // RST_STREAM_CANCEL
};
const unsigned char kV3Input[] = {
@@ -1021,7 +1059,7 @@ TEST_P(SpdyFramerTest, Basic) {
0x80, spdy_version_ch_, 0x00, 0x03, // RST_STREAM on Stream #1
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, // RST_STREAM_CANCEL
0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
0x00, 0x00, 0x00, 0x00,
@@ -1029,7 +1067,7 @@ TEST_P(SpdyFramerTest, Basic) {
0x80, spdy_version_ch_, 0x00, 0x03, // RST_STREAM on Stream #3
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, // RST_STREAM_CANCEL
};
// SYN_STREAM doesn't exist in SPDY4, so instead we send
@@ -1066,14 +1104,14 @@ TEST_P(SpdyFramerTest, Basic) {
0x00, 0x04, 0x03, 0x00, // RST_STREAM on Stream #1
0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, // RST_STREAM_CANCEL
0x00, 0x00, 0x00, 0x00, // DATA on Stream #3
0x00, 0x00, 0x00, 0x03,
0x00, 0x0f, 0x03, 0x00, // RST_STREAM on Stream #3
0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, // RST_STREAM_CANCEL
0x52, 0x45, 0x53, 0x45, // opaque data
0x54, 0x53, 0x54, 0x52,
0x45, 0x41, 0x4d,
@@ -1292,7 +1330,7 @@ TEST_P(SpdyFramerTest, FinOnSynReplyFrame) {
}
TEST_P(SpdyFramerTest, HeaderCompression) {
- if (spdy_version_ >= 4) {
+ if (spdy_version_ > SPDY3) {
// Deflate compression doesn't apply to HPACK.
return;
}
@@ -1376,7 +1414,7 @@ TEST_P(SpdyFramerTest, UnclosedStreamDataCompressors) {
EXPECT_TRUE(syn_frame.get() != NULL);
StringPiece bytes = "this is a test test test test test!";
- net::SpdyDataIR data_ir(1, bytes);
+ SpdyDataIR data_ir(1, bytes);
data_ir.set_fin(true);
scoped_ptr<SpdyFrame> send_frame(send_framer.SerializeData(data_ir));
EXPECT_TRUE(send_frame.get() != NULL);
@@ -1420,7 +1458,7 @@ TEST_P(SpdyFramerTest, UnclosedStreamDataCompressorsOneByteAtATime) {
EXPECT_TRUE(syn_frame.get() != NULL);
const char bytes[] = "this is a test test test test test!";
- net::SpdyDataIR data_ir(1, StringPiece(bytes, arraysize(bytes)));
+ SpdyDataIR data_ir(1, StringPiece(bytes, arraysize(bytes)));
data_ir.set_fin(true);
scoped_ptr<SpdyFrame> send_frame(send_framer.SerializeData(data_ir));
EXPECT_TRUE(send_frame.get() != NULL);
@@ -1454,7 +1492,7 @@ TEST_P(SpdyFramerTest, UnclosedStreamDataCompressorsOneByteAtATime) {
TEST_P(SpdyFramerTest, WindowUpdateFrame) {
SpdyFramer framer(spdy_version_);
scoped_ptr<SpdyFrame> frame(framer.SerializeWindowUpdate(
- net::SpdyWindowUpdateIR(1, 0x12345678)));
+ SpdyWindowUpdateIR(1, 0x12345678)));
const char kDescription[] = "WINDOW_UPDATE frame, stream 1, delta 0x12345678";
const unsigned char kV3FrameData[] = { // Also applies for V2.
@@ -1507,7 +1545,69 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
SpdyDataIR data_header_ir(1);
data_header_ir.SetDataShallow(base::StringPiece(bytes, strlen(bytes)));
- frame.reset(framer.SerializeDataFrameHeader(data_header_ir));
+ frame.reset(framer.SerializeDataFrameHeaderWithPaddingLengthField(
+ data_header_ir));
+ CompareCharArraysWithHexError(
+ kDescription,
+ reinterpret_cast<const unsigned char*>(frame->data()),
+ framer.GetDataFrameMinimumSize(),
+ IsSpdy4() ? kV4FrameData : kV3FrameData,
+ framer.GetDataFrameMinimumSize());
+ }
+
+ {
+ const char kDescription[] = "'hello' data frame with more 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[] = {
+ 0x01, 0x0b, 0x00, 0x30, // Length = 267. PAD_HIGH and PAD_LOW set.
+ 0x00, 0x00, 0x00, 0x01,
+ 0x01, 0x04, // Pad Low and Pad High fields.
+ 'h', 'e', 'l', 'l', // Data
+ 'o',
+ // Padding of 260 zeros (so both PAD_HIGH and PAD_LOW fields are used).
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ };
+ const char bytes[] = "hello";
+
+ SpdyDataIR data_ir(1, StringPiece(bytes, strlen(bytes)));
+ // 260 zeros and the pad low/high fields make the overall padding to be 262
+ // bytes.
+ data_ir.set_padding_len(262);
+ scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+ if (IsSpdy4()) {
+ CompareFrame(
+ kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
+ } else {
+ CompareFrame(
+ kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+ }
+
+ frame.reset(framer.SerializeDataFrameHeaderWithPaddingLengthField(data_ir));
CompareCharArraysWithHexError(
kDescription,
reinterpret_cast<const unsigned char*>(frame->data()),
@@ -1517,7 +1617,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
}
{
- const char kDescription[] = "'hello' data frame with padding, no FIN";
+ const char kDescription[] = "'hello' data frame with few padding, no FIN";
const unsigned char kV3FrameData[] = { // Also applies for V2.
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x05,
@@ -1537,7 +1637,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
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.
+ // 7 zeros and the pad low field make the overall padding to be 8 bytes.
data_ir.set_padding_len(8);
scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
if (IsSpdy4()) {
@@ -1550,6 +1650,47 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
}
{
+ const char kDescription[] =
+ "'hello' data frame with 1 byte 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, 0x06, 0x00, 0x10, // Length = 6. PAD_LOW set.
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, // Pad Low field.
+ 'h', 'e', 'l', 'l', // Data
+ 'o',
+ };
+ const char bytes[] = "hello";
+
+ SpdyDataIR data_ir(1, StringPiece(bytes, strlen(bytes)));
+ // The pad low field itself is used for the 1-byte padding and no padding
+ // payload is needed.
+ data_ir.set_padding_len(1);
+ scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+ if (IsSpdy4()) {
+ CompareFrame(
+ kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
+ } else {
+ CompareFrame(
+ kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+ }
+
+ frame.reset(framer.SerializeDataFrameHeaderWithPaddingLengthField(data_ir));
+ CompareCharArraysWithHexError(
+ kDescription,
+ reinterpret_cast<const unsigned char*>(frame->data()),
+ framer.GetDataFrameMinimumSize(),
+ IsSpdy4() ? kV4FrameData : kV3FrameData,
+ framer.GetDataFrameMinimumSize());
+ }
+
+ {
const char kDescription[] = "Data frame with negative data byte, no FIN";
const unsigned char kV3FrameData[] = { // Also applies for V2.
0x00, 0x00, 0x00, 0x01,
@@ -1561,7 +1702,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
0x00, 0x00, 0x00, 0x01,
0xff
};
- net::SpdyDataIR data_ir(1, StringPiece("\xff", 1));
+ SpdyDataIR data_ir(1, StringPiece("\xff", 1));
scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
if (IsSpdy4()) {
CompareFrame(
@@ -1586,7 +1727,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
'h', 'e', 'l', 'l',
'o'
};
- net::SpdyDataIR data_ir(1, StringPiece("hello", 5));
+ SpdyDataIR data_ir(1, StringPiece("hello", 5));
data_ir.set_fin(true);
scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
if (IsSpdy4()) {
@@ -1608,7 +1749,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
};
- net::SpdyDataIR data_ir(1, StringPiece());
+ SpdyDataIR data_ir(1, StringPiece());
scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
if (IsSpdy4()) {
CompareFrame(
@@ -1617,6 +1758,14 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
CompareFrame(
kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
}
+
+ frame.reset(framer.SerializeDataFrameHeaderWithPaddingLengthField(data_ir));
+ CompareCharArraysWithHexError(
+ kDescription,
+ reinterpret_cast<const unsigned char*>(frame->data()),
+ framer.GetDataFrameMinimumSize(),
+ IsSpdy4() ? kV4FrameData : kV3FrameData,
+ framer.GetDataFrameMinimumSize());
}
{
@@ -1633,7 +1782,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
'h', 'e', 'l', 'l',
'o'
};
- net::SpdyDataIR data_ir(0x7fffffff, "hello");
+ SpdyDataIR data_ir(0x7fffffff, "hello");
data_ir.set_fin(true);
scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
if (IsSpdy4()) {
@@ -1662,7 +1811,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) {
memcpy(expected_frame_data.get(), kFrameHeader, arraysize(kFrameHeader));
memset(expected_frame_data.get() + arraysize(kFrameHeader), 'A', kDataSize);
- net::SpdyDataIR data_ir(1, StringPiece(kData.data(), kData.size()));
+ SpdyDataIR data_ir(1, StringPiece(kData.data(), kData.size()));
data_ir.set_fin(true);
scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
CompareFrame(kDescription, *frame, expected_frame_data.get(), kFrameSize);
@@ -2136,7 +2285,7 @@ TEST_P(SpdyFramerTest, CreateRstStream) {
0x00, 0x00, 0x00, 0x01,
0x52, 0x53, 0x54
};
- net::SpdyRstStreamIR rst_stream(1, RST_STREAM_PROTOCOL_ERROR, "RST");
+ SpdyRstStreamIR rst_stream(1, RST_STREAM_PROTOCOL_ERROR, "RST");
scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
if (IsSpdy4()) {
CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
@@ -2158,9 +2307,9 @@ TEST_P(SpdyFramerTest, CreateRstStream) {
0x7f, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x01,
};
- net::SpdyRstStreamIR rst_stream(0x7FFFFFFF,
- RST_STREAM_PROTOCOL_ERROR,
- "");
+ SpdyRstStreamIR rst_stream(0x7FFFFFFF,
+ RST_STREAM_PROTOCOL_ERROR,
+ "");
scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
if (IsSpdy4()) {
CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
@@ -2182,9 +2331,9 @@ TEST_P(SpdyFramerTest, CreateRstStream) {
0x7f, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x06,
};
- net::SpdyRstStreamIR rst_stream(0x7FFFFFFF,
- RST_STREAM_INTERNAL_ERROR,
- "");
+ SpdyRstStreamIR rst_stream(0x7FFFFFFF,
+ RST_STREAM_INTERNAL_ERROR,
+ "");
scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
if (IsSpdy4()) {
CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
@@ -2680,7 +2829,7 @@ TEST_P(SpdyFramerTest, CreateWindowUpdate) {
0x00, 0x00, 0x00, 0x01,
};
scoped_ptr<SpdyFrame> frame(
- framer.SerializeWindowUpdate(net::SpdyWindowUpdateIR(1, 1)));
+ framer.SerializeWindowUpdate(SpdyWindowUpdateIR(1, 1)));
if (IsSpdy4()) {
CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
} else {
@@ -2702,7 +2851,7 @@ TEST_P(SpdyFramerTest, CreateWindowUpdate) {
0x00, 0x00, 0x00, 0x01,
};
scoped_ptr<SpdyFrame> frame(framer.SerializeWindowUpdate(
- net::SpdyWindowUpdateIR(0x7FFFFFFF, 1)));
+ SpdyWindowUpdateIR(0x7FFFFFFF, 1)));
if (IsSpdy4()) {
CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
} else {
@@ -2724,7 +2873,7 @@ TEST_P(SpdyFramerTest, CreateWindowUpdate) {
0x7f, 0xff, 0xff, 0xff,
};
scoped_ptr<SpdyFrame> frame(framer.SerializeWindowUpdate(
- net::SpdyWindowUpdateIR(1, 0x7FFFFFFF)));
+ SpdyWindowUpdateIR(1, 0x7FFFFFFF)));
if (IsSpdy4()) {
CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
} else {
@@ -2769,13 +2918,13 @@ TEST_P(SpdyFramerTest, CreateBlocked) {
CompareFrames(kDescription, *frame_serialized, *frame_created);
}
-TEST_P(SpdyFramerTest, CreatePushPromise) {
+TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) {
if (spdy_version_ < SPDY4) {
return;
}
SpdyFramer framer(spdy_version_);
-
+ framer.set_enable_compression(false);
const char kDescription[] = "PUSH_PROMISE frame";
const unsigned char kFrameData[] = {
@@ -2888,7 +3037,7 @@ TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) {
}
TEST_P(SpdyFramerTest, ControlFrameAtMaxSizeLimit) {
- if (spdy_version_ >= 4) {
+ if (spdy_version_ > SPDY3) {
// TODO(jgraettinger): This test setup doesn't work with HPACK.
return;
}
@@ -2923,7 +3072,7 @@ TEST_P(SpdyFramerTest, ControlFrameAtMaxSizeLimit) {
}
TEST_P(SpdyFramerTest, ControlFrameTooLarge) {
- if (spdy_version_ >= 4) {
+ if (spdy_version_ > SPDY3) {
// TODO(jgraettinger): This test setup doesn't work with HPACK.
return;
}
@@ -2963,6 +3112,63 @@ TEST_P(SpdyFramerTest, ControlFrameTooLarge) {
EXPECT_EQ(0u, visitor.header_buffer_length_);
}
+TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) {
+ if (spdy_version_ < SPDY4) {
+ return;
+ }
+ SpdyFramer framer(spdy_version_);
+ framer.set_enable_compression(false);
+ SpdyHeadersIR headers(1);
+
+ // Exact payload length will change with HPACK, but this should be long
+ // enough to cause an overflow.
+ const size_t kBigValueSize = framer.GetControlFrameBufferMaxSize();
+ string big_value(kBigValueSize, 'x');
+ headers.SetHeader("aa", big_value.c_str());
+ scoped_ptr<SpdyFrame> control_frame(framer.SerializeHeaders(headers));
+ EXPECT_TRUE(control_frame.get() != NULL);
+ EXPECT_GT(control_frame->size(), framer.GetControlFrameBufferMaxSize());
+
+ TestSpdyVisitor visitor(spdy_version_);
+ visitor.SimulateInFramer(
+ reinterpret_cast<unsigned char*>(control_frame->data()),
+ control_frame->size());
+ EXPECT_TRUE(visitor.header_buffer_valid_);
+ EXPECT_EQ(0, visitor.error_count_);
+ EXPECT_EQ(1, visitor.headers_frame_count_);
+ EXPECT_EQ(1, visitor.continuation_count_);
+ EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
+}
+
+TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) {
+ if (spdy_version_ < SPDY4) {
+ return;
+ }
+ SpdyFramer framer(spdy_version_);
+ framer.set_enable_compression(false);
+ SpdyPushPromiseIR push_promise(1, 2);
+
+ // Exact payload length will change with HPACK, but this should be long
+ // enough to cause an overflow.
+ const size_t kBigValueSize = framer.GetControlFrameBufferMaxSize();
+ string big_value(kBigValueSize, 'x');
+ push_promise.SetHeader("aa", big_value.c_str());
+ scoped_ptr<SpdyFrame> control_frame(
+ framer.SerializePushPromise(push_promise));
+ EXPECT_TRUE(control_frame.get() != NULL);
+ EXPECT_GT(control_frame->size(), framer.GetControlFrameBufferMaxSize());
+
+ TestSpdyVisitor visitor(spdy_version_);
+ visitor.SimulateInFramer(
+ reinterpret_cast<unsigned char*>(control_frame->data()),
+ control_frame->size());
+ EXPECT_TRUE(visitor.header_buffer_valid_);
+ EXPECT_EQ(0, visitor.error_count_);
+ EXPECT_EQ(1, visitor.push_promise_frame_count_);
+ EXPECT_EQ(1, visitor.continuation_count_);
+ EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
+}
+
// Check that the framer stops delivering header data chunks once the visitor
// declares it doesn't want any more. This is important to guard against
// "zip bomb" types of attacks.
@@ -3007,7 +3213,7 @@ TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) {
}
TEST_P(SpdyFramerTest, DecompressCorruptHeaderBlock) {
- if (spdy_version_ >= 4) {
+ if (spdy_version_ > SPDY3) {
// Deflate compression doesn't apply to HPACK.
return;
}
@@ -3086,7 +3292,7 @@ TEST_P(SpdyFramerTest, ReadZeroLenSettingsFrame) {
visitor.SimulateInFramer(
reinterpret_cast<unsigned char*>(control_frame->data()),
framer.GetControlFrameHeaderSize());
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
// Should generate an error, since zero-len settings frames are unsupported.
EXPECT_EQ(1, visitor.error_count_);
} else {
@@ -3148,7 +3354,7 @@ TEST_P(SpdyFramerTest, ReadLargeSettingsFrame) {
control_frame->size());
EXPECT_EQ(0, visitor.error_count_);
EXPECT_EQ(3, visitor.setting_count_);
- if (spdy_version_ >= 4) {
+ if (spdy_version_ > SPDY3) {
EXPECT_EQ(1, visitor.settings_ack_sent_);
}
@@ -3166,7 +3372,7 @@ TEST_P(SpdyFramerTest, ReadLargeSettingsFrame) {
}
EXPECT_EQ(0, visitor.error_count_);
EXPECT_EQ(3 * 2, visitor.setting_count_);
- if (spdy_version_ >= 4) {
+ if (spdy_version_ > SPDY3) {
EXPECT_EQ(2, visitor.settings_ack_sent_);
}
}
@@ -3289,7 +3495,7 @@ TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) {
}
TEST_P(SpdyFramerTest, ProcessSettingsAckFrame) {
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
SpdyFramer framer(spdy_version_);
@@ -3310,7 +3516,7 @@ TEST_P(SpdyFramerTest, ProcessSettingsAckFrame) {
TEST_P(SpdyFramerTest, ProcessDataFrameWithPadding) {
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -3380,7 +3586,7 @@ TEST_P(SpdyFramerTest, ProcessDataFrameWithPadding) {
TEST_P(SpdyFramerTest, ReadWindowUpdate) {
SpdyFramer framer(spdy_version_);
scoped_ptr<SpdyFrame> control_frame(
- framer.SerializeWindowUpdate(net::SpdyWindowUpdateIR(1, 2)));
+ framer.SerializeWindowUpdate(SpdyWindowUpdateIR(1, 2)));
TestSpdyVisitor visitor(spdy_version_);
visitor.SimulateInFramer(
reinterpret_cast<unsigned char*>(control_frame->data()),
@@ -3444,7 +3650,7 @@ TEST_P(SpdyFramerTest, ReadCredentialFrameFollowedByAnotherFrame) {
string multiple_frame_data(reinterpret_cast<const char*>(kV3FrameData),
arraysize(kV3FrameData));
scoped_ptr<SpdyFrame> control_frame(
- framer.SerializeWindowUpdate(net::SpdyWindowUpdateIR(1, 2)));
+ framer.SerializeWindowUpdate(SpdyWindowUpdateIR(1, 2)));
multiple_frame_data.append(string(control_frame->data(),
control_frame->size()));
visitor.SimulateInFramer(
@@ -3455,13 +3661,13 @@ TEST_P(SpdyFramerTest, ReadCredentialFrameFollowedByAnotherFrame) {
EXPECT_EQ(2u, visitor.last_window_update_delta_);
}
-TEST_P(SpdyFramerTest, CreateContinuation) {
+TEST_P(SpdyFramerTest, CreateContinuationUncompressed) {
if (spdy_version_ < SPDY4) {
return;
}
SpdyFramer framer(spdy_version_);
-
+ framer.set_enable_compression(false);
const char kDescription[] = "CONTINUATION frame";
const unsigned char kFrameData[] = {
@@ -3483,7 +3689,7 @@ TEST_P(SpdyFramerTest, CreateContinuation) {
}
TEST_P(SpdyFramerTest, ReadCompressedPushPromise) {
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -3506,7 +3712,7 @@ TEST_P(SpdyFramerTest, ReadCompressedPushPromise) {
}
TEST_P(SpdyFramerTest, ReadHeadersWithContinuation) {
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -3551,7 +3757,7 @@ TEST_P(SpdyFramerTest, ReadHeadersWithContinuation) {
}
TEST_P(SpdyFramerTest, ReadHeadersWithContinuationAndFin) {
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -3597,7 +3803,7 @@ TEST_P(SpdyFramerTest, ReadHeadersWithContinuationAndFin) {
}
TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuation) {
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -3644,7 +3850,7 @@ TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuation) {
}
TEST_P(SpdyFramerTest, ReadContinuationWithWrongStreamId) {
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -3680,7 +3886,7 @@ TEST_P(SpdyFramerTest, ReadContinuationWithWrongStreamId) {
}
TEST_P(SpdyFramerTest, ReadContinuationOutOfOrder) {
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -3707,7 +3913,7 @@ TEST_P(SpdyFramerTest, ReadContinuationOutOfOrder) {
}
TEST_P(SpdyFramerTest, ExpectContinuationReceiveData) {
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -3740,7 +3946,7 @@ TEST_P(SpdyFramerTest, ExpectContinuationReceiveData) {
}
TEST_P(SpdyFramerTest, ExpectContinuationReceiveControlFrame) {
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -3933,7 +4139,7 @@ TEST_P(SpdyFramerTest, StatusCodeToStringTest) {
EXPECT_STREQ("FLOW_CONTROL_ERROR",
SpdyFramer::StatusCodeToString(RST_STREAM_FLOW_CONTROL_ERROR));
EXPECT_STREQ("UNKNOWN_STATUS",
- SpdyFramer::StatusCodeToString(RST_STREAM_NUM_STATUS_CODES));
+ SpdyFramer::StatusCodeToString(-1));
}
TEST_P(SpdyFramerTest, FrameTypeToStringTest) {
@@ -3997,7 +4203,7 @@ TEST_P(SpdyFramerTest, CatchProbableHttpResponse) {
}
TEST_P(SpdyFramerTest, DataFrameFlagsV2V3) {
- if (spdy_version_ >= 4) {
+ if (spdy_version_ > SPDY3) {
return;
}
@@ -4008,7 +4214,7 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV2V3) {
SpdyFramer framer(spdy_version_);
framer.set_visitor(&visitor);
- net::SpdyDataIR data_ir(1, StringPiece("hello", 5));
+ SpdyDataIR data_ir(1, StringPiece("hello", 5));
scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
SetFrameFlags(frame.get(), flags, spdy_version_);
@@ -4037,7 +4243,7 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV2V3) {
}
TEST_P(SpdyFramerTest, DataFrameFlagsV4) {
- if (spdy_version_ < 4) {
+ if (spdy_version_ <= SPDY3) {
return;
}
@@ -4051,7 +4257,7 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV4) {
SpdyFramer framer(spdy_version_);
framer.set_visitor(&visitor);
- net::SpdyDataIR data_ir(1, StringPiece("hello", 5));
+ SpdyDataIR data_ir(1, StringPiece("hello", 5));
scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
SetFrameFlags(frame.get(), flags, spdy_version_);
@@ -4210,7 +4416,7 @@ TEST_P(SpdyFramerTest, RstStreamFrameFlags) {
SpdyFramer framer(spdy_version_);
framer.set_visitor(&visitor);
- net::SpdyRstStreamIR rst_stream(13, RST_STREAM_CANCEL, "");
+ SpdyRstStreamIR rst_stream(13, RST_STREAM_CANCEL, "");
scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
SetFrameFlags(frame.get(), flags, spdy_version_);
@@ -4235,7 +4441,7 @@ TEST_P(SpdyFramerTest, RstStreamFrameFlags) {
}
TEST_P(SpdyFramerTest, SettingsFrameFlagsOldFormat) {
- if (spdy_version_ >= 4) { return; }
+ if (spdy_version_ > SPDY3) { return; }
for (int flags = 0; flags < 256; ++flags) {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -4276,7 +4482,7 @@ TEST_P(SpdyFramerTest, SettingsFrameFlagsOldFormat) {
}
TEST_P(SpdyFramerTest, SettingsFrameFlags) {
- if (spdy_version_ < 4) { return; }
+ if (spdy_version_ <= SPDY3) { return; }
for (int flags = 0; flags < 256; ++flags) {
SCOPED_TRACE(testing::Message() << "Flags " << flags);
@@ -4422,7 +4628,7 @@ TEST_P(SpdyFramerTest, PingFrameFlags) {
scoped_ptr<SpdyFrame> frame(framer.SerializePing(SpdyPingIR(42)));
SetFrameFlags(frame.get(), flags, spdy_version_);
- if (spdy_version_ >= SPDY4 &&
+ if (spdy_version_ > SPDY3 &&
flags == PING_FLAG_ACK) {
EXPECT_CALL(visitor, OnPing(42, true));
} else if (flags == 0) {
@@ -4432,7 +4638,7 @@ TEST_P(SpdyFramerTest, PingFrameFlags) {
}
framer.ProcessInput(frame->data(), frame->size());
- if ((spdy_version_ >= SPDY4 && flags == PING_FLAG_ACK) ||
+ if ((spdy_version_ > SPDY3 && flags == PING_FLAG_ACK) ||
flags == 0) {
EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
@@ -4455,7 +4661,7 @@ TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) {
framer.set_visitor(&visitor);
scoped_ptr<SpdyFrame> frame(framer.SerializeWindowUpdate(
- net::SpdyWindowUpdateIR(4, 1024)));
+ SpdyWindowUpdateIR(4, 1024)));
SetFrameFlags(frame.get(), flags, spdy_version_);
if (flags != 0) {
@@ -4623,61 +4829,72 @@ TEST_P(SpdyFramerTest, SettingsFlagsAndId) {
// Test handling of a RST_STREAM with out-of-bounds status codes.
TEST_P(SpdyFramerTest, RstStreamStatusBounds) {
- DCHECK_GE(0xff, RST_STREAM_NUM_STATUS_CODES);
-
+ const unsigned char kRstStreamStatusTooLow = 0x00;
+ const unsigned char kRstStreamStatusTooHigh = 0xff;
const unsigned char kV3RstStreamInvalid[] = {
0x80, spdy_version_ch_, 0x00, 0x03,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, RST_STREAM_INVALID
+ 0x00, 0x00, 0x00, kRstStreamStatusTooLow
};
const unsigned char kV4RstStreamInvalid[] = {
0x00, 0x04, 0x03, 0x00,
0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, RST_STREAM_INVALID
+ 0x00, 0x00, 0x00, kRstStreamStatusTooLow
};
const unsigned char kV3RstStreamNumStatusCodes[] = {
0x80, spdy_version_ch_, 0x00, 0x03,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, RST_STREAM_NUM_STATUS_CODES
+ 0x00, 0x00, 0x00, kRstStreamStatusTooHigh
};
const unsigned char kV4RstStreamNumStatusCodes[] = {
0x00, 0x04, 0x03, 0x00,
0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, RST_STREAM_NUM_STATUS_CODES
+ 0x00, 0x00, 0x00, kRstStreamStatusTooHigh
};
testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
SpdyFramer framer(spdy_version_);
framer.set_visitor(&visitor);
- EXPECT_CALL(visitor, OnRstStream(1, RST_STREAM_INVALID));
if (IsSpdy4()) {
+ EXPECT_CALL(visitor, OnError(_));
framer.ProcessInput(reinterpret_cast<const char*>(kV4RstStreamInvalid),
arraysize(kV4RstStreamInvalid));
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
} else {
+ EXPECT_CALL(visitor, OnRstStream(1, RST_STREAM_INVALID));
framer.ProcessInput(reinterpret_cast<const char*>(kV3RstStreamInvalid),
arraysize(kV3RstStreamInvalid));
- }
- EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
- EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
<< SpdyFramer::ErrorCodeToString(framer.error_code());
+ }
+
+
+ framer.Reset();
- EXPECT_CALL(visitor, OnRstStream(1, RST_STREAM_INVALID));
if (IsSpdy4()) {
+ EXPECT_CALL(visitor, OnError(_));
framer.ProcessInput(
reinterpret_cast<const char*>(kV4RstStreamNumStatusCodes),
arraysize(kV4RstStreamNumStatusCodes));
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
+ << SpdyFramer::ErrorCodeToString(framer.error_code());
} else {
+ EXPECT_CALL(visitor, OnRstStream(1, RST_STREAM_INVALID));
framer.ProcessInput(
reinterpret_cast<const char*>(kV3RstStreamNumStatusCodes),
arraysize(kV3RstStreamNumStatusCodes));
- }
- EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
- EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
<< SpdyFramer::ErrorCodeToString(framer.error_code());
+ }
}
// Tests handling of a GOAWAY frame with out-of-bounds stream ID.
« no previous file with comments | « net/spdy/spdy_framer.cc ('k') | net/spdy/spdy_protocol.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698