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

Unified Diff: net/spdy/spdy_session_spdy3_unittest.cc

Issue 14311002: [SPDY] Avoid leaking bytes from the session flow control receive window (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | net/spdy/spdy_stream.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_session_spdy3_unittest.cc
diff --git a/net/spdy/spdy_session_spdy3_unittest.cc b/net/spdy/spdy_session_spdy3_unittest.cc
index 1c63960cd0d82a0a14a7da64b9472195965fff43..c15d3fdab3d98e2681e85837ae6354a79ad1870a 100644
--- a/net/spdy/spdy_session_spdy3_unittest.cc
+++ b/net/spdy/spdy_session_spdy3_unittest.cc
@@ -2274,6 +2274,108 @@ TEST_F(SpdySessionSpdy3Test, SessionFlowControlInactiveStream31) {
EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
}
+// A delegate that drops any received data.
+class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate {
+ public:
+ DropReceivedDataDelegate(const scoped_refptr<SpdyStream>& stream,
+ base::StringPiece data)
+ : StreamDelegateSendImmediate(
+ stream, scoped_ptr<SpdyHeaderBlock>(), data) {}
+
+ virtual ~DropReceivedDataDelegate() {}
+
+ // Drop any received data.
+ virtual int OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE {
+ return OK;
+ }
+};
+
+// Send data back and forth but use a delegate that drops its received
+// data. The receive window should still increase to its original
+// value, i.e. we shouldn't "leak" receive window bytes.
+TEST_F(SpdySessionSpdy3Test, SessionFlowControlNoReceiveLeaks31) {
+ const char kStreamUrl[] = "http://www.google.com/";
+
+ session_deps_.enable_spdy_31 = true;
+
+ const int32 msg_data_size = 100;
+ const std::string msg_data(msg_data_size, 'a');
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+
+ scoped_ptr<SpdyFrame> initial_window_update(
+ ConstructSpdyWindowUpdate(
+ kSessionFlowControlStreamId,
+ kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize));
+ scoped_ptr<SpdyFrame> req(
+ ConstructSpdyPost(kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0));
+ scoped_ptr<SpdyFrame> msg(
+ ConstructSpdyBodyFrame(1, msg_data.data(), msg_data_size, false));
+ MockWrite writes[] = {
+ CreateMockWrite(*initial_window_update, 0),
+ CreateMockWrite(*req, 1),
+ CreateMockWrite(*msg, 3),
+ };
+
+ scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<SpdyFrame> echo(
+ ConstructSpdyBodyFrame(1, msg_data.data(), msg_data_size, false));
+ scoped_ptr<SpdyFrame> window_update(
+ ConstructSpdyWindowUpdate(
+ kSessionFlowControlStreamId, msg_data_size));
+ MockRead reads[] = {
+ CreateMockRead(*resp, 2),
+ CreateMockRead(*echo, 4),
+ MockRead(ASYNC, 0, 5) // EOF
+ };
+
+ // Create SpdySession and SpdyStream and send the request.
+ DeterministicSocketData data(reads, arraysize(reads),
+ writes, arraysize(writes));
+ data.set_connect_data(connect_data);
+ session_deps_.host_resolver->set_synchronous_mode(true);
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+ SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+ session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ CreateDeterministicNetworkSession();
+
+ scoped_refptr<SpdySession> session = CreateInitializedSession();
+
+ GURL url(kStreamUrl);
+ scoped_refptr<SpdyStream> stream =
+ CreateStreamSynchronously(session, url, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(stream.get() != NULL);
+ EXPECT_EQ(0u, stream->stream_id());
+
+ DropReceivedDataDelegate delegate(stream, msg_data);
+ stream->SetDelegate(&delegate);
+
+ stream->set_spdy_headers(
+ ConstructPostHeaderBlock(url.spec(), msg_data_size));
+ EXPECT_TRUE(stream->HasUrl());
+ EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
+
+ EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
+ EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
+
+ data.RunFor(5);
+
+ EXPECT_TRUE(data.at_write_eof());
+ EXPECT_TRUE(data.at_read_eof());
+
+ EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
+ EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
+
+ stream->Close();
+
+ EXPECT_EQ(OK, delegate.WaitForClose());
+
+ EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
+ EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
+}
+
// Send data back and forth; the send and receive windows should
// change appropriately.
TEST_F(SpdySessionSpdy3Test, SessionFlowControlEndToEnd31) {
@@ -2384,15 +2486,19 @@ TEST_F(SpdySessionSpdy3Test, SessionFlowControlEndToEnd31) {
EXPECT_TRUE(data.at_write_eof());
EXPECT_TRUE(data.at_read_eof());
- // Normally done by the delegate, but not by our test delegate.
- session->IncreaseRecvWindowSize(msg_data_size);
+ EXPECT_EQ(msg_data, delegate.TakeReceivedData());
+ // Draining the delegate's read queue should increase our receive
+ // window.
EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
stream->Close();
EXPECT_EQ(OK, delegate.WaitForClose());
+
+ EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
+ EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
}
// Cause a stall by reducing the flow control send window to 0. The
@@ -2478,7 +2584,7 @@ TEST_F(SpdySessionSpdy3Test, ResumeAfterSendWindowSizeIncrease31) {
EXPECT_TRUE(delegate.send_headers_completed());
EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version"));
- EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate.received_data());
+ EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate.TakeReceivedData());
EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate.body_data_sent());
}
@@ -2614,13 +2720,13 @@ TEST_F(SpdySessionSpdy3Test, ResumeByPriorityAfterSendWindowSizeIncrease31) {
EXPECT_TRUE(delegate1.send_headers_completed());
EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
- EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate1.received_data());
+ EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate1.TakeReceivedData());
EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate1.body_data_sent());
EXPECT_TRUE(delegate2.send_headers_completed());
EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
- EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate2.received_data());
+ EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate2.TakeReceivedData());
EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate2.body_data_sent());
}
@@ -2808,19 +2914,19 @@ TEST_F(SpdySessionSpdy3Test, SendWindowSizeIncreaseWithDeletedStreams31) {
EXPECT_TRUE(delegate1.send_headers_completed());
EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
- EXPECT_EQ("", delegate1.received_data());
+ EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
EXPECT_EQ(0, delegate1.body_data_sent());
EXPECT_TRUE(delegate2.send_headers_completed());
EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
- EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate2.received_data());
+ EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate2.TakeReceivedData());
EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate2.body_data_sent());
EXPECT_TRUE(delegate3.send_headers_completed());
EXPECT_EQ("200", delegate3.GetResponseHeaderValue(":status"));
EXPECT_EQ("HTTP/1.1", delegate3.GetResponseHeaderValue(":version"));
- EXPECT_EQ("", delegate3.received_data());
+ EXPECT_EQ(std::string(), delegate3.TakeReceivedData());
EXPECT_EQ(0, delegate3.body_data_sent());
}
@@ -2969,13 +3075,13 @@ TEST_F(SpdySessionSpdy3Test, SendWindowSizeIncreaseWithDeletedSession31) {
EXPECT_TRUE(delegate1.send_headers_completed());
EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
- EXPECT_EQ("", delegate1.received_data());
+ EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
EXPECT_EQ(0, delegate1.body_data_sent());
EXPECT_TRUE(delegate2.send_headers_completed());
EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
- EXPECT_EQ("", delegate2.received_data());
+ EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
EXPECT_EQ(0, delegate2.body_data_sent());
}
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | net/spdy/spdy_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698