summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-08 14:13:20 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-08 14:13:20 +0000
commitca1812bf81813c39931ccc3bd5accc0275b3d3e0 (patch)
treedb0a59aa4c5f10929728b468992f56f370e25790 /net
parent5a64e82151109e69bbf8cb83ee945a9f5e966910 (diff)
downloadchromium_src-ca1812bf81813c39931ccc3bd5accc0275b3d3e0.zip
chromium_src-ca1812bf81813c39931ccc3bd5accc0275b3d3e0.tar.gz
chromium_src-ca1812bf81813c39931ccc3bd5accc0275b3d3e0.tar.bz2
[SPDY] Fix session flow control bug with incoming data for inactive streams
The session receive flow control window should not decrease on incoming data for an inactive stream. BUG=176592 Review URL: https://chromiumcodereview.appspot.com/12648002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@186960 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/spdy/spdy_session.cc7
-rw-r--r--net/spdy/spdy_session.h2
-rw-r--r--net/spdy/spdy_session_spdy3_unittest.cc35
3 files changed, 41 insertions, 3 deletions
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 61fd280..8336640 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -1388,13 +1388,14 @@ void SpdySession::OnStreamFrameData(SpdyStreamId stream_id,
base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin));
}
- if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION && len > 0)
- DecreaseRecvWindowSize(static_cast<int32>(len));
-
// By the time data comes in, the stream may already be inactive.
if (!IsStreamActive(stream_id))
return;
+ // Only decrease the window size for data for active streams.
+ if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION && len > 0)
+ DecreaseRecvWindowSize(static_cast<int32>(len));
+
scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
stream->OnDataReceived(data, len);
}
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 4facb51..4c8f251 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -449,6 +449,8 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy3Test, IncreaseRecvWindowSize);
FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy3Test, AdjustRecvWindowSize31);
FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy3Test, AdjustSendWindowSize31);
+ FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy3Test,
+ SessionFlowControlInactiveStream31);
FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy3Test, SessionFlowControlEndToEnd31);
typedef std::deque<SpdyStreamRequest*> PendingStreamRequestQueue;
diff --git a/net/spdy/spdy_session_spdy3_unittest.cc b/net/spdy/spdy_session_spdy3_unittest.cc
index a0d8583..e814f45 100644
--- a/net/spdy/spdy_session_spdy3_unittest.cc
+++ b/net/spdy/spdy_session_spdy3_unittest.cc
@@ -2275,6 +2275,41 @@ TEST_F(SpdySessionSpdy3Test, AdjustSendWindowSize31) {
EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
}
+// Incoming data for an inactive stream should not cause the session
+// receive window size to decrease.
+TEST_F(SpdySessionSpdy3Test, SessionFlowControlInactiveStream31) {
+ session_deps_.enable_spdy_31 = true;
+ session_deps_.host_resolver->set_synchronous_mode(true);
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ scoped_ptr<SpdyFrame> resp(ConstructSpdyBodyFrame(1, false));
+ MockRead reads[] = {
+ CreateMockRead(*resp, 0),
+ MockRead(ASYNC, 0, 1) // EOF
+ };
+ DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
+ data.set_connect_data(connect_data);
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+ SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+ session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ CreateDeterministicNetworkSession();
+ scoped_refptr<SpdySession> session = GetSession(pair_);
+ InitializeSession(
+ http_session_.get(), session.get(), test_host_port_pair_);
+ EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
+ session->flow_control_state());
+
+ EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
+ EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
+
+ data.RunFor(2);
+
+ EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
+ EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
+}
+
namespace {
void ExpectOK(int status) {