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

Unified Diff: net/spdy/spdy_framer_spdy2_test.cc

Issue 9618002: SPDY - integration of spdy/3 code. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 9 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_framer_spdy3_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_framer_spdy2_test.cc
===================================================================
--- net/spdy/spdy_framer_spdy2_test.cc (working copy)
+++ net/spdy/spdy_framer_spdy2_test.cc (working copy)
@@ -11,13 +11,152 @@
#include "net/spdy/spdy_frame_builder.h"
#include "testing/platform_test.h"
+namespace {
+
+// Default SPDY version for unit tests.
+const int SPDY_VERSION_FOR_TESTS = 2;
+
+// The current default spdy version as a byte to be included in const
+// byte arrays below. Name choice is unfortunate, but better to fit to four
+// bytes than not.
+unsigned char kVer = SPDY_VERSION_FOR_TESTS;
+
+spdy::SpdySetting SpdySettingFromWireFormat(uint32 key, uint32 value) {
+ return spdy::SpdySetting(
+ spdy::SettingsFlagsAndId::FromWireFormat(SPDY_VERSION_FOR_TESTS, key),
+ value);
+}
+
+} // namespace
+
namespace spdy {
-namespace test {
+namespace test_spdy2 {
+static const size_t kMaxDecompressedSize = 1024;
+
+class SpdyFramerTestUtil {
+ public:
+ // Decompress a single frame using the decompression context held by
+ // the SpdyFramer. The implemention will CHECK fail if the input is anything
+ // other than a single, well-formed compressed frame.
+ //
+ // Returns a new decompressed SpdyFrame.
+ template<class SpdyFrameType> static SpdyFrame* DecompressFrame(
+ SpdyFramer* framer, const SpdyFrameType& frame) {
+ DecompressionVisitor visitor;
+ framer->set_visitor(&visitor);
+ size_t input_size = frame.length() + SpdyFrame::kHeaderSize;
+ CHECK_EQ(input_size, framer->ProcessInput(frame.data(), input_size));
+ CHECK_EQ(SpdyFramer::SPDY_RESET, framer->state());
+ framer->set_visitor(NULL);
+
+ char* buffer = visitor.ReleaseBuffer();
+ CHECK(buffer);
+ SpdyFrame* decompressed_frame = new SpdyFrame(buffer, true);
+ decompressed_frame->set_length(visitor.size() - SpdyFrame::kHeaderSize);
+ return decompressed_frame;
+ }
+
+ class DecompressionVisitor : public SpdyFramerVisitorInterface {
+ public:
+ DecompressionVisitor()
+ : buffer_(NULL), size_(0), finished_(false), allow_data_frames_(false) {
+ }
+
+ virtual void OnControl(const SpdyControlFrame* frame) {
+ CHECK(frame->has_header_block());
+ CHECK(!buffer_.get());
+ CHECK_EQ(size_, 0u);
+ CHECK(!finished_);
+
+ int32 control_frame_header_size = 0;
+ switch (frame->type()) {
+ case SYN_STREAM:
+ control_frame_header_size = SpdySynStreamControlFrame::size();
+ break;
+ case SYN_REPLY:
+ control_frame_header_size = SpdySynReplyControlFrame::size();
+ break;
+ case HEADERS:
+ control_frame_header_size = SpdyHeadersControlFrame::size();
+ break;
+ default:
+ LOG(FATAL);
+ return;
+ }
+
+ // Allocate space for the frame, and the copy header over.
+ buffer_.reset(new char[kMaxDecompressedSize]);
+ memcpy(buffer_.get(), frame->data(), control_frame_header_size);
+ size_ += control_frame_header_size;
+ }
+
+ virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
+ const char* header_data,
+ size_t len) {
+ CHECK(buffer_.get() != NULL);
+ CHECK_GE(kMaxDecompressedSize, size_ + len);
+ CHECK(!finished_);
+ if (len != 0) {
+ memcpy(buffer_.get() + size_, header_data, len);
+ size_ += len;
+ } else {
+ // Done.
+ finished_ = true;
+ }
+ return true;
+ }
+
+ virtual bool OnCredentialFrameData(const char* header_data,
+ size_t len) {
+ LOG(FATAL) << "Unexpected CREDENTIAL Frame";
+ return false;
+ }
+
+ virtual void OnError(SpdyFramer* framer) { LOG(FATAL); }
+ virtual void OnDataFrameHeader(const SpdyDataFrame* frame) {
+ // For most tests, this class does not expect to see OnDataFrameHeader
+ // calls. Individual tests can override this if they need to.
+ if (!allow_data_frames_) {
+ LOG(FATAL) << "Unexpected data frame header";
+ }
+ }
+ virtual void OnStreamFrameData(SpdyStreamId stream_id,
+ const char* data,
+ size_t len) {
+ LOG(FATAL);
+ }
+ virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) {
+ LOG(FATAL);
+ }
+
+ char* ReleaseBuffer() {
+ CHECK(finished_);
+ return buffer_.release();
+ }
+
+ size_t size() const {
+ CHECK(finished_);
+ return size_;
+ }
+ void set_allow_data_frames(bool allow) { allow_data_frames_ = allow; }
+
+ private:
+ scoped_array<char> buffer_;
+ size_t size_;
+ bool finished_;
+ bool allow_data_frames_;
+
+ DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor);
+ };
+
+ DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil);
+};
+
std::string HexDumpWithMarks(const unsigned char* data, int length,
const bool* marks, int mark_length) {
- static const char kHexChars[] = "0123456789ABCDEF";
+ static const char kHexChars[] = "0123456789abcdef";
static const int kColumns = 4;
const int kSizeLimit = 1024;
@@ -58,8 +197,8 @@
const int actual_len,
const unsigned char* expected,
const int expected_len) {
- const int min_len = actual_len > expected_len ? expected_len : actual_len;
- const int max_len = actual_len > expected_len ? actual_len : expected_len;
+ const int min_len = std::min(actual_len, expected_len);
+ const int max_len = std::max(actual_len, expected_len);
scoped_array<bool> marks(new bool[max_len]);
bool identical = (actual_len == expected_len);
for (int i = 0; i < min_len; ++i) {
@@ -89,13 +228,16 @@
static const size_t kDefaultCredentialBufferSize = 16 * 1024;
TestSpdyVisitor()
- : use_compression_(false),
+ : framer_(kVer),
+ use_compression_(false),
error_count_(0),
syn_frame_count_(0),
syn_reply_frame_count_(0),
headers_frame_count_(0),
goaway_count_(0),
credential_count_(0),
+ settings_frame_count_(0),
+ setting_count_(0),
data_bytes_(0),
fin_frame_count_(0),
fin_flag_count_(0),
@@ -166,6 +308,9 @@
case CREDENTIAL:
credential_count_++;
break;
+ case SETTINGS:
+ settings_frame_count_++;
+ break;
default:
DLOG(FATAL); // Error!
}
@@ -173,6 +318,10 @@
++fin_flag_count_;
}
+ virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) {
+ setting_count_++;
+ }
+
bool OnControlFrameHeaderData(SpdyStreamId stream_id,
const char* header_data,
size_t len) {
@@ -182,7 +331,7 @@
++zero_length_control_frame_header_data_count_;
// Indicates end-of-header-block.
CHECK(header_buffer_valid_);
- bool parsed_headers = SpdyFramer::ParseHeaderBlockInBuffer(
+ bool parsed_headers = framer_.ParseHeaderBlockInBuffer(
header_buffer_.get(), header_buffer_length_, &headers_);
DCHECK(parsed_headers);
return true;
@@ -197,7 +346,8 @@
return true;
}
- bool OnCredentialFrameData(const char* credential_data, size_t len) {
+ bool OnCredentialFrameData(const char* credential_data,
+ size_t len) {
if (len == 0) {
if (!framer_.ParseCredentialData(credential_buffer_.get(),
credential_buffer_length_,
@@ -272,6 +422,8 @@
int headers_frame_count_;
int goaway_count_;
int credential_count_;
+ int settings_frame_count_;
+ int setting_count_;
int data_bytes_;
int fin_frame_count_; // The count of RST_STREAM type frames received.
int fin_flag_count_; // The count of frames with the FIN flag set.
@@ -297,7 +449,7 @@
SpdyCredential credential_;
};
-} // namespace test
+} // namespace test_spdy2
} // namespace spdy
@@ -315,12 +467,13 @@
using spdy::DATA_FLAG_COMPRESSED;
using spdy::DATA_FLAG_FIN;
using spdy::SYN_STREAM;
-using spdy::test::CompareCharArraysWithHexError;
-using spdy::test::TestSpdyVisitor;
+using spdy::test_spdy2::CompareCharArraysWithHexError;
+using spdy::test_spdy2::SpdyFramerTestUtil;
+using spdy::test_spdy2::TestSpdyVisitor;
namespace spdy {
-TEST(SpdyFrameBuilderTest, WriteLimits) {
+TEST(SpdyFrameBuilderSpdy2Test, WriteLimits) {
SpdyFrameBuilder builder(kLengthMask + 4);
// length field should fail.
EXPECT_FALSE(builder.WriteBytes(reinterpret_cast<const void*>(0x1),
@@ -335,7 +488,7 @@
EXPECT_EQ(4 + kLengthMask, static_cast<unsigned>(builder.length()));
}
-class SpdyFramerTest : public PlatformTest {
+class SpdyFramerSpdy2Test : public PlatformTest {
public:
virtual void TearDown() {}
@@ -382,11 +535,11 @@
// Test that we can encode and decode a SpdyHeaderBlock in serialized form.
-TEST_F(SpdyFramerTest, HeaderBlockInBuffer) {
+TEST_F(SpdyFramerSpdy2Test, HeaderBlockInBuffer) {
SpdyHeaderBlock headers;
headers["alpha"] = "beta";
headers["gamma"] = "charlie";
- SpdyFramer framer;
+ SpdyFramer framer(kVer);
// Encode the header block into a SynStream frame.
scoped_ptr<SpdySynStreamControlFrame> frame(
@@ -405,11 +558,11 @@
}
// Test that if there's not a full frame, we fail to parse it.
-TEST_F(SpdyFramerTest, UndersizedHeaderBlockInBuffer) {
+TEST_F(SpdyFramerSpdy2Test, UndersizedHeaderBlockInBuffer) {
SpdyHeaderBlock headers;
headers["alpha"] = "beta";
headers["gamma"] = "charlie";
- SpdyFramer framer;
+ SpdyFramer framer(kVer);
// Encode the header block into a SynStream frame.
scoped_ptr<SpdySynStreamControlFrame> frame(
@@ -424,7 +577,7 @@
&new_headers));
}
-TEST_F(SpdyFramerTest, OutOfOrderHeaders) {
+TEST_F(SpdyFramerSpdy2Test, OutOfOrderHeaders) {
// Frame builder with plentiful buffer size.
SpdyFrameBuilder frame(1024);
@@ -435,12 +588,19 @@
frame.WriteUInt32(0); // Associated stream id
frame.WriteUInt16(0); // Priority.
- frame.WriteUInt16(2); // Number of headers.
- SpdyHeaderBlock::iterator it;
- frame.WriteString("gamma");
- frame.WriteString("gamma");
- frame.WriteString("alpha");
- frame.WriteString("alpha");
+ if (SPDY_VERSION_FOR_TESTS < 3) {
+ frame.WriteUInt16(2); // Number of headers.
+ frame.WriteString("gamma");
+ frame.WriteString("gamma");
+ frame.WriteString("alpha");
+ frame.WriteString("alpha");
+ } else {
+ frame.WriteUInt32(2); // Number of headers.
+ frame.WriteStringPiece32("gamma");
+ frame.WriteStringPiece32("gamma");
+ frame.WriteStringPiece32("alpha");
+ frame.WriteStringPiece32("alpha");
+ }
// write the length
frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize);
@@ -449,14 +609,85 @@
SpdySynStreamControlFrame syn_frame(control_frame->data(), false);
std::string serialized_headers(syn_frame.header_block(),
syn_frame.header_block_len());
- SpdyFramer framer;
+ SpdyFramer framer(kVer);
framer.set_enable_compression(false);
EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
serialized_headers.size(),
&new_headers));
}
-TEST_F(SpdyFramerTest, DuplicateHeader) {
+TEST_F(SpdyFramerSpdy2Test, CreateCredential) {
+ SpdyFramer framer(kVer);
+
+ {
+ const char kDescription[] = "CREDENTIAL frame";
+ const unsigned char kFrameData[] = {
+ 0x80, kVer, 0x00, 0x0A,
+ 0x00, 0x00, 0x00, 0x33,
+ 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x05, 'p', 'r',
+ 'o', 'o', 'f', 0x00,
+ 0x00, 0x00, 0x06, 'a',
+ ' ', 'c', 'e', 'r',
+ 't', 0x00, 0x00, 0x00,
+ 0x0C, 'a', 'n', 'o',
+ 't', 'h', 'e', 'r',
+ ' ', 'c', 'e', 'r',
+ 't', 0x00, 0x00, 0x00,
+ 0x0A, 'f', 'i', 'n',
+ 'a', 'l', ' ', 'c',
+ 'e', 'r', 't',
+ };
+ SpdyCredential credential;
+ credential.slot = 3;
+ credential.proof = "proof";
+ credential.certs.push_back("a cert");
+ credential.certs.push_back("another cert");
+ credential.certs.push_back("final cert");
+ scoped_ptr<SpdyFrame> frame(framer.CreateCredentialFrame(credential));
+ CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ }
+}
+
+TEST_F(SpdyFramerSpdy2Test, ParseCredentialFrameData) {
+ SpdyFramer framer(kVer);
+
+ {
+ unsigned char kFrameData[] = {
+ 0x80, kVer, 0x00, 0x0A,
+ 0x00, 0x00, 0x00, 0x33,
+ 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x05, 'p', 'r',
+ 'o', 'o', 'f', 0x00,
+ 0x00, 0x00, 0x06, 'a',
+ ' ', 'c', 'e', 'r',
+ 't', 0x00, 0x00, 0x00,
+ 0x0C, 'a', 'n', 'o',
+ 't', 'h', 'e', 'r',
+ ' ', 'c', 'e', 'r',
+ 't', 0x00, 0x00, 0x00,
+ 0x0A, 'f', 'i', 'n',
+ 'a', 'l', ' ', 'c',
+ 'e', 'r', 't',
+ };
+ SpdyCredentialControlFrame frame(reinterpret_cast<char*>(kFrameData),
+ false);
+ SpdyCredential credential;
+ EXPECT_TRUE(SpdyFramer::ParseCredentialData(frame.payload(), frame.length(),
+ &credential));
+ EXPECT_EQ(3u, credential.slot);
+ EXPECT_EQ("proof", credential.proof);
+ EXPECT_EQ("a cert", credential.certs.front());
+ credential.certs.erase(credential.certs.begin());
+ EXPECT_EQ("another cert", credential.certs.front());
+ credential.certs.erase(credential.certs.begin());
+ EXPECT_EQ("final cert", credential.certs.front());
+ credential.certs.erase(credential.certs.begin());
+ EXPECT_TRUE(credential.certs.empty());
+ }
+}
+
+TEST_F(SpdyFramerSpdy2Test, DuplicateHeader) {
// Frame builder with plentiful buffer size.
SpdyFrameBuilder frame(1024);
@@ -467,12 +698,19 @@
frame.WriteUInt32(0); // associated stream id
frame.WriteUInt16(0); // Priority.
- frame.WriteUInt16(2); // Number of headers.
- SpdyHeaderBlock::iterator it;
- frame.WriteString("name");
- frame.WriteString("value1");
- frame.WriteString("name");
- frame.WriteString("value2");
+ if (SPDY_VERSION_FOR_TESTS < 3) {
+ frame.WriteUInt16(2); // Number of headers.
+ frame.WriteString("name");
+ frame.WriteString("value1");
+ frame.WriteString("name");
+ frame.WriteString("value2");
+ } else {
+ frame.WriteUInt32(2); // Number of headers.
+ frame.WriteStringPiece32("name");
+ frame.WriteStringPiece32("value1");
+ frame.WriteStringPiece32("name");
+ frame.WriteStringPiece32("value2");
+ }
// write the length
frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize);
@@ -481,7 +719,7 @@
SpdySynStreamControlFrame syn_frame(control_frame->data(), false);
std::string serialized_headers(syn_frame.header_block(),
syn_frame.header_block_len());
- SpdyFramer framer;
+ SpdyFramer framer(kVer);
framer.set_enable_compression(false);
// This should fail because duplicate headers are verboten by the spec.
EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
@@ -489,7 +727,7 @@
&new_headers));
}
-TEST_F(SpdyFramerTest, MultiValueHeader) {
+TEST_F(SpdyFramerSpdy2Test, MultiValueHeader) {
// Frame builder with plentiful buffer size.
SpdyFrameBuilder frame(1024);
@@ -500,11 +738,16 @@
frame.WriteUInt32(0); // associated stream id
frame.WriteUInt16(0); // Priority.
- frame.WriteUInt16(1); // Number of headers.
- SpdyHeaderBlock::iterator it;
- frame.WriteString("name");
std::string value("value1\0value2");
- frame.WriteString(value);
+ if (SPDY_VERSION_FOR_TESTS < 3) {
+ frame.WriteUInt16(1); // Number of headers.
+ frame.WriteString("name");
+ frame.WriteString(value);
+ } else {
+ frame.WriteUInt32(1); // Number of headers.
+ frame.WriteStringPiece32("name");
+ frame.WriteStringPiece32(value);
+ }
// write the length
frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize);
@@ -513,7 +756,7 @@
SpdySynStreamControlFrame syn_frame(control_frame->data(), false);
std::string serialized_headers(syn_frame.header_block(),
syn_frame.header_block_len());
- SpdyFramer framer;
+ SpdyFramer framer(kVer);
framer.set_enable_compression(false);
EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
serialized_headers.size(),
@@ -522,7 +765,7 @@
EXPECT_EQ(value, new_headers.find("name")->second);
}
-TEST_F(SpdyFramerTest, BasicCompression) {
+TEST_F(SpdyFramerSpdy2Test, BasicCompression) {
SpdyHeaderBlock headers;
headers["server"] = "SpdyServer 1.0";
headers["date"] = "Mon 12 Jan 2009 12:12:12 PST";
@@ -531,7 +774,7 @@
headers["content-type"] = "text/html";
headers["content-length"] = "12";
- SpdyFramer framer;
+ SpdyFramer framer(kVer);
framer.set_enable_compression(true);
scoped_ptr<SpdySynStreamControlFrame>
frame1(framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, true,
@@ -544,10 +787,12 @@
EXPECT_LE(frame2->length(), frame1->length());
// Decompress the first frame
- scoped_ptr<SpdyFrame> frame3(framer.DecompressFrame(*frame1.get()));
+ scoped_ptr<SpdyFrame> frame3(SpdyFramerTestUtil::DecompressFrame(
+ &framer, *frame1.get()));
// Decompress the second frame
- scoped_ptr<SpdyFrame> frame4(framer.DecompressFrame(*frame2.get()));
+ scoped_ptr<SpdyFrame> frame4(SpdyFramerTestUtil::DecompressFrame(
+ &framer, *frame2.get()));
// Expect frames 3 & 4 to be the same.
EXPECT_EQ(0,
@@ -566,30 +811,9 @@
SpdyFrame::kHeaderSize + uncompressed_frame->length()));
}
-TEST_F(SpdyFramerTest, DecompressUncompressedFrame) {
- SpdyHeaderBlock headers;
- headers["server"] = "SpdyServer 1.0";
- headers["date"] = "Mon 12 Jan 2009 12:12:12 PST";
- headers["status"] = "200";
- headers["version"] = "HTTP/1.1";
- headers["content-type"] = "text/html";
- headers["content-length"] = "12";
-
- SpdyFramer framer;
- framer.set_enable_compression(true);
- scoped_ptr<SpdySynStreamControlFrame>
- frame1(framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, false,
- &headers));
-
- // Decompress the frame
- scoped_ptr<SpdyFrame> frame2(framer.DecompressFrame(*frame1.get()));
-
- EXPECT_EQ(NULL, frame2.get());
-}
-
-TEST_F(SpdyFramerTest, Basic) {
- const unsigned char input[] = {
- 0x80, 0x02, 0x00, 0x01, // SYN Stream #1
+TEST_F(SpdyFramerSpdy2Test, Basic) {
+ const unsigned char kV2Input[] = {
+ 0x80, kVer, 0x00, 0x01, // SYN Stream #1
0x00, 0x00, 0x00, 0x14,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
@@ -597,7 +821,7 @@
0x00, 0x02, 'h', 'h',
0x00, 0x02, 'v', 'v',
- 0x80, 0x02, 0x00, 0x08, // HEADERS on Stream #1
+ 0x80, kVer, 0x00, 0x08, // HEADERS on Stream #1
0x00, 0x00, 0x00, 0x18,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x02,
@@ -608,11 +832,11 @@
0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
0x00, 0x00, 0x00, 0x0c,
- 0xde, 0xad, 0xbe, 0xef,
- 0xde, 0xad, 0xbe, 0xef,
- 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef,
- 0x80, 0x02, 0x00, 0x01, // SYN Stream #3
+ 0x80, kVer, 0x00, 0x01, // SYN Stream #3
0x00, 0x00, 0x00, 0x0c,
0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x00,
@@ -620,14 +844,14 @@
0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
0x00, 0x00, 0x00, 0x08,
- 0xde, 0xad, 0xbe, 0xef,
- 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef,
0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
0x00, 0x00, 0x00, 0x04,
- 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef,
- 0x80, 0x02, 0x00, 0x03, // RST_STREAM on Stream #1
+ 0x80, kVer, 0x00, 0x03, // RST_STREAM on Stream #1
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
@@ -635,14 +859,77 @@
0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
0x00, 0x00, 0x00, 0x00,
- 0x80, 0x02, 0x00, 0x03, // RST_STREAM on Stream #3
+ 0x80, kVer, 0x00, 0x03, // RST_STREAM on Stream #3
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x00,
};
+ const unsigned char kV3Input[] = {
+ 0x80, kVer, 0x00, 0x01, // SYN Stream #1
+ 0x00, 0x00, 0x00, 0x1a,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x02, 'h', 'h',
+ 0x00, 0x00, 0x00, 0x02,
+ 'v', 'v',
+
+ 0x80, kVer, 0x00, 0x08, // HEADERS on Stream #1
+ 0x00, 0x00, 0x00, 0x22,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x02, 'h', '2',
+ 0x00, 0x00, 0x00, 0x02,
+ 'v', '2', 0x00, 0x00,
+ 0x00, 0x02, 'h', '3',
+ 0x00, 0x00, 0x00, 0x02,
+ 'v', '3',
+
+ 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
+ 0x00, 0x00, 0x00, 0x0c,
+ 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef,
+
+ 0x80, kVer, 0x00, 0x01, // SYN Stream #3
+ 0x00, 0x00, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
+ 0x00, 0x00, 0x00, 0x08,
+ 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef,
+
+ 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
+ 0x00, 0x00, 0x00, 0x04,
+ 0xde, 0xad, 0xbe, 0xef,
+
+ 0x80, kVer, 0x00, 0x03, // RST_STREAM on Stream #1
+ 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
+ 0x00, 0x00, 0x00, 0x00,
+
+ 0x80, kVer, 0x00, 0x03, // RST_STREAM on Stream #3
+ 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00,
+ };
+
TestSpdyVisitor visitor;
- visitor.SimulateInFramer(input, sizeof(input));
+ if (SPDY_VERSION_FOR_TESTS < 3) {
+ visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
+ } else {
+ visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
+ }
EXPECT_EQ(0, visitor.error_count_);
EXPECT_EQ(2, visitor.syn_frame_count_);
@@ -656,9 +943,9 @@
}
// Test that the FIN flag on a data frame signifies EOF.
-TEST_F(SpdyFramerTest, FinOnDataFrame) {
- const unsigned char input[] = {
- 0x80, 0x02, 0x00, 0x01, // SYN Stream #1
+TEST_F(SpdyFramerSpdy2Test, FinOnDataFrame) {
+ const unsigned char kV2Input[] = {
+ 0x80, kVer, 0x00, 0x01, // SYN Stream #1
0x00, 0x00, 0x00, 0x14,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
@@ -666,7 +953,7 @@
0x00, 0x02, 'h', 'h',
0x00, 0x02, 'v', 'v',
- 0x80, 0x02, 0x00, 0x02, // SYN REPLY Stream #1
+ 0x80, kVer, 0x00, 0x02, // SYN REPLY Stream #1
0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
@@ -683,9 +970,43 @@
0x01, 0x00, 0x00, 0x04,
0xde, 0xad, 0xbe, 0xef,
};
+ const unsigned char kV3Input[] = {
+ 0x80, kVer, 0x00, 0x01, // SYN Stream #1
+ 0x00, 0x00, 0x00, 0x1a,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x02, 'h', 'h',
+ 0x00, 0x00, 0x00, 0x02,
+ 'v', 'v',
+ 0x80, kVer, 0x00, 0x02, // SYN REPLY Stream #1
+ 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x02, 'a', 'a',
+ 0x00, 0x00, 0x00, 0x02,
+ 'b', 'b',
+
+ 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
+ 0x00, 0x00, 0x00, 0x0c,
+ 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef,
+
+ 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1, with EOF
+ 0x01, 0x00, 0x00, 0x04,
+ 0xde, 0xad, 0xbe, 0xef,
+ };
+
TestSpdyVisitor visitor;
- visitor.SimulateInFramer(input, sizeof(input));
+ if (SPDY_VERSION_FOR_TESTS < 3) {
+ visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
+ } else {
+ visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
+ }
EXPECT_EQ(0, visitor.error_count_);
EXPECT_EQ(1, visitor.syn_frame_count_);
@@ -699,9 +1020,9 @@
}
// Test that the FIN flag on a SYN reply frame signifies EOF.
-TEST_F(SpdyFramerTest, FinOnSynReplyFrame) {
- const unsigned char input[] = {
- 0x80, 0x02, 0x00, 0x01, // SYN Stream #1
+TEST_F(SpdyFramerSpdy2Test, FinOnSynReplyFrame) {
+ const unsigned char kV2Input[] = {
+ 0x80, kVer, 0x00, 0x01, // SYN Stream #1
0x00, 0x00, 0x00, 0x14,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
@@ -709,7 +1030,7 @@
0x00, 0x02, 'h', 'h',
0x00, 0x02, 'v', 'v',
- 0x80, 0x02, 0x00, 0x02, // SYN REPLY Stream #1
+ 0x80, kVer, 0x00, 0x02, // SYN REPLY Stream #1
0x01, 0x00, 0x00, 0x14,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
@@ -717,9 +1038,34 @@
0x00, 0x02, 'a', 'a',
0x00, 0x02, 'b', 'b',
};
+ const unsigned char kV3Input[] = {
+ 0x80, kVer, 0x00, 0x01, // SYN Stream #1
+ 0x00, 0x00, 0x00, 0x1a,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x02, 'h', 'h',
+ 0x00, 0x00, 0x00, 0x02,
+ 'v', 'v',
+ 0x80, kVer, 0x00, 0x02, // SYN REPLY Stream #1
+ 0x01, 0x00, 0x00, 0x1a,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x02, 'a', 'a',
+ 0x00, 0x00, 0x00, 0x02,
+ 'b', 'b',
+ };
+
TestSpdyVisitor visitor;
- visitor.SimulateInFramer(input, sizeof(input));
+ if (SPDY_VERSION_FOR_TESTS < 3) {
+ visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
+ } else {
+ visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
+ }
EXPECT_EQ(0, visitor.error_count_);
EXPECT_EQ(1, visitor.syn_frame_count_);
@@ -732,9 +1078,9 @@
EXPECT_EQ(0, visitor.data_frame_count_);
}
-TEST_F(SpdyFramerTest, HeaderCompression) {
- SpdyFramer send_framer;
- SpdyFramer recv_framer;
+TEST_F(SpdyFramerSpdy2Test, HeaderCompression) {
+ SpdyFramer send_framer(kVer);
+ SpdyFramer recv_framer(kVer);
send_framer.set_enable_compression(true);
recv_framer.set_enable_compression(true);
@@ -751,33 +1097,30 @@
block[kHeader1] = kValue1;
block[kHeader2] = kValue2;
SpdyControlFlags flags(CONTROL_FLAG_NONE);
- scoped_ptr<spdy::SpdyFrame> syn_frame_1(
+ scoped_ptr<SpdySynStreamControlFrame> syn_frame_1(
send_framer.CreateSynStream(1, 0, 0, flags, true, &block));
EXPECT_TRUE(syn_frame_1.get() != NULL);
// SYN_STREAM #2
block[kHeader3] = kValue3;
- scoped_ptr<spdy::SpdyFrame> syn_frame_2(
+ scoped_ptr<SpdySynStreamControlFrame> syn_frame_2(
send_framer.CreateSynStream(3, 0, 0, flags, true, &block));
EXPECT_TRUE(syn_frame_2.get() != NULL);
// Now start decompressing
scoped_ptr<SpdyFrame> decompressed;
- scoped_ptr<SpdyFrame> decompressed_syn_frame;
- SpdySynStreamControlFrame* syn_frame;
+ scoped_ptr<SpdySynStreamControlFrame> syn_frame;
scoped_ptr<std::string> serialized_headers;
SpdyHeaderBlock decompressed_headers;
// Decompress SYN_STREAM #1
- decompressed.reset(recv_framer.DecompressFrame(*syn_frame_1.get()));
+ decompressed.reset(SpdyFramerTestUtil::DecompressFrame(
+ &recv_framer, *syn_frame_1.get()));
EXPECT_TRUE(decompressed.get() != NULL);
EXPECT_TRUE(decompressed->is_control_frame());
EXPECT_EQ(SYN_STREAM,
reinterpret_cast<SpdyControlFrame*>(decompressed.get())->type());
- decompressed_syn_frame.reset(
- new SpdySynStreamControlFrame(decompressed->data(), false));
- syn_frame = reinterpret_cast<SpdySynStreamControlFrame*>(
- decompressed_syn_frame.get());
+ syn_frame.reset(new SpdySynStreamControlFrame(decompressed->data(), false));
serialized_headers.reset(new std::string(syn_frame->header_block(),
syn_frame->header_block_len()));
EXPECT_TRUE(recv_framer.ParseHeaderBlockInBuffer(serialized_headers->c_str(),
@@ -788,15 +1131,13 @@
EXPECT_EQ(kValue2, decompressed_headers[kHeader2]);
// Decompress SYN_STREAM #2
- decompressed.reset(recv_framer.DecompressFrame(*syn_frame_2.get()));
+ decompressed.reset(SpdyFramerTestUtil::DecompressFrame(
+ &recv_framer, *syn_frame_2.get()));
EXPECT_TRUE(decompressed.get() != NULL);
EXPECT_TRUE(decompressed->is_control_frame());
EXPECT_EQ(SYN_STREAM,
reinterpret_cast<SpdyControlFrame*>(decompressed.get())->type());
- decompressed_syn_frame.reset(
- new SpdySynStreamControlFrame(decompressed->data(), false));
- syn_frame = reinterpret_cast<SpdySynStreamControlFrame*>(
- decompressed_syn_frame.get());
+ syn_frame.reset(new SpdySynStreamControlFrame(decompressed->data(), false));
serialized_headers.reset(new std::string(syn_frame->header_block(),
syn_frame->header_block_len()));
decompressed_headers.clear();
@@ -816,8 +1157,8 @@
}
// Verify we don't leak when we leave streams unclosed
-TEST_F(SpdyFramerTest, UnclosedStreamDataCompressors) {
- SpdyFramer send_framer;
+TEST_F(SpdyFramerSpdy2Test, UnclosedStreamDataCompressors) {
+ SpdyFramer send_framer(kVer);
send_framer.set_enable_compression(true);
@@ -830,7 +1171,7 @@
block[kHeader1] = kValue1;
block[kHeader2] = kValue2;
SpdyControlFlags flags(CONTROL_FLAG_NONE);
- scoped_ptr<spdy::SpdyFrame> syn_frame(
+ scoped_ptr<SpdyFrame> syn_frame(
send_framer.CreateSynStream(1, 0, 0, flags, true, &block));
EXPECT_TRUE(syn_frame.get() != NULL);
@@ -838,7 +1179,7 @@
scoped_ptr<SpdyFrame> send_frame(
send_framer.CreateDataFrame(
1, bytes, arraysize(bytes),
- DATA_FLAG_FIN));
+ static_cast<SpdyDataFlags>(DATA_FLAG_FIN)));
EXPECT_TRUE(send_frame.get() != NULL);
// Run the inputs through the framer.
@@ -867,12 +1208,76 @@
EXPECT_EQ(0, send_framer.num_stream_decompressors());
}
-TEST_F(SpdyFramerTest, WindowUpdateFrame) {
+// Verify we can decompress the stream even if handed over to the
+// framer 1 byte at a time.
+TEST_F(SpdyFramerSpdy2Test, UnclosedStreamDataCompressorsOneByteAtATime) {
+ SpdyFramer send_framer(kVer);
+
+ send_framer.set_enable_compression(true);
+
+ const char kHeader1[] = "header1";
+ const char kHeader2[] = "header2";
+ const char kValue1[] = "value1";
+ const char kValue2[] = "value2";
+
+ SpdyHeaderBlock block;
+ block[kHeader1] = kValue1;
+ block[kHeader2] = kValue2;
+ SpdyControlFlags flags(CONTROL_FLAG_NONE);
+ scoped_ptr<SpdyFrame> syn_frame(
+ send_framer.CreateSynStream(1, 0, 0, flags, true, &block));
+ EXPECT_TRUE(syn_frame.get() != NULL);
+
+ const char bytes[] = "this is a test test test test test!";
+ scoped_ptr<SpdyFrame> send_frame(
+ send_framer.CreateDataFrame(
+ 1, bytes, arraysize(bytes),
+ static_cast<SpdyDataFlags>(DATA_FLAG_FIN)));
+ EXPECT_TRUE(send_frame.get() != NULL);
+
+ // Run the inputs through the framer.
+ TestSpdyVisitor visitor;
+ visitor.use_compression_ = true;
+ const unsigned char* data;
+ data = reinterpret_cast<const unsigned char*>(syn_frame->data());
+ for (size_t idx = 0;
+ idx < syn_frame->length() + SpdyFrame::kHeaderSize;
+ ++idx) {
+ visitor.SimulateInFramer(data + idx, 1);
+ ASSERT_EQ(0, visitor.error_count_);
+ }
+ data = reinterpret_cast<const unsigned char*>(send_frame->data());
+ for (size_t idx = 0;
+ idx < send_frame->length() + SpdyFrame::kHeaderSize;
+ ++idx) {
+ visitor.SimulateInFramer(data + idx, 1);
+ ASSERT_EQ(0, visitor.error_count_);
+ }
+
+ EXPECT_EQ(0, visitor.error_count_);
+ EXPECT_EQ(1, visitor.syn_frame_count_);
+ EXPECT_EQ(0, visitor.syn_reply_frame_count_);
+ EXPECT_EQ(0, visitor.headers_frame_count_);
+ EXPECT_EQ(arraysize(bytes), static_cast<unsigned>(visitor.data_bytes_));
+ EXPECT_EQ(0, visitor.fin_frame_count_);
+ EXPECT_EQ(0, visitor.fin_flag_count_);
+ EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
+ EXPECT_EQ(1, visitor.data_frame_count_);
+
+ // We closed the streams, so all compressors should be down.
+ EXPECT_EQ(0, visitor.framer_.num_stream_compressors());
+ EXPECT_EQ(0, visitor.framer_.num_stream_decompressors());
+ EXPECT_EQ(0, send_framer.num_stream_compressors());
+ EXPECT_EQ(0, send_framer.num_stream_decompressors());
+}
+
+TEST_F(SpdyFramerSpdy2Test, WindowUpdateFrame) {
+ SpdyFramer framer(kVer);
scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame(
- SpdyFramer::CreateWindowUpdate(1, 0x12345678));
+ framer.CreateWindowUpdate(1, 0x12345678));
const unsigned char expected_data_frame[] = {
- 0x80, 0x02, 0x00, 0x09,
+ 0x80, kVer, 0x00, 0x09,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
0x12, 0x34, 0x56, 0x78
@@ -883,8 +1288,8 @@
memcmp(window_update_frame->data(), expected_data_frame, 16));
}
-TEST_F(SpdyFramerTest, CreateDataFrame) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreateDataFrame) {
+ SpdyFramer framer(kVer);
{
const char kDescription[] = "'hello' data frame, no FIN";
@@ -969,8 +1374,8 @@
}
}
-TEST_F(SpdyFramerTest, CreateSynStreamUncompressed) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreateSynStreamUncompressed) {
+ SpdyFramer framer(kVer);
framer.set_enable_compression(false);
{
@@ -980,24 +1385,43 @@
headers["bar"] = "foo";
headers["foo"] = "bar";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x01,
+ const unsigned char kPri =
+ (SPDY_VERSION_FOR_TESTS != 2) ? 0xE0 : 0xC0;
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x01,
0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
- 0xC0, 0x00, 0x00, 0x02,
+ kPri, 0x00, 0x00, 0x02,
0x00, 0x03, 'b', 'a',
'r', 0x00, 0x03, 'f',
'o', 'o', 0x00, 0x03,
'f', 'o', 'o', 0x00,
0x03, 'b', 'a', 'r'
};
- scoped_ptr<SpdyFrame> frame(framer.CreateSynStream(
- 1, 0, SPDY_PRIORITY_LOWEST, CONTROL_FLAG_NONE,
- false, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
- EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(
- reinterpret_cast<const SpdyControlFrame*>(frame.get())));
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x2a,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ kPri, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x03, 'b', 'a',
+ 'r', 0x00, 0x00, 0x00,
+ 0x03, 'f', 'o', 'o',
+ 0x00, 0x00, 0x00, 0x03,
+ 'f', 'o', 'o', 0x00,
+ 0x00, 0x00, 0x03, 'b',
+ 'a', 'r'
+ };
+ scoped_ptr<SpdySynStreamControlFrame> frame(framer.CreateSynStream(
+ 1, 0, framer.GetLowestPriority(), CONTROL_FLAG_NONE, false, &headers));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
+ EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(frame.get()));
}
{
@@ -1009,8 +1433,8 @@
headers[""] = "foo";
headers["foo"] = "bar";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x01,
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x01,
0x01, 0x00, 0x00, 0x1D,
0x7f, 0xff, 0xff, 0xff,
0x7f, 0xff, 0xff, 0xff,
@@ -1021,58 +1445,97 @@
0x00, 0x03, 'b', 'a',
'r'
};
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x01,
+ 0x01, 0x00, 0x00, 0x27,
+ 0x7f, 0xff, 0xff, 0xff,
+ 0x7f, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 'f', 'o',
+ 'o', 0x00, 0x00, 0x00,
+ 0x03, 'f', 'o', 'o',
+ 0x00, 0x00, 0x00, 0x03,
+ 'b', 'a', 'r'
+ };
scoped_ptr<SpdyFrame> frame(framer.CreateSynStream(
- 0x7fffffff, 0x7fffffff, SPDY_PRIORITY_HIGHEST, CONTROL_FLAG_FIN,
+ 0x7fffffff, 0x7fffffff, framer.GetHighestPriority(), CONTROL_FLAG_FIN,
false, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
}
{
const char kDescription[] =
- "SYN_STREAM frame with a 0-length header val, highest pri, FIN, "
+ "SYN_STREAM frame with a 0-length header val, high pri, FIN, "
"max stream ID";
SpdyHeaderBlock headers;
headers["bar"] = "foo";
headers["foo"] = "";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x01,
+ const unsigned char kPri =
+ (SPDY_VERSION_FOR_TESTS != 2) ? 0x20 : 0x40;
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x01,
0x01, 0x00, 0x00, 0x1D,
0x7f, 0xff, 0xff, 0xff,
0x7f, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x02,
+ kPri, 0x00, 0x00, 0x02,
0x00, 0x03, 'b', 'a',
'r', 0x00, 0x03, 'f',
'o', 'o', 0x00, 0x03,
'f', 'o', 'o', 0x00,
0x00
};
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x01,
+ 0x01, 0x00, 0x00, 0x27,
+ 0x7f, 0xff, 0xff, 0xff,
+ 0x7f, 0xff, 0xff, 0xff,
+ kPri, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x03, 'b', 'a',
+ 'r', 0x00, 0x00, 0x00,
+ 0x03, 'f', 'o', 'o',
+ 0x00, 0x00, 0x00, 0x03,
+ 'f', 'o', 'o', 0x00,
+ 0x00, 0x00, 0x00
+ };
scoped_ptr<SpdyFrame> frame(framer.CreateSynStream(
- 0x7fffffff, 0x7fffffff, SPDY_PRIORITY_HIGHEST, CONTROL_FLAG_FIN,
- false, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ 0x7fffffff, 0x7fffffff, 1, CONTROL_FLAG_FIN, false, &headers));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
}
}
-TEST_F(SpdyFramerTest, CreateSynStreamCompressed) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreateSynStreamCompressed) {
+ SpdyFramer framer(kVer);
framer.set_enable_compression(true);
{
const char kDescription[] =
- "SYN_STREAM frame, lowest pri, no FIN";
+ "SYN_STREAM frame, low pri, no FIN";
SpdyHeaderBlock headers;
headers["bar"] = "foo";
headers["foo"] = "bar";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x01,
+ const SpdyPriority priority =
+ (SPDY_VERSION_FOR_TESTS != 2) ? 4 : 2;
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x01,
0x00, 0x00, 0x00, 0x25,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
- 0xC0, 0x00, 0x38, 0xea,
+ 0x80, 0x00, 0x38, 0xea,
0xdf, 0xa2, 0x51, 0xb2,
0x62, 0x60, 0x62, 0x60,
0x4e, 0x4a, 0x2c, 0x62,
@@ -1081,15 +1544,32 @@
0x00, 0x00, 0x00, 0xff,
0xff
};
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x27,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x38, 0xEA,
+ 0xE3, 0xC6, 0xA7, 0xC2,
+ 0x02, 0xE5, 0x0E, 0x50,
+ 0xC2, 0x4B, 0x4A, 0x04,
+ 0xE5, 0x0B, 0xE6, 0xB4,
+ 0xFC, 0x7C, 0x24, 0x0A,
+ 0x28, 0x08, 0x00, 0x00,
+ 0x00, 0xFF, 0xFF
+ };
scoped_ptr<SpdyFrame> frame(framer.CreateSynStream(
- 1, 0, SPDY_PRIORITY_LOWEST, CONTROL_FLAG_NONE,
- true, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ 1, 0, priority, CONTROL_FLAG_NONE, true, &headers));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
}
}
-TEST_F(SpdyFramerTest, CreateSynReplyUncompressed) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreateSynReplyUncompressed) {
+ SpdyFramer framer(kVer);
framer.set_enable_compression(false);
{
@@ -1099,8 +1579,8 @@
headers["bar"] = "foo";
headers["foo"] = "bar";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x02,
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x02,
0x00, 0x00, 0x00, 0x1C,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x02,
@@ -1110,9 +1590,26 @@
'f', 'o', 'o', 0x00,
0x03, 'b', 'a', 'r'
};
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x24,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x03,
+ 'b', 'a', 'r', 0x00,
+ 0x00, 0x00, 0x03, 'f',
+ 'o', 'o', 0x00, 0x00,
+ 0x00, 0x03, 'f', 'o',
+ 'o', 0x00, 0x00, 0x00,
+ 0x03, 'b', 'a', 'r'
+ };
scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
1, CONTROL_FLAG_NONE, false, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
}
{
@@ -1123,8 +1620,8 @@
headers[""] = "foo";
headers["foo"] = "bar";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x02,
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x02,
0x01, 0x00, 0x00, 0x19,
0x7f, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x02,
@@ -1134,9 +1631,26 @@
0x00, 0x03, 'b', 'a',
'r'
};
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x02,
+ 0x01, 0x00, 0x00, 0x21,
+ 0x7f, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03,
+ 'f', 'o', 'o', 0x00,
+ 0x00, 0x00, 0x03, 'f',
+ 'o', 'o', 0x00, 0x00,
+ 0x00, 0x03, 'b', 'a',
+ 'r'
+ };
scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
}
{
@@ -1147,8 +1661,8 @@
headers["bar"] = "foo";
headers["foo"] = "";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x02,
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x02,
0x01, 0x00, 0x00, 0x19,
0x7f, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x02,
@@ -1158,14 +1672,31 @@
'f', 'o', 'o', 0x00,
0x00
};
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x02,
+ 0x01, 0x00, 0x00, 0x21,
+ 0x7f, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x03,
+ 'b', 'a', 'r', 0x00,
+ 0x00, 0x00, 0x03, 'f',
+ 'o', 'o', 0x00, 0x00,
+ 0x00, 0x03, 'f', 'o',
+ 'o', 0x00, 0x00, 0x00,
+ 0x00
+ };
scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
}
}
-TEST_F(SpdyFramerTest, CreateSynReplyCompressed) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreateSynReplyCompressed) {
+ SpdyFramer framer(kVer);
framer.set_enable_compression(true);
{
@@ -1175,8 +1706,8 @@
headers["bar"] = "foo";
headers["foo"] = "bar";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x02,
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x02,
0x00, 0x00, 0x00, 0x21,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x38, 0xea,
@@ -1188,33 +1719,50 @@
0x00, 0x00, 0x00, 0xff,
0xff
};
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x21,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x38, 0xea, 0xe3, 0xc6,
+ 0xa7, 0xc2, 0x02, 0xe5,
+ 0x0e, 0x50, 0xc2, 0x4b,
+ 0x4a, 0x04, 0xe5, 0x0b,
+ 0xe6, 0xb4, 0xfc, 0x7c,
+ 0x24, 0x0a, 0x28, 0x08,
+ 0x00, 0x00, 0x00, 0xff,
+ 0xff
+ };
scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
1, CONTROL_FLAG_NONE, true, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
}
}
-TEST_F(SpdyFramerTest, CreateRstStream) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreateRstStream) {
+ SpdyFramer framer(kVer);
{
const char kDescription[] = "RST_STREAM frame";
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x03,
+ 0x80, kVer, 0x00, 0x03,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
};
- scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(1, PROTOCOL_ERROR));
+ scoped_ptr<SpdyRstStreamControlFrame> frame(
+ framer.CreateRstStream(1, PROTOCOL_ERROR));
CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
- EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(
- reinterpret_cast<const SpdyControlFrame*>(frame.get())));
+ EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(frame.get()));
}
{
const char kDescription[] = "RST_STREAM frame with max stream ID";
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x03,
+ 0x80, kVer, 0x00, 0x03,
0x00, 0x00, 0x00, 0x08,
0x7f, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x01,
@@ -1227,7 +1775,7 @@
{
const char kDescription[] = "RST_STREAM frame with max status code";
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x03,
+ 0x80, kVer, 0x00, 0x03,
0x00, 0x00, 0x00, 0x08,
0x7f, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x06,
@@ -1238,51 +1786,108 @@
}
}
-TEST_F(SpdyFramerTest, CreateSettings) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreateSettings) {
+ SpdyFramer framer(kVer);
{
+ const char kDescription[] = "Network byte order SETTINGS frame";
+
+ uint32 kValue = 0x0a0b0c0d;
+ uint8 kFlags = 0x04;
+ uint32 kId = 0x030201;
+ SettingsFlagsAndId idAndFlags(kFlags, kId);
+
+ SpdySettings settings;
+ settings.push_back(SpdySetting(idAndFlags, kValue));
+
+ EXPECT_EQ(kValue, settings.back().second);
+ EXPECT_EQ(kFlags, settings.back().first.flags());
+ EXPECT_EQ(kId, settings.back().first.id());
+
+ const unsigned char kFrameDatav2[] = {
+ 0x80, kVer, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x01, 0x02, 0x03, 0x04,
+ 0x0a, 0x0b, 0x0c, 0x0d,
+ };
+
+ const unsigned char kFrameDatav3[] = {
+ 0x80, kVer, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x04, 0x03, 0x02, 0x01,
+ 0x0a, 0x0b, 0x0c, 0x0d,
+ };
+
+ scoped_ptr<SpdySettingsControlFrame> frame(framer.CreateSettings(settings));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kFrameDatav2 : kFrameDatav3,
+ arraysize(kFrameDatav3)); // Size is unchanged among versions.
+ EXPECT_EQ(SpdyFramer::kInvalidStream,
+ SpdyFramer::GetControlFrameStreamId(frame.get()));
+
+ // Make sure that ParseSettings also works as advertised.
+ SpdySettings parsed_settings;
+ EXPECT_TRUE(framer.ParseSettings(frame.get(), &parsed_settings));
+ EXPECT_EQ(settings.size(), parsed_settings.size());
+ EXPECT_EQ(kFlags, parsed_settings.back().first.flags());
+ EXPECT_EQ(kId, parsed_settings.back().first.id());
+ }
+
+ {
const char kDescription[] = "Basic SETTINGS frame";
SpdySettings settings;
- settings.push_back(SpdySetting(0x00000000, 0x00000000));
- settings.push_back(SpdySetting(0xffffffff, 0x00000001));
- settings.push_back(SpdySetting(0xff000001, 0x00000002));
+ settings.push_back(
+ SpdySettingFromWireFormat(0x00000000, 0x00000000)); // 1st Setting
+ settings.push_back(
+ SpdySettingFromWireFormat(0xffffffff, 0x00000001)); // 2nd Setting
+ settings.push_back(
+ SpdySettingFromWireFormat(0xff000001, 0x00000002)); // 3rd Setting
// Duplicates allowed
- settings.push_back(SpdySetting(0x01000002, 0x00000003));
- settings.push_back(SpdySetting(0x01000002, 0x00000003));
+ settings.push_back(
+ SpdySettingFromWireFormat(0x01000002, 0x00000003)); // 4th Setting
+ settings.push_back(
+ SpdySettingFromWireFormat(0x01000002, 0x00000003)); // 5th Setting
- settings.push_back(SpdySetting(0x01000003, 0x000000ff));
- settings.push_back(SpdySetting(0x01000004, 0xff000001));
- settings.push_back(SpdySetting(0x01000004, 0xffffffff));
+ settings.push_back(
+ SpdySettingFromWireFormat(0x01000003, 0x000000ff)); // 6th Setting
+ settings.push_back(
+ SpdySettingFromWireFormat(0x01000004, 0xff000001)); // 7th Setting
+ settings.push_back(
+ SpdySettingFromWireFormat(0x01000004, 0xffffffff)); // 8th Setting
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x04,
+ 0x80, kVer, 0x00, 0x04,
0x00, 0x00, 0x00, 0x44,
0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, // 1st Setting
0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, // 2nd Setting
0x00, 0x00, 0x00, 0x01,
- 0xff, 0x00, 0x00, 0x01,
+ 0x01, 0x00, 0x00, 0xff, // 3rd Setting
0x00, 0x00, 0x00, 0x02,
- 0x01, 0x00, 0x00, 0x02,
+ 0x02, 0x00, 0x00, 0x01, // 4th Setting
0x00, 0x00, 0x00, 0x03,
- 0x01, 0x00, 0x00, 0x02,
+ 0x02, 0x00, 0x00, 0x01, // 5th Setting
0x00, 0x00, 0x00, 0x03,
- 0x01, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x00, 0x01, // 6th Setting
0x00, 0x00, 0x00, 0xff,
- 0x01, 0x00, 0x00, 0x04,
+ 0x04, 0x00, 0x00, 0x01, // 7th Setting
0xff, 0x00, 0x00, 0x01,
- 0x01, 0x00, 0x00, 0x04,
+ 0x04, 0x00, 0x00, 0x01, // 8th Setting
0xff, 0xff, 0xff, 0xff,
};
- scoped_ptr<SpdyFrame> frame(framer.CreateSettings(settings));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ scoped_ptr<SpdySettingsControlFrame> frame(framer.CreateSettings(settings));
+ CompareFrame(kDescription,
+ *frame,
+ kFrameData,
+ arraysize(kFrameData));
EXPECT_EQ(SpdyFramer::kInvalidStream,
- SpdyFramer::GetControlFrameStreamId(
- reinterpret_cast<const SpdyControlFrame*>(frame.get())));
+ SpdyFramer::GetControlFrameStreamId(frame.get()));
}
{
@@ -1291,7 +1896,7 @@
SpdySettings settings;
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x04,
+ 0x80, kVer, 0x00, 0x04,
0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00,
};
@@ -1300,62 +1905,43 @@
}
}
-TEST_F(SpdyFramerTest, CreateNopFrame) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreatePingFrame) {
+ SpdyFramer framer(kVer);
{
- const char kDescription[] = "NOOP frame";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x00,
- };
- scoped_ptr<SpdyFrame> frame(framer.CreateNopFrame());
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
- EXPECT_EQ(SpdyFramer::kInvalidStream,
- SpdyFramer::GetControlFrameStreamId(
- reinterpret_cast<const SpdyControlFrame*>(frame.get())));
- }
-}
-
-TEST_F(SpdyFramerTest, CreatePingFrame) {
- SpdyFramer framer;
-
- {
const char kDescription[] = "PING frame";
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x06,
+ 0x80, kVer, 0x00, 0x06,
0x00, 0x00, 0x00, 0x04,
0x12, 0x34, 0x56, 0x78,
};
- scoped_ptr<SpdyFrame> frame(framer.CreatePingFrame(0x12345678u));
+ scoped_ptr<SpdyPingControlFrame> frame(framer.CreatePingFrame(0x12345678u));
CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
EXPECT_EQ(SpdyFramer::kInvalidStream,
- SpdyFramer::GetControlFrameStreamId(
- reinterpret_cast<const SpdyControlFrame*>(frame.get())));
+ SpdyFramer::GetControlFrameStreamId(frame.get()));
}
}
-TEST_F(SpdyFramerTest, CreateGoAway) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreateGoAway) {
+ SpdyFramer framer(kVer);
{
const char kDescription[] = "GOAWAY frame";
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x07,
+ 0x80, kVer, 0x00, 0x07,
0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00,
};
- scoped_ptr<SpdyFrame> frame(framer.CreateGoAway(0));
+ scoped_ptr<SpdyGoAwayControlFrame> frame(framer.CreateGoAway(0));
CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
EXPECT_EQ(SpdyFramer::kInvalidStream,
- SpdyFramer::GetControlFrameStreamId(
- reinterpret_cast<const SpdyControlFrame*>(frame.get())));
+ SpdyFramer::GetControlFrameStreamId(frame.get()));
}
{
const char kDescription[] = "GOAWAY frame with max stream ID";
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x07,
+ 0x80, kVer, 0x00, 0x07,
0x00, 0x00, 0x00, 0x04,
0x7f, 0xff, 0xff, 0xff,
};
@@ -1364,8 +1950,8 @@
}
}
-TEST_F(SpdyFramerTest, CreateHeadersUncompressed) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreateHeadersUncompressed) {
+ SpdyFramer framer(kVer);
framer.set_enable_compression(false);
{
@@ -1375,8 +1961,8 @@
headers["bar"] = "foo";
headers["foo"] = "bar";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x08,
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x08,
0x00, 0x00, 0x00, 0x1C,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x02,
@@ -1386,9 +1972,26 @@
'f', 'o', 'o', 0x00,
0x03, 'b', 'a', 'r'
};
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x24,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x03,
+ 'b', 'a', 'r', 0x00,
+ 0x00, 0x00, 0x03, 'f',
+ 'o', 'o', 0x00, 0x00,
+ 0x00, 0x03, 'f', 'o',
+ 'o', 0x00, 0x00, 0x00,
+ 0x03, 'b', 'a', 'r'
+ };
scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
1, CONTROL_FLAG_NONE, false, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
}
{
@@ -1399,8 +2002,8 @@
headers[""] = "foo";
headers["foo"] = "bar";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x08,
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x08,
0x01, 0x00, 0x00, 0x19,
0x7f, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x02,
@@ -1410,9 +2013,26 @@
0x00, 0x03, 'b', 'a',
'r'
};
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x08,
+ 0x01, 0x00, 0x00, 0x21,
+ 0x7f, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03,
+ 'f', 'o', 'o', 0x00,
+ 0x00, 0x00, 0x03, 'f',
+ 'o', 'o', 0x00, 0x00,
+ 0x00, 0x03, 'b', 'a',
+ 'r'
+ };
scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
}
{
@@ -1423,8 +2043,8 @@
headers["bar"] = "foo";
headers["foo"] = "";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x08,
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x08,
0x01, 0x00, 0x00, 0x19,
0x7f, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x02,
@@ -1434,14 +2054,31 @@
'f', 'o', 'o', 0x00,
0x00
};
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x08,
+ 0x01, 0x00, 0x00, 0x21,
+ 0x7f, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x03,
+ 'b', 'a', 'r', 0x00,
+ 0x00, 0x00, 0x03, 'f',
+ 'o', 'o', 0x00, 0x00,
+ 0x00, 0x03, 'f', 'o',
+ 'o', 0x00, 0x00, 0x00,
+ 0x00
+ };
scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
}
}
-TEST_F(SpdyFramerTest, CreateHeadersCompressed) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreateHeadersCompressed) {
+ SpdyFramer framer(kVer);
framer.set_enable_compression(true);
{
@@ -1451,8 +2088,8 @@
headers["bar"] = "foo";
headers["foo"] = "bar";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x08,
+ const unsigned char kV2FrameData[] = {
+ 0x80, kVer, 0x00, 0x08,
0x00, 0x00, 0x00, 0x21,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x38, 0xea,
@@ -1464,33 +2101,50 @@
0x00, 0x00, 0x00, 0xff,
0xff
};
+ const unsigned char kV3FrameData[] = {
+ 0x80, kVer, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x21,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x38, 0xea, 0xe3, 0xc6,
+ 0xa7, 0xc2, 0x02, 0xe5,
+ 0x0e, 0x50, 0xc2, 0x4b,
+ 0x4a, 0x04, 0xe5, 0x0b,
+ 0xe6, 0xb4, 0xfc, 0x7c,
+ 0x24, 0x0a, 0x28, 0x08,
+ 0x00, 0x00, 0x00, 0xff,
+ 0xff
+ };
scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
1, CONTROL_FLAG_NONE, true, &headers));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+ CompareFrame(kDescription,
+ *frame,
+ (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
+ (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
+ : arraysize(kV3FrameData));
}
}
-TEST_F(SpdyFramerTest, CreateWindowUpdate) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, CreateWindowUpdate) {
+ SpdyFramer framer(kVer);
{
const char kDescription[] = "WINDOW_UPDATE frame";
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x09,
+ 0x80, kVer, 0x00, 0x09,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
};
- scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(1, 1));
+ scoped_ptr<SpdyWindowUpdateControlFrame> frame(
+ framer.CreateWindowUpdate(1, 1));
CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
- EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(
- reinterpret_cast<const SpdyControlFrame*>(frame.get())));
+ EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(frame.get()));
}
{
const char kDescription[] = "WINDOW_UPDATE frame with max stream ID";
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x09,
+ 0x80, kVer, 0x00, 0x09,
0x00, 0x00, 0x00, 0x08,
0x7f, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x01,
@@ -1502,7 +2156,7 @@
{
const char kDescription[] = "WINDOW_UPDATE frame with max window delta";
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x09,
+ 0x80, kVer, 0x00, 0x09,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
0x7f, 0xff, 0xff, 0xff,
@@ -1512,85 +2166,13 @@
}
}
-TEST_F(SpdyFramerTest, CreateCredential) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, DuplicateFrame) {
+ SpdyFramer framer(kVer);
{
- const char kDescription[] = "CREDENTIAL frame";
- const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x0A,
- 0x00, 0x00, 0x00, 0x33,
- 0x00, 0x03, 0x00, 0x00,
- 0x00, 0x05, 'p', 'r',
- 'o', 'o', 'f', 0x00,
- 0x00, 0x00, 0x06, 'a',
- ' ', 'c', 'e', 'r',
- 't', 0x00, 0x00, 0x00,
- 0x0C, 'a', 'n', 'o',
- 't', 'h', 'e', 'r',
- ' ', 'c', 'e', 'r',
- 't', 0x00, 0x00, 0x00,
- 0x0A, 'f', 'i', 'n',
- 'a', 'l', ' ', 'c',
- 'e', 'r', 't',
- };
- SpdyCredential credential;
- credential.slot = 3;
- credential.proof = "proof";
- credential.certs.push_back("a cert");
- credential.certs.push_back("another cert");
- credential.certs.push_back("final cert");
- scoped_ptr<SpdyFrame> frame(framer.CreateCredentialFrame(credential));
- CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
- }
-}
-
-TEST_F(SpdyFramerTest, ParseCredentialFrame) {
- SpdyFramer framer;
-
- {
- unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x0A,
- 0x00, 0x00, 0x00, 0x33,
- 0x00, 0x03, 0x00, 0x00,
- 0x00, 0x05, 'p', 'r',
- 'o', 'o', 'f', 0x00,
- 0x00, 0x00, 0x06, 'a',
- ' ', 'c', 'e', 'r',
- 't', 0x00, 0x00, 0x00,
- 0x0C, 'a', 'n', 'o',
- 't', 'h', 'e', 'r',
- ' ', 'c', 'e', 'r',
- 't', 0x00, 0x00, 0x00,
- 0x0A, 'f', 'i', 'n',
- 'a', 'l', ' ', 'c',
- 'e', 'r', 't',
- };
- SpdyCredentialControlFrame frame(reinterpret_cast<char*>(kFrameData),
- false);
- SpdyCredential credential;
- EXPECT_TRUE(SpdyFramer::ParseCredentialData(frame.payload(),
- frame.length(),
- &credential));
- EXPECT_EQ(3u, credential.slot);
- EXPECT_EQ("proof", credential.proof);
- EXPECT_EQ("a cert", credential.certs.front());
- credential.certs.erase(credential.certs.begin());
- EXPECT_EQ("another cert", credential.certs.front());
- credential.certs.erase(credential.certs.begin());
- EXPECT_EQ("final cert", credential.certs.front());
- credential.certs.erase(credential.certs.begin());
- EXPECT_TRUE(credential.certs.empty());
- }
-}
-
-TEST_F(SpdyFramerTest, DuplicateFrame) {
- SpdyFramer framer;
-
- {
const char kDescription[] = "PING frame";
const unsigned char kFrameData[] = {
- 0x80, 0x02, 0x00, 0x06,
+ 0x80, kVer, 0x00, 0x06,
0x00, 0x00, 0x00, 0x04,
0x12, 0x34, 0x56, 0x78,
};
@@ -1607,7 +2189,7 @@
// the framer to overrun the buffer, and smash other heap contents. This test
// relies on the debug version of the heap manager, which checks for buffer
// overrun errors during delete processing. Regression test for b/2974814.
-TEST_F(SpdyFramerTest, ExpandBuffer_HeapSmash) {
+TEST_F(SpdyFramerSpdy2Test, ExpandBuffer_HeapSmash) {
// Sweep through the area of problematic values, to make sure we always cover
// the danger zone, even if it moves around at bit due to SPDY changes.
for (uint16 val2_len = SpdyFramer::kControlFrameBufferInitialSize - 50;
@@ -1618,7 +2200,7 @@
headers["bar"] = "foo";
headers["foo"] = "baz";
headers["grue"] = val2.c_str();
- SpdyFramer framer;
+ SpdyFramer framer(kVer);
scoped_ptr<SpdySynStreamControlFrame> template_frame(
framer.CreateSynStream(1, // stream_id
0, // associated_stream_id
@@ -1635,14 +2217,158 @@
}
}
-TEST_F(SpdyFramerTest, ReadCredentialFrame) {
+TEST_F(SpdyFramerSpdy2Test, ControlFrameSizesAreValidated) {
+ // Create a GoAway frame that has a few extra bytes at the end.
+ // We create enough overhead to require the framer to expand its frame buffer.
+ size_t overhead = SpdyFramer::kUncompressedControlFrameBufferInitialSize;
+ SpdyFramer framer(kVer);
+ scoped_ptr<SpdyGoAwayControlFrame> goaway(framer.CreateGoAway(1));
+ goaway->set_length(goaway->length() + overhead);
+ std::string pad('A', overhead);
+ TestSpdyVisitor visitor;
+
+ // First attempt without validation on.
+ visitor.framer_.set_validate_control_frame_sizes(false);
+ visitor.SimulateInFramer(
+ reinterpret_cast<unsigned char*>(goaway->data()),
+ goaway->length() - overhead + SpdyControlFrame::kHeaderSize);
+ visitor.SimulateInFramer(
+ reinterpret_cast<const unsigned char*>(pad.c_str()),
+ overhead);
+ EXPECT_EQ(0, visitor.error_count_); // Not an error.
+ EXPECT_EQ(1, visitor.goaway_count_); // The goaway was parsed.
+
+ // Attempt with validation on.
+ visitor.framer_.set_validate_control_frame_sizes(true);
+ visitor.SimulateInFramer(
+ reinterpret_cast<unsigned char*>(goaway->data()),
+ goaway->length() - overhead + SpdyControlFrame::kHeaderSize);
+ visitor.SimulateInFramer(
+ reinterpret_cast<const unsigned char*>(pad.c_str()),
+ overhead);
+ EXPECT_EQ(1, visitor.error_count_); // This generated an error.
+ EXPECT_EQ(1, visitor.goaway_count_); // Unchanged from before.
+}
+
+TEST_F(SpdyFramerSpdy2Test, ReadZeroLenSettingsFrame) {
+ SpdyFramer framer(kVer);
+ SpdySettings settings;
+ scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
+ control_frame->set_length(0);
+ TestSpdyVisitor visitor;
+ visitor.use_compression_ = false;
+ visitor.SimulateInFramer(
+ reinterpret_cast<unsigned char*>(control_frame->data()),
+ control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
+ // Should generate an error, since zero-len settings frames are unsupported.
+ EXPECT_EQ(1, visitor.error_count_);
+}
+
+// Tests handling of SETTINGS frames with invalid length.
+TEST_F(SpdyFramerSpdy2Test, ReadBogusLenSettingsFrame) {
+ SpdyFramer framer(kVer);
+ SpdySettings settings;
+ // Add a setting to pad the frame so that we don't get a buffer overflow when
+ // calling SimulateInFramer() below.
+ settings.push_back(SpdySetting(SettingsFlagsAndId(0, 1), 0x00000002));
+ scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
+ control_frame->set_length(5);
+ TestSpdyVisitor visitor;
+ visitor.use_compression_ = false;
+ visitor.SimulateInFramer(
+ reinterpret_cast<unsigned char*>(control_frame->data()),
+ control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
+ // Should generate an error, since zero-len settings frames are unsupported.
+ EXPECT_EQ(1, visitor.error_count_);
+}
+
+// Tests handling of SETTINGS frames larger than the frame buffer size.
+TEST_F(SpdyFramerSpdy2Test, ReadLargeSettingsFrame) {
+ SpdyFramer framer(kVer);
+ SpdySettings settings;
+ settings.push_back(SpdySetting(SettingsFlagsAndId(0, 1), 0x00000002));
+ settings.push_back(SpdySetting(SettingsFlagsAndId(0, 2), 0x00000003));
+ settings.push_back(SpdySetting(SettingsFlagsAndId(0, 3), 0x00000004));
+ scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
+ EXPECT_LT(SpdyFramer::kUncompressedControlFrameBufferInitialSize,
+ control_frame->length() + SpdyControlFrame::kHeaderSize);
+ TestSpdyVisitor visitor;
+ visitor.use_compression_ = false;
+
+ // Read all at once.
+ visitor.SimulateInFramer(
+ reinterpret_cast<unsigned char*>(control_frame->data()),
+ control_frame->length() + SpdyControlFrame::kHeaderSize);
+ EXPECT_EQ(0, visitor.error_count_);
+ EXPECT_EQ(settings.size(), static_cast<unsigned>(visitor.setting_count_));
+ EXPECT_EQ(1, visitor.settings_frame_count_);
+
+ // Read data in small chunks.
+ size_t framed_data = 0;
+ size_t unframed_data = control_frame->length() +
+ SpdyControlFrame::kHeaderSize;
+ size_t kReadChunkSize = 5; // Read five bytes at a time.
+ while (unframed_data > 0) {
+ size_t to_read = std::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(settings.size() * 2, static_cast<unsigned>(visitor.setting_count_));
+ EXPECT_EQ(2, visitor.settings_frame_count_);
+}
+
+// Tests handling of SETTINGS frame with duplicate entries.
+TEST_F(SpdyFramerSpdy2Test, ReadDuplicateSettings) {
+ SpdyFramer framer(kVer);
+ SpdySettings settings;
+ settings.push_back(SpdySetting(SettingsFlagsAndId(0, 1), 0x00000002));
+ settings.push_back(SpdySetting(SettingsFlagsAndId(0, 1), 0x00000003));
+ // This last setting should not be processed due to error above.
+ settings.push_back(SpdySetting(SettingsFlagsAndId(0, 3), 0x00000003));
+ scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
+ TestSpdyVisitor visitor;
+ visitor.use_compression_ = false;
+
+ visitor.SimulateInFramer(
+ reinterpret_cast<unsigned char*>(control_frame->data()),
+ control_frame->length() + SpdyControlFrame::kHeaderSize);
+ EXPECT_EQ(1, visitor.error_count_);
+ EXPECT_EQ(1, visitor.setting_count_);
+ EXPECT_EQ(1, visitor.settings_frame_count_);
+}
+
+// Tests handling of SETTINGS frame with entries out of order.
+TEST_F(SpdyFramerSpdy2Test, ReadOutOfOrderSettings) {
+ SpdyFramer framer(kVer);
+ SpdySettings settings;
+ settings.push_back(SpdySetting(SettingsFlagsAndId(0, 2), 0x00000002));
+ settings.push_back(SpdySetting(SettingsFlagsAndId(0, 1), 0x00000003));
+ // This last setting should not be processed due to error above.
+ settings.push_back(SpdySetting(SettingsFlagsAndId(0, 3), 0x00000003));
+ scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
+ TestSpdyVisitor visitor;
+ visitor.use_compression_ = false;
+
+ visitor.SimulateInFramer(
+ reinterpret_cast<unsigned char*>(control_frame->data()),
+ control_frame->length() + SpdyControlFrame::kHeaderSize);
+ EXPECT_EQ(1, visitor.error_count_);
+ EXPECT_EQ(1, visitor.setting_count_);
+ EXPECT_EQ(1, visitor.settings_frame_count_);
+}
+
+TEST_F(SpdyFramerSpdy2Test, ReadCredentialFrame) {
SpdyCredential credential;
credential.slot = 3;
credential.proof = "proof";
credential.certs.push_back("a cert");
credential.certs.push_back("another cert");
credential.certs.push_back("final cert");
- SpdyFramer framer;
+ SpdyFramer framer(kVer);
scoped_ptr<SpdyFrame> control_frame(
framer.CreateCredentialFrame(credential));
EXPECT_TRUE(control_frame.get() != NULL);
@@ -1662,14 +2388,14 @@
}
}
-TEST_F(SpdyFramerTest, ReadCredentialFrameWithCorruptProof) {
+TEST_F(SpdyFramerSpdy2Test, ReadCredentialFrameWithCorruptProof) {
SpdyCredential credential;
credential.slot = 3;
credential.proof = "proof";
credential.certs.push_back("a cert");
credential.certs.push_back("another cert");
credential.certs.push_back("final cert");
- SpdyFramer framer;
+ SpdyFramer framer(kVer);
scoped_ptr<SpdyFrame> control_frame(
framer.CreateCredentialFrame(credential));
EXPECT_TRUE(control_frame.get() != NULL);
@@ -1684,14 +2410,14 @@
EXPECT_EQ(1, visitor.error_count_);
}
-TEST_F(SpdyFramerTest, ReadCredentialFrameWithCorruptCertificate) {
+TEST_F(SpdyFramerSpdy2Test, ReadCredentialFrameWithCorruptCertificate) {
SpdyCredential credential;
credential.slot = 3;
credential.proof = "proof";
credential.certs.push_back("a cert");
credential.certs.push_back("another cert");
credential.certs.push_back("final cert");
- SpdyFramer framer;
+ SpdyFramer framer(kVer);
scoped_ptr<SpdyFrame> control_frame(
framer.CreateCredentialFrame(credential));
EXPECT_TRUE(control_frame.get() != NULL);
@@ -1706,8 +2432,8 @@
EXPECT_EQ(1, visitor.error_count_);
}
-TEST_F(SpdyFramerTest, ReadGarbage) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, ReadGarbage) {
+ SpdyFramer framer(kVer);
unsigned char garbage_frame[256];
memset(garbage_frame, ~0, sizeof(garbage_frame));
TestSpdyVisitor visitor;
@@ -1716,12 +2442,12 @@
EXPECT_EQ(1, visitor.error_count_);
}
-TEST_F(SpdyFramerTest, ReadGarbageWithValidVersion) {
- SpdyFramer framer;
+TEST_F(SpdyFramerSpdy2Test, ReadGarbageWithValidVersion) {
+ SpdyFramer framer(kVer);
char garbage_frame[256];
memset(garbage_frame, ~0, sizeof(garbage_frame));
SpdyControlFrame control_frame(&garbage_frame[0], false);
- control_frame.set_version(kSpdyProtocolVersion);
+ control_frame.set_version(SPDY_VERSION_FOR_TESTS);
TestSpdyVisitor visitor;
visitor.use_compression_ = false;
visitor.SimulateInFramer(
@@ -1730,7 +2456,7 @@
EXPECT_EQ(1, visitor.error_count_);
}
-TEST(SpdyFramer, StateToStringTest) {
+TEST_F(SpdyFramerSpdy2Test, StateToStringTest) {
EXPECT_STREQ("ERROR",
SpdyFramer::StateToString(SpdyFramer::SPDY_ERROR));
EXPECT_STREQ("DONE",
@@ -1760,12 +2486,15 @@
EXPECT_STREQ("SPDY_CREDENTIAL_FRAME_PAYLOAD",
SpdyFramer::StateToString(
SpdyFramer::SPDY_CREDENTIAL_FRAME_PAYLOAD));
+ EXPECT_STREQ("SPDY_SETTINGS_FRAME_PAYLOAD",
+ SpdyFramer::StateToString(
+ SpdyFramer::SPDY_SETTINGS_FRAME_PAYLOAD));
EXPECT_STREQ("UNKNOWN_STATE",
SpdyFramer::StateToString(
- SpdyFramer::SPDY_CREDENTIAL_FRAME_PAYLOAD + 1));
+ SpdyFramer::SPDY_SETTINGS_FRAME_PAYLOAD + 1));
}
-TEST(SpdyFramer, ErrorCodeToStringTest) {
+TEST_F(SpdyFramerSpdy2Test, ErrorCodeToStringTest) {
EXPECT_STREQ("NO_ERROR",
SpdyFramer::ErrorCodeToString(SpdyFramer::SPDY_NO_ERROR));
EXPECT_STREQ("INVALID_CONTROL_FRAME",
@@ -1790,7 +2519,7 @@
SpdyFramer::ErrorCodeToString(SpdyFramer::LAST_ERROR));
}
-TEST(SpdyFramer, StatusCodeToStringTest) {
+TEST_F(SpdyFramerSpdy2Test, StatusCodeToStringTest) {
EXPECT_STREQ("INVALID",
SpdyFramer::StatusCodeToString(INVALID));
EXPECT_STREQ("PROTOCOL_ERROR",
@@ -1811,7 +2540,7 @@
SpdyFramer::StatusCodeToString(NUM_STATUS_CODES));
}
-TEST(SpdyFramer, ControlTypeToStringTest) {
+TEST_F(SpdyFramerSpdy2Test, ControlTypeToStringTest) {
EXPECT_STREQ("SYN_STREAM",
SpdyFramer::ControlTypeToString(SYN_STREAM));
EXPECT_STREQ("SYN_REPLY",
@@ -1830,13 +2559,13 @@
SpdyFramer::ControlTypeToString(HEADERS));
EXPECT_STREQ("WINDOW_UPDATE",
SpdyFramer::ControlTypeToString(WINDOW_UPDATE));
- EXPECT_STREQ("SETTINGS",
- SpdyFramer::ControlTypeToString(SETTINGS));
+ EXPECT_STREQ("CREDENTIAL",
+ SpdyFramer::ControlTypeToString(CREDENTIAL));
EXPECT_STREQ("UNKNOWN_CONTROL_TYPE",
SpdyFramer::ControlTypeToString(NUM_CONTROL_FRAME_TYPES));
}
-TEST(SpdyFramer, GetMinimumControlFrameSizeTest) {
+TEST_F(SpdyFramerSpdy2Test, GetMinimumControlFrameSizeTest) {
EXPECT_EQ(SpdySynStreamControlFrame::size(),
SpdyFramer::GetMinimumControlFrameSize(SYN_STREAM));
EXPECT_EQ(SpdySynReplyControlFrame::size(),
@@ -1845,7 +2574,7 @@
SpdyFramer::GetMinimumControlFrameSize(RST_STREAM));
EXPECT_EQ(SpdySettingsControlFrame::size(),
SpdyFramer::GetMinimumControlFrameSize(SETTINGS));
- EXPECT_EQ(SpdyNoOpControlFrame::size(),
+ EXPECT_EQ(SpdyFrame::kHeaderSize,
SpdyFramer::GetMinimumControlFrameSize(NOOP));
EXPECT_EQ(SpdyPingControlFrame::size(),
SpdyFramer::GetMinimumControlFrameSize(PING));
@@ -1861,11 +2590,34 @@
SpdyFramer::GetMinimumControlFrameSize(NUM_CONTROL_FRAME_TYPES));
}
-std::string RandomString(int length) {
- std::string rv;
- for (int index = 0; index < length; index++)
- rv += static_cast<char>('a' + (rand() % 26));
- return rv;
+TEST_F(SpdyFramerSpdy2Test, CatchProbableHttpResponse) {
+ SpdyFramerTestUtil::DecompressionVisitor visitor;
+ visitor.set_allow_data_frames(true);
+ {
+ SpdyFramer framer(kVer);
+ framer.set_visitor(&visitor);
+ framer.ProcessInput("HTTP/1.1", 8);
+ EXPECT_TRUE(framer.probable_http_response());
+ }
+ {
+ SpdyFramer framer(kVer);
+ framer.set_visitor(&visitor);
+ framer.ProcessInput("HTTP/1.0", 8);
+ EXPECT_TRUE(framer.probable_http_response());
+ }
}
+TEST_F(SpdyFramerSpdy2Test, SettingsFlagsAndId) {
+ const uint32 kId = 0x020304;
+ const uint32 kFlags = 0x01;
+ const uint32 kWireFormat =
+ htonl((SPDY_VERSION_FOR_TESTS < 3) ? 0x04030201 : 0x01020304);
+
+ SettingsFlagsAndId id_and_flags =
+ SettingsFlagsAndId::FromWireFormat(SPDY_VERSION_FOR_TESTS, kWireFormat);
+ EXPECT_EQ(kId, id_and_flags.id());
+ EXPECT_EQ(kFlags, id_and_flags.flags());
+ EXPECT_EQ(kWireFormat, id_and_flags.GetWireFormat(SPDY_VERSION_FOR_TESTS));
+}
+
} // namespace
« no previous file with comments | « net/spdy/spdy_framer.cc ('k') | net/spdy/spdy_framer_spdy3_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698