Index: net/spdy/spdy_framer_test.cc |
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc |
index 27e7123eb40a5dd65346fe37e0c616aa87ae61be..dfb1f9fa89c91857d25433a1d196d1135098cddf 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_; |
@@ -1073,7 +1095,7 @@ TEST_P(SpdyFramerTest, Basic) { |
// SYN_STREAM doesn't exist in SPDY4, so instead we send |
// HEADERS frames with PRIORITY and END_HEADERS set. |
const unsigned char kV4Input[] = { |
- 0x00, 0x05, 0x01, 0x0c, // HEADERS: PRIORITY | END_HEADERS |
+ 0x00, 0x05, 0x01, 0x24, // HEADERS: PRIORITY | END_HEADERS |
0x00, 0x00, 0x00, 0x01, // Stream 1 |
0x00, 0x00, 0x00, 0x00, // Priority 0 |
0x82, // :method: GET |
@@ -1088,7 +1110,7 @@ TEST_P(SpdyFramerTest, Basic) { |
0xde, 0xad, 0xbe, 0xef, |
0xde, 0xad, 0xbe, 0xef, |
- 0x00, 0x05, 0x01, 0x0c, // HEADERS: PRIORITY | END_HEADERS |
+ 0x00, 0x05, 0x01, 0x24, // HEADERS: PRIORITY | END_HEADERS |
0x00, 0x00, 0x00, 0x03, // Stream 3 |
0x00, 0x00, 0x00, 0x00, // Priority 0 |
0x82, // :method: GET |
@@ -1208,7 +1230,7 @@ TEST_P(SpdyFramerTest, FinOnDataFrame) { |
// SYN_STREAM and SYN_REPLY don't exist in SPDY4, so instead we send |
// HEADERS frames with PRIORITY(SYN_STREAM only) and END_HEADERS set. |
const unsigned char kV4Input[] = { |
- 0x00, 0x05, 0x01, 0x0c, // HEADERS: PRIORITY | END_HEADERS |
+ 0x00, 0x05, 0x01, 0x24, // HEADERS: PRIORITY | END_HEADERS |
0x00, 0x00, 0x00, 0x01, // Stream 1 |
0x00, 0x00, 0x00, 0x00, // Priority 0 |
0x82, // :method: GET |
@@ -1294,7 +1316,7 @@ TEST_P(SpdyFramerTest, FinOnSynReplyFrame) { |
// SYN_STREAM and SYN_REPLY don't exist in SPDY4, so instead we send |
// HEADERS frames with PRIORITY(SYN_STREAM only) and END_HEADERS set. |
const unsigned char kV4Input[] = { |
- 0x00, 0x05, 0x01, 0x0c, // HEADERS: PRIORITY | END_HEADERS |
+ 0x00, 0x05, 0x01, 0x24, // HEADERS: PRIORITY | END_HEADERS |
0x00, 0x00, 0x00, 0x01, // Stream 1 |
0x00, 0x00, 0x00, 0x00, // Priority 0 |
0x82, // :method: GET |
@@ -1565,7 +1587,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { |
}; |
const unsigned char kV4FrameData[] = { |
- 0x01, 0x0b, 0x00, 0x30, // Length = 267. PAD_HIGH and PAD_LOW set. |
+ 0x01, 0x0b, 0x00, 0x18, // 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 |
@@ -1626,7 +1648,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { |
}; |
const unsigned char kV4FrameData[] = { |
- 0x00, 0x0d, 0x00, 0x10, // Length = 13. PAD_LOW set. |
+ 0x00, 0x0d, 0x00, 0x08, // Length = 13. PAD_LOW set. |
0x00, 0x00, 0x00, 0x01, |
0x07, // Pad Low field. |
'h', 'e', 'l', 'l', // Data |
@@ -1660,7 +1682,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { |
}; |
const unsigned char kV4FrameData[] = { |
- 0x00, 0x06, 0x00, 0x10, // Length = 6. PAD_LOW set. |
+ 0x00, 0x06, 0x00, 0x08, // Length = 6. PAD_LOW set. |
0x00, 0x00, 0x00, 0x01, |
0x00, // Pad Low field. |
'h', 'e', 'l', 'l', // Data |
@@ -1854,7 +1876,7 @@ TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) { |
'a', 'r' |
}; |
const unsigned char kV4FrameData[] = { |
- 0x00, 0x16, 0x01, 0x0c, // HEADERS: PRIORITY | END_HEADERS |
+ 0x00, 0x16, 0x01, 0x24, // HEADERS: PRIORITY | END_HEADERS |
0x00, 0x00, 0x00, 0x01, // Stream 1 |
0x00, 0x00, 0x00, 0x07, // Priority 7 |
0x00, 0x03, 0x62, 0x61, // @.ba |
@@ -1909,7 +1931,7 @@ TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) { |
'b', 'a', 'r' |
}; |
const unsigned char kV4FrameData[] = { |
- 0x00, 0x13, 0x01, 0x0d, // HEADERS: PRIORITY | FIN | END_HEADERS |
+ 0x00, 0x13, 0x01, 0x25, // HEADERS: PRIORITY | FIN | END_HEADERS |
0x7f, 0xff, 0xff, 0xff, // Stream 0x7fffffff |
0x00, 0x00, 0x00, 0x00, // Priority 0 |
0x00, 0x00, 0x03, 0x66, // @..f |
@@ -1966,7 +1988,7 @@ TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) { |
0x00, 0x00, 0x00 |
}; |
const unsigned char kV4FrameData[] = { |
- 0x00, 0x13, 0x01, 0x0d, // HEADERS: PRIORITY | FIN | END_HEADERS |
+ 0x00, 0x13, 0x01, 0x25, // HEADERS: PRIORITY | FIN | END_HEADERS |
0x7f, 0xff, 0xff, 0xff, // Stream 0x7fffffff |
0x00, 0x00, 0x00, 0x01, // Priority 1 |
0x00, 0x03, 0x62, 0x61, // @.ba |
@@ -2883,16 +2905,18 @@ TEST_P(SpdyFramerTest, CreateWindowUpdate) { |
} |
TEST_P(SpdyFramerTest, SerializeBlocked) { |
- if (spdy_version_ < SPDY4) { |
+ if (spdy_version_ <= SPDY3) { |
return; |
} |
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)); |
@@ -2900,7 +2924,7 @@ TEST_P(SpdyFramerTest, SerializeBlocked) { |
} |
TEST_P(SpdyFramerTest, CreateBlocked) { |
- if (spdy_version_ < SPDY4) { |
+ if (spdy_version_ <= SPDY3) { |
return; |
} |
@@ -2913,13 +2937,13 @@ 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); |
} |
TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) { |
- if (spdy_version_ < SPDY4) { |
+ if (spdy_version_ <= SPDY3) { |
return; |
} |
@@ -2946,6 +2970,36 @@ TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) { |
CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); |
} |
+TEST_P(SpdyFramerTest, CreateAltSvc) { |
+ if (spdy_version_ <= SPDY3) { |
+ 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); |
@@ -3054,7 +3108,7 @@ TEST_P(SpdyFramerTest, ControlFrameAtMaxSizeLimit) { |
// Create a frame at exactly that size. |
string big_value(kBigValueSize, 'x'); |
- syn_stream.SetHeader("aa", big_value.c_str()); |
+ syn_stream.SetHeader("aa", big_value); |
control_frame.reset(framer.SerializeSynStream(syn_stream)); |
EXPECT_TRUE(control_frame.get() != NULL); |
EXPECT_EQ(framer.GetControlFrameBufferMaxSize(), control_frame->size()); |
@@ -3089,7 +3143,7 @@ TEST_P(SpdyFramerTest, ControlFrameTooLarge) { |
// Create a frame at exatly that size. |
string big_value(kBigValueSize, 'x'); |
- syn_stream.SetHeader("aa", big_value.c_str()); |
+ syn_stream.SetHeader("aa", big_value); |
// Upstream branches here and wraps SPDY4 with EXPECT_DEBUG_DFATAL. We |
// neither support that in Chromium, nor do we use the same DFATAL (see |
// SpdyFrameBuilder::WriteFramePrefix()). |
@@ -3113,7 +3167,7 @@ TEST_P(SpdyFramerTest, ControlFrameTooLarge) { |
} |
TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) { |
- if (spdy_version_ < SPDY4) { |
+ if (spdy_version_ <= SPDY3) { |
return; |
} |
SpdyFramer framer(spdy_version_); |
@@ -3124,7 +3178,7 @@ TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) { |
// enough to cause an overflow. |
const size_t kBigValueSize = framer.GetControlFrameBufferMaxSize(); |
string big_value(kBigValueSize, 'x'); |
- headers.SetHeader("aa", big_value.c_str()); |
+ headers.SetHeader("aa", big_value); |
scoped_ptr<SpdyFrame> control_frame(framer.SerializeHeaders(headers)); |
EXPECT_TRUE(control_frame.get() != NULL); |
EXPECT_GT(control_frame->size(), framer.GetControlFrameBufferMaxSize()); |
@@ -3141,7 +3195,7 @@ TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) { |
} |
TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) { |
- if (spdy_version_ < SPDY4) { |
+ if (spdy_version_ <= SPDY3) { |
return; |
} |
SpdyFramer framer(spdy_version_); |
@@ -3152,7 +3206,7 @@ TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) { |
// enough to cause an overflow. |
const size_t kBigValueSize = framer.GetControlFrameBufferMaxSize(); |
string big_value(kBigValueSize, 'x'); |
- push_promise.SetHeader("aa", big_value.c_str()); |
+ push_promise.SetHeader("aa", big_value); |
scoped_ptr<SpdyFrame> control_frame( |
framer.SerializePushPromise(push_promise)); |
EXPECT_TRUE(control_frame.get() != NULL); |
@@ -3182,7 +3236,7 @@ TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) { |
SpdySynStreamIR syn_stream(1); |
syn_stream.set_priority(1); |
syn_stream.set_fin(true); |
- syn_stream.SetHeader("aa", big_value.c_str()); |
+ syn_stream.SetHeader("aa", big_value); |
scoped_ptr<SpdyFrame> control_frame(framer.SerializeSynStream(syn_stream)); |
EXPECT_TRUE(control_frame.get() != NULL); |
TestSpdyVisitor visitor(spdy_version_); |
@@ -3436,6 +3490,25 @@ TEST_P(SpdyFramerTest, ReadDuplicateSettings) { |
} |
} |
+// Tests handling of SETTINGS_COMPRESS_DATA. |
+TEST_P(SpdyFramerTest, AcceptSettingsCompressData) { |
+ if (!IsSpdy4()) { return; } |
+ SpdyFramer framer(spdy_version_); |
+ |
+ const unsigned char kFrameData[] = { |
+ 0x00, 0x05, 0x04, 0x00, |
+ 0x00, 0x00, 0x00, 0x00, |
+ 0x05, 0x00, 0x00, 0x00, |
+ 0x01, |
+ }; |
+ |
+ TestSpdyVisitor visitor(spdy_version_); |
+ visitor.use_compression_ = false; |
+ visitor.SimulateInFramer(kFrameData, sizeof(kFrameData)); |
+ EXPECT_EQ(1, visitor.setting_count_); |
+ EXPECT_EQ(0, visitor.error_count_); |
+} |
+ |
// Tests handling of SETTINGS frame with entries out of order. |
TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) { |
SpdyFramer framer(spdy_version_); |
@@ -3662,7 +3735,7 @@ TEST_P(SpdyFramerTest, ReadCredentialFrameFollowedByAnotherFrame) { |
} |
TEST_P(SpdyFramerTest, CreateContinuationUncompressed) { |
- if (spdy_version_ < SPDY4) { |
+ if (spdy_version_ <= SPDY3) { |
return; |
} |
@@ -3711,29 +3784,34 @@ TEST_P(SpdyFramerTest, ReadCompressedPushPromise) { |
EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_)); |
} |
-TEST_P(SpdyFramerTest, ReadHeadersWithContinuation) { |
+TEST_P(SpdyFramerTest, ReadHeadersWithContinuationAndPadding) { |
if (spdy_version_ <= SPDY3) { |
return; |
} |
const unsigned char kInput[] = { |
- 0x00, 0x10, 0x01, 0x00, // HEADERS |
+ 0x00, 0x14, 0x01, 0x08, // HEADERS: PAD_LOW |
0x00, 0x00, 0x00, 0x01, // Stream 1 |
+ 0x03, // Padding of 3. |
0x00, 0x06, 0x63, 0x6f, |
0x6f, 0x6b, 0x69, 0x65, |
0x07, 0x66, 0x6f, 0x6f, |
0x3d, 0x62, 0x61, 0x72, |
+ 0x00, 0x00, 0x00, |
- 0x00, 0x14, 0x09, 0x00, // CONTINUATION |
+ 0x00, 0x1a, 0x09, 0x18, // CONTINUATION: PAD_LOW & PAD_HIGH |
0x00, 0x00, 0x00, 0x01, // Stream 1 |
+ 0x00, 0x04, // Padding of 4. |
0x00, 0x06, 0x63, 0x6f, |
0x6f, 0x6b, 0x69, 0x65, |
0x08, 0x62, 0x61, 0x7a, |
0x3d, 0x62, 0x69, 0x6e, |
0x67, 0x00, 0x06, 0x63, |
+ 0x00, 0x00, 0x00, 0x00, |
- 0x00, 0x12, 0x09, 0x04, // CONTINUATION: END_HEADERS |
+ 0x00, 0x13, 0x09, 0x0c, // CONTINUATION: PAD_LOW & END_HEADERS |
0x00, 0x00, 0x00, 0x01, // Stream 1 |
+ 0x00, // Padding of 0. |
0x6f, 0x6f, 0x6b, 0x69, |
0x65, 0x00, 0x00, 0x04, |
0x6e, 0x61, 0x6d, 0x65, |
@@ -3741,7 +3819,6 @@ TEST_P(SpdyFramerTest, ReadHeadersWithContinuation) { |
0x75, 0x65, |
}; |
- SpdyFramer framer(spdy_version_); |
TestSpdyVisitor visitor(spdy_version_); |
visitor.SimulateInFramer(kInput, sizeof(kInput)); |
@@ -3802,21 +3879,23 @@ TEST_P(SpdyFramerTest, ReadHeadersWithContinuationAndFin) { |
Pair("name", "value"))); |
} |
-TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuation) { |
+TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuationAndPadding) { |
if (spdy_version_ <= SPDY3) { |
return; |
} |
const unsigned char kInput[] = { |
- 0x00, 0x14, 0x05, 0x00, // PUSH_PROMISE |
+ 0x00, 0x18, 0x05, 0x18, // PUSH_PROMISE: PAD_LOW & PAD_HIGH |
0x00, 0x00, 0x00, 0x01, // Stream 1 |
0x00, 0x00, 0x00, 0x2A, // Promised stream 42 |
+ 0x00, 0x02, // Padding of 2. |
0x00, 0x06, 0x63, 0x6f, |
0x6f, 0x6b, 0x69, 0x65, |
0x07, 0x66, 0x6f, 0x6f, |
0x3d, 0x62, 0x61, 0x72, |
+ 0x00, 0x00, |
- 0x00, 0x14, 0x09, 0x00, // CONTINUATION |
+ 0x00, 0x14, 0x09, 0x00, // CONTINUATION: |
0x00, 0x00, 0x00, 0x01, // Stream 1 |
0x00, 0x06, 0x63, 0x6f, |
0x6f, 0x6b, 0x69, 0x65, |
@@ -3824,13 +3903,15 @@ TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuation) { |
0x3d, 0x62, 0x69, 0x6e, |
0x67, 0x00, 0x06, 0x63, |
- 0x00, 0x12, 0x09, 0x04, // CONTINUATION: END_HEADERS |
+ 0x00, 0x17, 0x09, 0x0c, // CONTINUATION: PAD_LOW & END_HEADERS |
0x00, 0x00, 0x00, 0x01, // Stream 1 |
+ 0x04, // Padding of 4. |
0x6f, 0x6f, 0x6b, 0x69, |
0x65, 0x00, 0x00, 0x04, |
0x6e, 0x61, 0x6d, 0x65, |
0x05, 0x76, 0x61, 0x6c, |
- 0x75, 0x65, |
+ 0x75, 0x65, 0x00, 0x00, |
+ 0x00, 0x00, |
}; |
SpdyFramer framer(spdy_version_); |
@@ -3982,6 +4063,53 @@ TEST_P(SpdyFramerTest, ExpectContinuationReceiveControlFrame) { |
EXPECT_EQ(0, visitor.data_frame_count_); |
} |
+TEST_P(SpdyFramerTest, EndSegmentOnDataFrame) { |
+ if (spdy_version_ <= SPDY3) { |
+ return; |
+ } |
+ const unsigned char kInput[] = { |
+ 0x00, 0x0c, 0x00, 0x02, // DATA: END_SEGMENT |
+ 0x00, 0x00, 0x00, 0x01, // Stream 1 |
+ 0xde, 0xad, 0xbe, 0xef, |
+ 0xde, 0xad, 0xbe, 0xef, |
+ 0xde, 0xad, 0xbe, 0xef, |
+ }; |
+ |
+ TestSpdyVisitor visitor(spdy_version_); |
+ visitor.SimulateInFramer(kInput, sizeof(kInput)); |
+ |
+ // TODO(jgraettinger): Verify END_SEGMENT when support is added. |
+ EXPECT_EQ(0, visitor.error_count_); |
+ EXPECT_EQ(12, visitor.data_bytes_); |
+ EXPECT_EQ(0, visitor.fin_frame_count_); |
+ EXPECT_EQ(0, visitor.fin_flag_count_); |
+} |
+ |
+TEST_P(SpdyFramerTest, EndSegmentOnHeadersFrame) { |
+ if (spdy_version_ <= SPDY3) { |
+ return; |
+ } |
+ const unsigned char kInput[] = { |
+ 0x00, 0x10, 0x01, 0x06, // HEADERS: END_SEGMENT | END_HEADERS |
+ 0x00, 0x00, 0x00, 0x01, // Stream 1 |
+ 0x00, 0x06, 0x63, 0x6f, |
+ 0x6f, 0x6b, 0x69, 0x65, |
+ 0x07, 0x66, 0x6f, 0x6f, |
+ 0x3d, 0x62, 0x61, 0x72, |
+ }; |
+ |
+ TestSpdyVisitor visitor(spdy_version_); |
+ visitor.SimulateInFramer(kInput, sizeof(kInput)); |
+ |
+ // TODO(jgraettinger): Verify END_SEGMENT when support is added. |
+ EXPECT_EQ(0, visitor.error_count_); |
+ EXPECT_EQ(1, visitor.headers_frame_count_); |
+ EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
+ |
+ EXPECT_THAT(visitor.headers_, ElementsAre( |
+ Pair("cookie", "foo=bar"))); |
+} |
+ |
TEST_P(SpdyFramerTest, ReadGarbage) { |
SpdyFramer framer(spdy_version_); |
unsigned char garbage_frame[256]; |
@@ -4025,10 +4153,29 @@ TEST_P(SpdyFramerTest, ReadGarbageWithValidVersion) { |
EXPECT_EQ(1, visitor.error_count_); |
} |
+TEST_P(SpdyFramerTest, ReadGarbageHPACKEncoding) { |
+ if (spdy_version_ <= SPDY3) { |
+ return; |
+ } |
+ const unsigned char kInput[] = { |
+ 0x00, 0x12, 0x01, 0x04, // HEADER: END_HEADERS |
+ 0x00, 0x00, 0x00, 0x01, // Stream 1 |
+ 0xef, 0xef, 0xff, 0xff, |
+ 0xff, 0xff, 0xff, 0xff, |
+ 0xff, 0xff, 0xff, 0xff, |
+ 0xff, 0xff, 0xff, 0xff, |
+ 0xff, 0xff, |
+ }; |
+ |
+ TestSpdyVisitor visitor(spdy_version_); |
+ visitor.SimulateInFramer(kInput, arraysize(kInput)); |
+ EXPECT_EQ(1, visitor.error_count_); |
+} |
+ |
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 +4185,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 +4233,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) { |
@@ -4312,6 +4463,10 @@ TEST_P(SpdyFramerTest, SynStreamFrameFlags) { |
if (IsSpdy4()) { |
// PRIORITY required for SYN_STREAM simulation. |
set_flags |= HEADERS_FLAG_PRIORITY; |
+ |
+ // TODO(jgraettinger): Add padding to SynStreamIR, and implement framing. |
+ set_flags &= ~HEADERS_FLAG_PAD_LOW; |
+ set_flags &= ~HEADERS_FLAG_PAD_HIGH; |
} |
SetFrameFlags(frame.get(), set_flags, spdy_version_); |
@@ -4321,7 +4476,10 @@ TEST_P(SpdyFramerTest, SynStreamFrameFlags) { |
} else if (IsSpdy4() && |
flags & ~(CONTROL_FLAG_FIN | |
HEADERS_FLAG_PRIORITY | |
- HEADERS_FLAG_END_HEADERS)) { |
+ HEADERS_FLAG_END_HEADERS | |
+ HEADERS_FLAG_END_SEGMENT | |
+ HEADERS_FLAG_PAD_LOW | |
+ HEADERS_FLAG_PAD_HIGH)) { |
EXPECT_CALL(visitor, OnError(_)); |
} else { |
EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(8, SYN_STREAM, _)); |
@@ -4353,7 +4511,10 @@ TEST_P(SpdyFramerTest, SynStreamFrameFlags) { |
} else if (IsSpdy4() && |
flags & ~(CONTROL_FLAG_FIN | |
HEADERS_FLAG_PRIORITY | |
- HEADERS_FLAG_END_HEADERS)) { |
+ HEADERS_FLAG_END_HEADERS | |
+ HEADERS_FLAG_END_SEGMENT | |
+ HEADERS_FLAG_PAD_LOW | |
+ HEADERS_FLAG_PAD_HIGH)) { |
EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); |
EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, |
framer.error_code()) |
@@ -4570,12 +4731,22 @@ TEST_P(SpdyFramerTest, HeadersFrameFlags) { |
SpdyHeadersIR headers_ir(57); |
headers_ir.SetHeader("foo", "bar"); |
scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir)); |
- SetFrameFlags(frame.get(), flags, spdy_version_); |
+ int set_flags = flags; |
+ if (IsSpdy4()) { |
+ // TODO(jgraettinger): Add padding to SpdyHeadersIR, |
+ // and implement framing. |
+ set_flags &= ~HEADERS_FLAG_PAD_LOW; |
+ set_flags &= ~HEADERS_FLAG_PAD_HIGH; |
+ } |
+ SetFrameFlags(frame.get(), set_flags, spdy_version_); |
if (!IsSpdy4() && flags & ~CONTROL_FLAG_FIN) { |
EXPECT_CALL(visitor, OnError(_)); |
} else if (IsSpdy4() && flags & ~(CONTROL_FLAG_FIN | |
- HEADERS_FLAG_END_HEADERS)) { |
+ HEADERS_FLAG_END_HEADERS | |
+ HEADERS_FLAG_END_SEGMENT | |
+ HEADERS_FLAG_PAD_LOW | |
+ HEADERS_FLAG_PAD_HIGH)) { |
EXPECT_CALL(visitor, OnError(_)); |
} else { |
EXPECT_CALL(visitor, OnHeaders(57, |
@@ -4599,8 +4770,11 @@ TEST_P(SpdyFramerTest, HeadersFrameFlags) { |
EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, |
framer.error_code()) |
<< SpdyFramer::ErrorCodeToString(framer.error_code()); |
- } else if (IsSpdy4() && flags & ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | |
- HEADERS_FLAG_END_HEADERS)) { |
+ } else if (IsSpdy4() && flags & ~(CONTROL_FLAG_FIN | |
+ HEADERS_FLAG_END_HEADERS | |
+ HEADERS_FLAG_END_SEGMENT | |
+ HEADERS_FLAG_PAD_LOW | |
+ HEADERS_FLAG_PAD_HIGH)) { |
EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); |
EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, |
framer.error_code()) |
@@ -4685,7 +4859,7 @@ TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) { |
} |
TEST_P(SpdyFramerTest, PushPromiseFrameFlags) { |
- if (spdy_version_ < SPDY4) { |
+ if (spdy_version_ <= SPDY3) { |
return; |
} |
@@ -4704,9 +4878,14 @@ TEST_P(SpdyFramerTest, PushPromiseFrameFlags) { |
push_promise.SetHeader("foo", "bar"); |
scoped_ptr<SpdySerializedFrame> frame( |
framer.SerializePushPromise(push_promise)); |
- SetFrameFlags(frame.get(), flags, spdy_version_); |
+ // TODO(jgraettinger): Add padding to SpdyPushPromiseIR, |
+ // and implement framing. |
+ int set_flags = flags & ~HEADERS_FLAG_PAD_LOW & ~HEADERS_FLAG_PAD_HIGH; |
+ SetFrameFlags(frame.get(), set_flags, spdy_version_); |
- if (flags & ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE)) { |
+ if (flags & ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | |
+ HEADERS_FLAG_PAD_LOW | |
+ HEADERS_FLAG_PAD_HIGH)) { |
EXPECT_CALL(visitor, OnError(_)); |
} else { |
EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(42, PUSH_PROMISE, _)); |
@@ -4717,7 +4896,9 @@ TEST_P(SpdyFramerTest, PushPromiseFrameFlags) { |
} |
framer.ProcessInput(frame->data(), frame->size()); |
- if (flags & ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE)) { |
+ if (flags & ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | |
+ HEADERS_FLAG_PAD_LOW | |
+ HEADERS_FLAG_PAD_HIGH)) { |
EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); |
EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, |
framer.error_code()) |
@@ -4731,7 +4912,7 @@ TEST_P(SpdyFramerTest, PushPromiseFrameFlags) { |
} |
TEST_P(SpdyFramerTest, ContinuationFrameFlags) { |
- if (spdy_version_ < SPDY4) { |
+ if (spdy_version_ <= SPDY3) { |
return; |
} |
@@ -4760,9 +4941,14 @@ TEST_P(SpdyFramerTest, ContinuationFrameFlags) { |
continuation.SetHeader("foo", "bar"); |
scoped_ptr<SpdySerializedFrame> frame( |
framer.SerializeContinuation(continuation)); |
- SetFrameFlags(frame.get(), flags, spdy_version_); |
+ // TODO(jgraettinger): Add padding to the eventual continuation |
+ // serialization implementation. |
+ int set_flags = flags & ~HEADERS_FLAG_PAD_LOW & ~HEADERS_FLAG_PAD_HIGH; |
+ SetFrameFlags(frame.get(), set_flags, spdy_version_); |
- if (flags & ~(HEADERS_FLAG_END_HEADERS)) { |
+ if (flags & ~(HEADERS_FLAG_END_HEADERS | |
+ HEADERS_FLAG_PAD_LOW | |
+ HEADERS_FLAG_PAD_HIGH)) { |
EXPECT_CALL(visitor, OnError(_)); |
} else { |
EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(42, CONTINUATION, _)); |
@@ -4774,7 +4960,9 @@ TEST_P(SpdyFramerTest, ContinuationFrameFlags) { |
framer.ProcessInput(frame0->data(), frame0->size()); |
framer.ProcessInput(frame->data(), frame->size()); |
- if (flags & ~(HEADERS_FLAG_END_HEADERS)) { |
+ if (flags & ~(HEADERS_FLAG_END_HEADERS | |
+ HEADERS_FLAG_PAD_LOW | |
+ HEADERS_FLAG_PAD_HIGH)) { |
EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); |
EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, |
framer.error_code()) |
@@ -4787,6 +4975,10 @@ TEST_P(SpdyFramerTest, ContinuationFrameFlags) { |
} |
} |
+// TODO(mlavan): Add TEST_P(SpdyFramerTest, AltSvcFrameFlags) |
+ |
+// TODO(hkhalil): Add TEST_P(SpdyFramerTest, BlockedFrameFlags) |
+ |
TEST_P(SpdyFramerTest, EmptySynStream) { |
testing::StrictMock<test::MockSpdyFramerVisitor> visitor; |
testing::StrictMock<test::MockDebugVisitor> debug_visitor; |
@@ -4938,7 +5130,7 @@ TEST_P(SpdyFramerTest, GoAwayStreamIdBounds) { |
} |
TEST_P(SpdyFramerTest, OnBlocked) { |
- if (spdy_version_ < SPDY4) { |
+ if (spdy_version_ <= SPDY3) { |
return; |
} |
@@ -4959,4 +5151,249 @@ TEST_P(SpdyFramerTest, OnBlocked) { |
<< SpdyFramer::ErrorCodeToString(framer.error_code()); |
} |
+TEST_P(SpdyFramerTest, OnAltSvc) { |
+ if (spdy_version_ <= SPDY3) { |
+ 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_ <= SPDY3) { |
+ 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_ <= SPDY3) { |
+ 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_ <= SPDY3) { |
+ 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()); |
+} |
+ |
+// Tests handling of PRIORITY frames. |
+TEST_P(SpdyFramerTest, ReadPriority) { |
+ if (spdy_version_ <= SPDY3) { |
+ return; |
+ } |
+ |
+ const unsigned char kFrameData[] = { |
+ 0x00, 0x05, 0x02, 0x00, // PRIORITY frame |
+ 0x00, 0x00, 0x00, 0x03, // stream ID 3 |
+ 0x00, 0x00, 0x00, 0x01, // dependent on stream id 1 |
+ 0x00 // weight 0 |
+ }; |
+ |
+ TestSpdyVisitor visitor(spdy_version_); |
+ visitor.SimulateInFramer(kFrameData, sizeof(kFrameData)); |
+ |
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, visitor.framer_.state()); |
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, visitor.framer_.error_code()) |
+ << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); |
+} |
+ |
+// Tests handling of PRIORITY frame with incorrect size. |
+TEST_P(SpdyFramerTest, ReadIncorrectlySizedPriority) { |
+ if (spdy_version_ <= SPDY3) { |
+ return; |
+ } |
+ |
+ // PRIORITY frame of size 4, which isn't correct. |
+ const unsigned char kFrameData[] = { |
+ 0x00, 0x04, 0x02, 0x00, |
+ 0x00, 0x00, 0x00, 0x03, |
+ 0x00, 0x00, 0x00, 0x01, |
+ }; |
+ |
+ TestSpdyVisitor visitor(spdy_version_); |
+ visitor.SimulateInFramer(kFrameData, sizeof(kFrameData)); |
+ |
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, visitor.framer_.state()); |
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, |
+ visitor.framer_.error_code()) |
+ << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); |
+} |
+ |
} // namespace net |