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

Unified Diff: net/spdy/spdy_framer_test.cc

Issue 12213062: Invalid flags now result in a GOAWAY (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix test expectations Created 7 years, 10 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_session.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_framer_test.cc
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index 394586e538c0a849343c337383c6b57cad274b2d..646207829694bc9f94ab4f8303c64e8e1645e85a 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -26,6 +26,9 @@ namespace test {
static const size_t kMaxDecompressedSize = 1024;
+// TODO(akalin): Make sure expectations on mocks are set before mock
+// functions are called, as interleaving expectations and calls is
+// undefined.
class MockVisitor : public SpdyFramerVisitorInterface {
public:
MOCK_METHOD1(OnError, void(SpdyFramer* framer));
@@ -3079,6 +3082,9 @@ TEST_P(SpdyFramerTest, ErrorCodeToStringTest) {
EXPECT_STREQ("SPDY_INVALID_DATA_FRAME_FLAGS",
SpdyFramer::ErrorCodeToString(
SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS));
+ EXPECT_STREQ("SPDY_INVALID_CONTROL_FRAME_FLAGS",
+ SpdyFramer::ErrorCodeToString(
+ SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS));
EXPECT_STREQ("UNKNOWN_ERROR",
SpdyFramer::ErrorCodeToString(SpdyFramer::LAST_ERROR));
}
@@ -3176,24 +3182,22 @@ TEST_P(SpdyFramerTest, CatchProbableHttpResponse) {
SpdyFramer framer(spdy_version_);
framer.set_visitor(&visitor);
- // This won't cause an error at the framer level. It will cause
- // flag validation errors at the Visitor::OnDataFrameHeader level.
- EXPECT_CALL(visitor, OnDataFrameHeader(_));
+ EXPECT_CALL(visitor, OnError(_));
framer.ProcessInput("HTTP/1.1", 8);
EXPECT_TRUE(framer.probable_http_response());
- EXPECT_EQ(SpdyFramer::SPDY_FORWARD_STREAM_FRAME, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, framer.error_code());
}
{
testing::StrictMock<test::MockVisitor> visitor;
SpdyFramer framer(spdy_version_);
framer.set_visitor(&visitor);
- // This won't cause an error at the framer level. It will cause
- // flag validation errors at the Visitor::OnDataFrameHeader level.
- EXPECT_CALL(visitor, OnDataFrameHeader(_));
+ EXPECT_CALL(visitor, OnError(_));
framer.ProcessInput("HTTP/1.0", 8);
EXPECT_TRUE(framer.probable_http_response());
- EXPECT_EQ(SpdyFramer::SPDY_FORWARD_STREAM_FRAME, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, framer.error_code());
}
}
@@ -3209,18 +3213,333 @@ TEST_P(SpdyFramerTest, DataFrameFlags) {
framer.CreateDataFrame(1, "hello", 5, DATA_FLAG_NONE));
frame->set_flags(flags);
- // Flags are just passed along since they need to be validated at
- // a higher protocol layer.
- EXPECT_CALL(visitor, OnDataFrameHeader(_));
- EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5, SpdyDataFlags()));
- if (flags & DATA_FLAG_FIN) {
- EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, DATA_FLAG_FIN));
+ if (flags & ~DATA_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnDataFrameHeader(_));
+ EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5, SpdyDataFlags()));
+ if (flags & DATA_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, DATA_FLAG_FIN));
+ }
+ }
+
+ size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
+ framer.ProcessInput(frame->data(), frame_size);
+ if (flags & ~DATA_FLAG_FIN) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS,
+ framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+ }
+ }
+}
+
+TEST_P(SpdyFramerTest, SynStreamFrameFlags) {
+ for (int flags = 0; flags < 256; ++flags) {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<net::test::MockVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ EXPECT_CALL(visitor, OnControlFrameCompressed(_, _));
+
+ SpdyHeaderBlock headers;
+ headers["foo"] = "bar";
+ scoped_ptr<SpdyFrame> frame(
+ framer.CreateSynStream(8, 3, 1, 0, CONTROL_FLAG_NONE, true, &headers));
+ frame->set_flags(flags);
+
+ if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnSynStream(8, 3, 1, 0, flags & CONTROL_FLAG_FIN,
+ flags & CONTROL_FLAG_UNIDIRECTIONAL));
+ EXPECT_CALL(visitor, OnControlFrameHeaderData(8, _, _))
+ .WillRepeatedly(testing::Return(true));
+ if (flags & DATA_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, DATA_FLAG_FIN));
+ }
+ }
+
+ size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
+ framer.ProcessInput(frame->data(), frame_size);
+ if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+ }
+ }
+}
+
+TEST_P(SpdyFramerTest, SynReplyFrameFlags) {
+ for (int flags = 0; flags < 256; ++flags) {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<net::test::MockVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ EXPECT_CALL(visitor, OnControlFrameCompressed(_, _));
+
+ SpdyHeaderBlock headers;
+ headers["foo"] = "bar";
+ scoped_ptr<SpdyFrame> frame(
+ framer.CreateSynReply(37, CONTROL_FLAG_NONE, true, &headers));
+ frame->set_flags(flags);
+
+ if (flags & ~CONTROL_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnSynReply(37, flags & CONTROL_FLAG_FIN));
+ EXPECT_CALL(visitor, OnControlFrameHeaderData(37, _, _))
+ .WillRepeatedly(testing::Return(true));
+ if (flags & DATA_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, DATA_FLAG_FIN));
+ }
+ }
+
+ size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
+ framer.ProcessInput(frame->data(), frame_size);
+ if (flags & ~CONTROL_FLAG_FIN) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+ }
+ }
+}
+
+TEST_P(SpdyFramerTest, RstStreamFrameFlags) {
+ for (int flags = 0; flags < 256; ++flags) {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<net::test::MockVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(13, RST_STREAM_CANCEL));
+ frame->set_flags(flags);
+
+ if (flags != 0) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnRstStream(13, RST_STREAM_CANCEL));
+ }
+
+ size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
+ framer.ProcessInput(frame->data(), frame_size);
+ if (flags != 0) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+ }
+ }
+}
+
+TEST_P(SpdyFramerTest, SettingsFrameFlags) {
+ for (int flags = 0; flags < 256; ++flags) {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<net::test::MockVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ SettingsMap settings;
+ settings[SETTINGS_UPLOAD_BANDWIDTH] =
+ std::make_pair(SETTINGS_FLAG_NONE, 54321);
+ scoped_ptr<SpdyFrame> frame(framer.CreateSettings(settings));
+ frame->set_flags(flags);
+
+ if (flags & ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnSetting(SETTINGS_UPLOAD_BANDWIDTH,
+ SETTINGS_FLAG_NONE, 54321));
+ }
+
+ size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
+ framer.ProcessInput(frame->data(), frame_size);
+ if (flags & ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+ }
+ }
+}
+
+TEST_P(SpdyFramerTest, GoawayFrameFlags) {
+ for (int flags = 0; flags < 256; ++flags) {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<net::test::MockVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ scoped_ptr<SpdyFrame> frame(framer.CreateGoAway(97, GOAWAY_OK));
+ frame->set_flags(flags);
+
+ if (flags != 0) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnGoAway(97, GOAWAY_OK));
}
size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
framer.ProcessInput(frame->data(), frame_size);
- EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
- EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+ if (flags != 0) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+ }
+ }
+}
+
+TEST_P(SpdyFramerTest, HeadersFrameFlags) {
+ for (int flags = 0; flags < 256; ++flags) {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<net::test::MockVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ EXPECT_CALL(visitor, OnControlFrameCompressed(_, _));
+
+ SpdyHeaderBlock headers;
+ headers["foo"] = "bar";
+ scoped_ptr<SpdyFrame> frame(
+ framer.CreateHeaders(57, CONTROL_FLAG_NONE, true, &headers));
+ frame->set_flags(flags);
+
+ if (flags & ~CONTROL_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnHeaders(57, flags & CONTROL_FLAG_FIN));
+ EXPECT_CALL(visitor, OnControlFrameHeaderData(57, _, _))
+ .WillRepeatedly(testing::Return(true));
+ if (flags & DATA_FLAG_FIN) {
+ EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, DATA_FLAG_FIN));
+ }
+ }
+
+ size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
+ framer.ProcessInput(frame->data(), frame_size);
+ if (flags & ~CONTROL_FLAG_FIN) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+ }
+ }
+}
+
+TEST_P(SpdyFramerTest, PingFrameFlags) {
+ for (int flags = 0; flags < 256; ++flags) {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<net::test::MockVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ scoped_ptr<SpdyFrame> frame(framer.CreatePingFrame(42));
+ frame->set_flags(flags);
+
+ if (flags != 0) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnPing(42));
+ }
+
+ size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
+ framer.ProcessInput(frame->data(), frame_size);
+ if (flags != 0) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+ }
+ }
+}
+
+TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) {
+ for (int flags = 0; flags < 256; ++flags) {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<net::test::MockVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(4, 1024));
+ frame->set_flags(flags);
+
+ if (flags != 0) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnWindowUpdate(4, 1024));
+ }
+
+ size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
+ framer.ProcessInput(frame->data(), frame_size);
+ if (flags != 0) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+ }
+ }
+}
+
+TEST_P(SpdyFramerTest, CredentialFrameFlags) {
+ for (int flags = 0; flags < 256; ++flags) {
+ SCOPED_TRACE(testing::Message() << "Flags " << flags);
+
+ testing::StrictMock<net::test::MockVisitor> visitor;
+ SpdyFramer framer(spdy_version_);
+ framer.set_visitor(&visitor);
+
+ SpdyCredential credential;
+ scoped_ptr<SpdyFrame> frame(framer.CreateCredentialFrame(credential));
+ frame->set_flags(flags);
+
+ if (flags != 0) {
+ EXPECT_CALL(visitor, OnError(_));
+ } else {
+ EXPECT_CALL(visitor, OnCredentialFrameData(_, _))
+ .WillRepeatedly(testing::Return(true));
+ }
+
+ size_t frame_size = frame->length() + SpdyFrame::kHeaderSize;
+ framer.ProcessInput(frame->data(), frame_size);
+ if (flags != 0) {
+ EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
+ framer.error_code());
+ } else {
+ EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
+ EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code());
+ }
}
}
« no previous file with comments | « net/spdy/spdy_framer.cc ('k') | net/spdy/spdy_session.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698