summaryrefslogtreecommitdiffstats
path: root/net/spdy
diff options
context:
space:
mode:
Diffstat (limited to 'net/spdy')
-rw-r--r--net/spdy/spdy_network_transaction_unittest.cc38
-rw-r--r--net/spdy/spdy_session.cc140
-rw-r--r--net/spdy/spdy_session.h22
-rw-r--r--net/spdy/spdy_session_pool.cc4
-rw-r--r--net/spdy/spdy_session_pool.h2
-rw-r--r--net/spdy/spdy_session_unittest.cc299
-rw-r--r--net/spdy/spdy_test_util_common.cc10
-rw-r--r--net/spdy/spdy_test_util_common.h2
-rw-r--r--net/spdy/spdy_websocket_stream_unittest.cc56
9 files changed, 300 insertions, 273 deletions
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index 2f65151..98c4d13 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -4276,9 +4276,13 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
net_log, GetParam(), NULL);
helper.RunPreTestSetup();
+ SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
+
+ SpdySessionPoolPeer pool_peer(spdy_session_pool);
+ pool_peer.SetEnableSendingInitialData(true);
+
// Verify that no settings exist initially.
HostPortPair host_port_pair("www.google.com", helper.port());
- SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings(
host_port_pair).empty());
@@ -4304,7 +4308,20 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
EXPECT_EQ(2u, spdy_session_pool->http_server_properties()->GetSpdySettings(
host_port_pair).size());
- // Construct the SETTINGS frame.
+ // Construct the initial SETTINGS frame.
+ SettingsMap initial_settings;
+ initial_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
+ SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
+ scoped_ptr<SpdyFrame> initial_settings_frame(
+ spdy_util_.ConstructSpdySettings(initial_settings));
+
+ // Construct the initial window update.
+ scoped_ptr<SpdyFrame> initial_window_update(
+ spdy_util_.ConstructSpdyWindowUpdate(
+ kSessionFlowControlStreamId,
+ kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize));
+
+ // Construct the persisted SETTINGS frame.
const SettingsMap& settings =
spdy_session_pool->http_server_properties()->GetSpdySettings(
host_port_pair);
@@ -4315,10 +4332,19 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
scoped_ptr<SpdyFrame> req(
spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
- MockWrite writes[] = {
- CreateMockWrite(*settings_frame),
- CreateMockWrite(*req),
+ std::vector<MockWrite> writes;
+ if (GetParam().protocol == kProtoHTTP2Draft04) {
+ writes.push_back(
+ MockWrite(ASYNC,
+ kHttp2ConnectionHeaderPrefix,
+ kHttp2ConnectionHeaderPrefixSize));
+ }
+ writes.push_back(CreateMockWrite(*initial_settings_frame));
+ if (GetParam().protocol >= kProtoSPDY31) {
+ writes.push_back(CreateMockWrite(*initial_window_update));
};
+ writes.push_back(CreateMockWrite(*settings_frame));
+ writes.push_back(CreateMockWrite(*req));
// Construct the reply.
scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock());
@@ -4335,7 +4361,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
};
DelayedSocketData data(2, reads, arraysize(reads),
- writes, arraysize(writes));
+ vector_as_array(&writes), writes.size());
helper.AddData(&data);
helper.RunDefaultTest();
helper.VerifyDataConsumed();
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index d085a4d..8a730ce 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -205,9 +205,6 @@ base::Value* NetLogSpdyGoAwayCallback(SpdyStreamId last_stream_id,
return dict;
}
-// Maximum number of concurrent streams we will create, unless the server
-// sends a SETTINGS frame with a different value.
-const size_t kInitialMaxConcurrentStreams = 100;
// The maximum number of concurrent streams we will ever create. Even if
// the server permits more, we will never exceed this limit.
const size_t kMaxConcurrentStreamLimit = 256;
@@ -320,7 +317,7 @@ SpdySession::SpdySession(
const SpdySessionKey& spdy_session_key,
const base::WeakPtr<HttpServerProperties>& http_server_properties,
bool verify_domain_authentication,
- bool enable_sending_initial_settings,
+ bool enable_sending_initial_data,
bool enable_credential_frames,
bool enable_compression,
bool enable_ping_based_connection_checking,
@@ -364,6 +361,7 @@ SpdySession::SpdySession(
next_ping_id_(1),
last_activity_time_(time_func()),
check_ping_status_pending_(false),
+ send_connection_header_prefix_(false),
flow_control_state_(FLOW_CONTROL_NONE),
stream_initial_send_window_size_(kSpdyStreamInitialWindowSize),
stream_initial_recv_window_size_(stream_initial_recv_window_size == 0 ?
@@ -374,7 +372,7 @@ SpdySession::SpdySession(
session_unacked_recv_window_bytes_(0),
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)),
verify_domain_authentication_(verify_domain_authentication),
- enable_sending_initial_settings_(enable_sending_initial_settings),
+ enable_sending_initial_data_(enable_sending_initial_data),
enable_credential_frames_(enable_credential_frames),
enable_compression_(enable_compression),
enable_ping_based_connection_checking_(
@@ -458,6 +456,9 @@ Error SpdySession::InitializeWithSocket(
host_port_pair().ToString()));
}
+ if (protocol_ == kProtoHTTP2Draft04)
+ send_connection_header_prefix_ = true;
+
if (protocol_ >= kProtoSPDY31) {
flow_control_state_ = FLOW_CONTROL_STREAM_AND_SESSION;
session_send_window_size_ = kSpdySessionInitialWindowSize;
@@ -490,7 +491,8 @@ Error SpdySession::InitializeWithSocket(
if (error == OK) {
DCHECK_NE(availability_state_, STATE_CLOSED);
connection_->AddLayeredPool(this);
- SendInitialSettings();
+ if (enable_sending_initial_data_)
+ SendInitialData();
pool_ = pool;
} else {
DcheckClosed();
@@ -672,29 +674,37 @@ void SpdySession::CancelStreamRequest(SpdyStreamRequest* request) {
}
void SpdySession::ProcessPendingStreamRequests() {
- while (!max_concurrent_streams_ ||
- (active_streams_.size() + created_streams_.size() <
- max_concurrent_streams_)) {
- bool no_pending_create_streams = true;
- for (int i = NUM_PRIORITIES - 1; i >= MINIMUM_PRIORITY; --i) {
- if (!pending_create_stream_queues_[i].empty()) {
- SpdyStreamRequest* pending_request =
- pending_create_stream_queues_[i].front();
- CHECK(pending_request);
- pending_create_stream_queues_[i].pop_front();
- no_pending_create_streams = false;
- DCHECK(!ContainsKey(pending_stream_request_completions_,
- pending_request));
- pending_stream_request_completions_.insert(pending_request);
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&SpdySession::CompleteStreamRequest,
- weak_factory_.GetWeakPtr(), pending_request));
- break;
- }
+ // Like |max_concurrent_streams_|, 0 means infinite for
+ // |max_requests_to_process|.
+ size_t max_requests_to_process = 0;
+ if (max_concurrent_streams_ != 0) {
+ max_requests_to_process =
+ max_concurrent_streams_ -
+ (active_streams_.size() + created_streams_.size());
+ }
+ for (size_t i = 0;
+ max_requests_to_process == 0 || i < max_requests_to_process; ++i) {
+ bool processed_request = false;
+ for (int j = NUM_PRIORITIES - 1; j >= MINIMUM_PRIORITY; --j) {
+ if (pending_create_stream_queues_[j].empty())
+ continue;
+
+ SpdyStreamRequest* pending_request =
+ pending_create_stream_queues_[j].front();
+ CHECK(pending_request);
+ pending_create_stream_queues_[j].pop_front();
+ processed_request = true;
+ DCHECK(!ContainsKey(pending_stream_request_completions_,
+ pending_request));
+ pending_stream_request_completions_.insert(pending_request);
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&SpdySession::CompleteStreamRequest,
+ weak_factory_.GetWeakPtr(), pending_request));
+ break;
}
- if (no_pending_create_streams)
- return; // there were no streams in any queue
+ if (!processed_request)
+ break;
}
}
@@ -2348,29 +2358,38 @@ void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id,
stream_id, delta_window_size, it->second.stream->priority());
}
-void SpdySession::SendInitialSettings() {
+void SpdySession::SendInitialData() {
+ DCHECK(enable_sending_initial_data_);
DCHECK_NE(availability_state_, STATE_CLOSED);
+ if (send_connection_header_prefix_) {
+ DCHECK_EQ(protocol_, kProtoHTTP2Draft04);
+ scoped_ptr<SpdyFrame> connection_header_prefix_frame(
+ new SpdyFrame(const_cast<char*>(kHttp2ConnectionHeaderPrefix),
+ kHttp2ConnectionHeaderPrefixSize,
+ false /* take_ownership */));
+ // Count the prefix as part of the subsequent SETTINGS frame.
+ EnqueueSessionWrite(HIGHEST, SETTINGS,
+ connection_header_prefix_frame.Pass());
+ }
+
// First, notify the server about the settings they should use when
// communicating with us.
- if (GetProtocolVersion() >= 2 && enable_sending_initial_settings_) {
- SettingsMap settings_map;
- // Create a new settings frame notifying the sever of our
- // max_concurrent_streams_ and initial window size.
- settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] =
- SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
- if (GetProtocolVersion() > 2 &&
- stream_initial_recv_window_size_ != kSpdyStreamInitialWindowSize) {
- settings_map[SETTINGS_INITIAL_WINDOW_SIZE] =
- SettingsFlagsAndValue(SETTINGS_FLAG_NONE,
- stream_initial_recv_window_size_);
- }
- SendSettings(settings_map);
- }
+ SettingsMap settings_map;
+ // Create a new settings frame notifying the server of our
+ // max concurrent streams and initial window size.
+ settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] =
+ SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
+ if (flow_control_state_ >= FLOW_CONTROL_STREAM &&
+ stream_initial_recv_window_size_ != kSpdyStreamInitialWindowSize) {
+ settings_map[SETTINGS_INITIAL_WINDOW_SIZE] =
+ SettingsFlagsAndValue(SETTINGS_FLAG_NONE,
+ stream_initial_recv_window_size_);
+ }
+ SendSettings(settings_map);
// Next, notify the server about our initial recv window size.
- if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION &&
- enable_sending_initial_settings_) {
+ if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
// Bump up the receive window size to the real initial value. This
// has to go here since the WINDOW_UPDATE frame sent by
// IncreaseRecvWindowSize() call uses |buffered_spdy_framer_|.
@@ -2382,30 +2401,27 @@ void SpdySession::SendInitialSettings() {
kDefaultInitialRecvWindowSize - session_recv_window_size_);
}
- // Finally, notify the server about the settings they have previously
- // told us to use when communicating with them.
- const SettingsMap& settings_map =
+ // Finally, notify the server about the settings they have
+ // previously told us to use when communicating with them (after
+ // applying them).
+ const SettingsMap& server_settings_map =
http_server_properties_->GetSpdySettings(host_port_pair());
- if (settings_map.empty())
+ if (server_settings_map.empty())
return;
- const SpdySettingsIds id = SETTINGS_CURRENT_CWND;
- SettingsMap::const_iterator it = settings_map.find(id);
- uint32 value = 0;
- if (it != settings_map.end())
- value = it->second.second;
- UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwndSent", value, 1, 200, 100);
+ SettingsMap::const_iterator it =
+ server_settings_map.find(SETTINGS_CURRENT_CWND);
+ uint32 cwnd = (it != server_settings_map.end()) ? it->second.second : 0;
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwndSent", cwnd, 1, 200, 100);
- const SettingsMap& settings_map_new =
- http_server_properties_->GetSpdySettings(host_port_pair());
- for (SettingsMap::const_iterator i = settings_map_new.begin(),
- end = settings_map_new.end(); i != end; ++i) {
- const SpdySettingsIds new_id = i->first;
- const uint32 new_val = i->second.second;
+ for (SettingsMap::const_iterator it = server_settings_map.begin();
+ it != server_settings_map.end(); ++it) {
+ const SpdySettingsIds new_id = it->first;
+ const uint32 new_val = it->second.second;
HandleSetting(new_id, new_val);
}
- SendSettings(settings_map_new);
+ SendSettings(server_settings_map);
}
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index c2d5b10..c6a22e6 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -49,6 +49,10 @@ const int kMss = 1430;
// The 8 is the size of the SPDY frame header.
const int kMaxSpdyFrameChunkSize = (2 * kMss) - 8;
+// Maximum number of concurrent streams we will create, unless the server
+// sends a SETTINGS frame with a different value.
+const size_t kInitialMaxConcurrentStreams = 100;
+
// Specifies the maxiumum concurrent streams server could send (via push).
const int kMaxConcurrentPushedStreams = 1000;
@@ -202,7 +206,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
SpdySession(const SpdySessionKey& spdy_session_key,
const base::WeakPtr<HttpServerProperties>& http_server_properties,
bool verify_domain_authentication,
- bool enable_sending_initial_settings,
+ bool enable_sending_initial_data,
bool enable_credential_frames,
bool enable_compression,
bool enable_ping_based_connection_checking,
@@ -646,10 +650,15 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
int DoWrite();
int DoWriteComplete(int result);
- // Send relevant SETTINGS. This is generally called on connection setup.
- void SendInitialSettings();
+ // TODO(akalin): Rename the Send* and Write* functions below to
+ // Enqueue*.
+
+ // Send initial data. Called when a connection is successfully
+ // established in InitializeWithSocket() and
+ // |enable_sending_initial_data_| is true.
+ void SendInitialData();
- // Helper method to send SETTINGS a frame.
+ // Helper method to send a SETTINGS frame.
void SendSettings(const SettingsMap& settings);
// Handle SETTING. Either when we send settings, or when we receive a
@@ -1056,6 +1065,9 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// status.
bool check_ping_status_pending_;
+ // Whether to send the (HTTP/2) connection header prefix.
+ bool send_connection_header_prefix_;
+
// The (version-dependent) flow control state.
FlowControlState flow_control_state_;
@@ -1085,7 +1097,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// Outside of tests, these should always be true.
bool verify_domain_authentication_;
- bool enable_sending_initial_settings_;
+ bool enable_sending_initial_data_;
bool enable_credential_frames_;
bool enable_compression_;
bool enable_ping_based_connection_checking_;
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc
index 185ec23..9e47f3f 100644
--- a/net/spdy/spdy_session_pool.cc
+++ b/net/spdy/spdy_session_pool.cc
@@ -46,7 +46,7 @@ SpdySessionPool::SpdySessionPool(
ssl_config_service_(ssl_config_service),
resolver_(resolver),
verify_domain_authentication_(true),
- enable_sending_initial_settings_(true),
+ enable_sending_initial_data_(true),
force_single_domain_(force_single_domain),
enable_ip_pooling_(enable_ip_pooling),
enable_credential_frames_(enable_credential_frames),
@@ -103,7 +103,7 @@ net::Error SpdySessionPool::CreateAvailableSessionFromSocket(
new SpdySession(key,
http_server_properties_,
verify_domain_authentication_,
- enable_sending_initial_settings_,
+ enable_sending_initial_data_,
enable_credential_frames_,
enable_compression_,
enable_ping_based_connection_checking_,
diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h
index c27d6d5..812b7bd 100644
--- a/net/spdy/spdy_session_pool.h
+++ b/net/spdy/spdy_session_pool.h
@@ -211,7 +211,7 @@ class NET_EXPORT SpdySessionPool
// Defaults to true. May be controlled via SpdySessionPoolPeer for tests.
bool verify_domain_authentication_;
- bool enable_sending_initial_settings_;
+ bool enable_sending_initial_data_;
bool force_single_domain_;
bool enable_ip_pooling_;
bool enable_credential_frames_;
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index ea7a6d1..6388bf8 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -909,43 +909,27 @@ TEST_P(SpdySessionTest, FailedPing) {
EXPECT_EQ(NULL, spdy_stream1.get());
}
-// Start with max concurrent streams set to 1. Request two streams. Receive a
-// settings frame setting max concurrent streams to 2. Have the callback
-// release the stream, which releases its reference (the last) to the session.
-// Make sure nothing blows up.
-// http://crbug.com/57331
+// Request kInitialMaxConcurrentStreams + 1 streams. Receive a
+// settings frame increasing the max concurrent streams by 1. Make
+// sure nothing blows up. This is a regression test for
+// http://crbug.com/57331 .
TEST_P(SpdySessionTest, OnSettings) {
session_deps_.host_resolver->set_synchronous_mode(true);
const SpdySettingsIds kSpdySettingsIds = SETTINGS_MAX_CONCURRENT_STREAMS;
- SettingsMap initial_settings;
- const uint32 initial_max_concurrent_streams = 1;
- initial_settings[kSpdySettingsIds] =
- SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED,
- initial_max_concurrent_streams);
- scoped_ptr<SpdyFrame> initial_settings_frame(
- spdy_util_.ConstructSpdySettings(initial_settings));
- MockWrite writes[] = {
- CreateMockWrite(*initial_settings_frame, 0),
- };
-
SettingsMap new_settings;
- const uint32 max_concurrent_streams = 2;
+ const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
new_settings[kSpdySettingsIds] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
-
- // Set up the socket so we read a SETTINGS frame that raises max concurrent
- // streams to 2.
scoped_ptr<SpdyFrame> settings_frame(
spdy_util_.ConstructSpdySettings(new_settings));
MockRead reads[] = {
- CreateMockRead(*settings_frame, 1),
- MockRead(ASYNC, 0, 2),
+ CreateMockRead(*settings_frame, 0),
+ MockRead(ASYNC, 0, 1),
};
- DeterministicSocketData data(
- reads, arraysize(reads), writes, arraysize(writes));
+ DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
@@ -955,21 +939,16 @@ TEST_P(SpdySessionTest, OnSettings) {
CreateDeterministicNetworkSession();
- // Initialize the SpdySetting with 1 max concurrent streams.
- spdy_session_pool_->http_server_properties()->SetSpdySetting(
- test_host_port_pair_,
- kSpdySettingsIds,
- SETTINGS_FLAG_PLEASE_PERSIST,
- initial_max_concurrent_streams);
-
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- // Create 2 streams. First will succeed. Second will be pending.
- base::WeakPtr<SpdyStream> spdy_stream1 =
- CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
- session, test_url_, MEDIUM, BoundNetLog());
- ASSERT_TRUE(spdy_stream1.get() != NULL);
+ // Create the maximum number of concurrent streams.
+ for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
+ base::WeakPtr<SpdyStream> spdy_stream =
+ CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
+ session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream != NULL);
+ }
StreamReleaserCallback stream_releaser;
SpdyStreamRequest request;
@@ -979,7 +958,7 @@ TEST_P(SpdySessionTest, OnSettings) {
BoundNetLog(),
stream_releaser.MakeCallback(&request)));
- data.RunFor(2);
+ data.RunFor(1);
EXPECT_EQ(OK, stream_releaser.WaitForResult());
@@ -987,43 +966,27 @@ TEST_P(SpdySessionTest, OnSettings) {
EXPECT_TRUE(session == NULL);
}
-// Start with max concurrent streams set to 1 (that is persisted). Receive a
-// settings frame setting max concurrent streams to 2 and which also clears the
-// persisted data. Verify that persisted data is correct.
+// Start with a persisted value for max concurrent streams. Receive a
+// settings frame increasing the max concurrent streams by 1 and which
+// also clears the persisted data. Verify that persisted data is
+// correct.
TEST_P(SpdySessionTest, ClearSettings) {
session_deps_.host_resolver->set_synchronous_mode(true);
- const SpdySettingsIds kSpdySettingsIds = SETTINGS_MAX_CONCURRENT_STREAMS;
-
- SettingsMap initial_settings;
- const uint32 initial_max_concurrent_streams = 1;
- initial_settings[kSpdySettingsIds] =
- SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED,
- initial_max_concurrent_streams);
- scoped_ptr<SpdyFrame> initial_settings_frame(
- spdy_util_.ConstructSpdySettings(initial_settings));
- MockWrite writes[] = {
- CreateMockWrite(*initial_settings_frame, 0),
- };
-
SettingsMap new_settings;
- const uint32 max_concurrent_streams = 2;
- new_settings[kSpdySettingsIds] =
+ const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
+ new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
-
- // Set up the socket so we read a SETTINGS frame that raises max concurrent
- // streams to 2.
scoped_ptr<SpdyFrame> settings_frame(
spdy_util_.ConstructSpdySettings(new_settings));
uint8 flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
test::SetFrameFlags(settings_frame.get(), flags, spdy_util_.spdy_version());
MockRead reads[] = {
- CreateMockRead(*settings_frame, 1),
- MockRead(ASYNC, 0, 2),
+ CreateMockRead(*settings_frame, 0),
+ MockRead(ASYNC, 0, 1),
};
- DeterministicSocketData data(
- reads, arraysize(reads), writes, arraysize(writes));
+ DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
@@ -1033,24 +996,27 @@ TEST_P(SpdySessionTest, ClearSettings) {
CreateDeterministicNetworkSession();
- // Initialize the SpdySetting with 1 max concurrent streams.
+ // Initialize the SpdySetting with the default.
spdy_session_pool_->http_server_properties()->SetSpdySetting(
test_host_port_pair_,
- kSpdySettingsIds,
+ SETTINGS_MAX_CONCURRENT_STREAMS,
SETTINGS_FLAG_PLEASE_PERSIST,
- initial_max_concurrent_streams);
+ kInitialMaxConcurrentStreams);
- EXPECT_EQ(1u, spdy_session_pool_->http_server_properties()->GetSpdySettings(
- test_host_port_pair_).size());
+ EXPECT_FALSE(
+ spdy_session_pool_->http_server_properties()->GetSpdySettings(
+ test_host_port_pair_).empty());
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- // Create 2 streams. First will succeed. Second will be pending.
- base::WeakPtr<SpdyStream> spdy_stream1 =
- CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
- session, test_url_, MEDIUM, BoundNetLog());
- ASSERT_TRUE(spdy_stream1.get() != NULL);
+ // Create the maximum number of concurrent streams.
+ for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
+ base::WeakPtr<SpdyStream> spdy_stream =
+ CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
+ session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream != NULL);
+ }
StreamReleaserCallback stream_releaser;
@@ -1061,25 +1027,28 @@ TEST_P(SpdySessionTest, ClearSettings) {
BoundNetLog(),
stream_releaser.MakeCallback(&request)));
- data.RunFor(2);
+ data.RunFor(1);
EXPECT_EQ(OK, stream_releaser.WaitForResult());
// Make sure that persisted data is cleared.
- EXPECT_EQ(0u, spdy_session_pool_->http_server_properties()->GetSpdySettings(
- test_host_port_pair_).size());
+ EXPECT_TRUE(
+ spdy_session_pool_->http_server_properties()->GetSpdySettings(
+ test_host_port_pair_).empty());
- // Make sure session's max_concurrent_streams is 2.
- EXPECT_EQ(2u, session->max_concurrent_streams());
+ // Make sure session's max_concurrent_streams is correct.
+ EXPECT_EQ(kInitialMaxConcurrentStreams + 1,
+ session->max_concurrent_streams());
data.RunFor(1);
EXPECT_TRUE(session == NULL);
}
-// Start with max concurrent streams set to 1. Request two streams. When the
-// first completes, have the callback close itself, which should trigger the
-// second stream creation. Then cancel that one immediately. Don't crash.
-// http://crbug.com/63532
+// Start with max concurrent streams set to 1. Request two streams.
+// When the first completes, have the callback close its stream, which
+// should trigger the second stream creation. Then cancel that one
+// immediately. Don't crash. This is a regression test for
+// http://crbug.com/63532 .
TEST_P(SpdySessionTest, CancelPendingCreateStream) {
session_deps_.host_resolver->set_synchronous_mode(true);
@@ -1108,7 +1077,15 @@ TEST_P(SpdySessionTest, CancelPendingCreateStream) {
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
- // Create 2 streams. First will succeed. Second will be pending.
+ // Leave room for only one more stream to be created.
+ for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) {
+ base::WeakPtr<SpdyStream> spdy_stream =
+ CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
+ session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream != NULL);
+ }
+
+ // Create 2 more streams. First will succeed. Second will be pending.
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session, test_url_, MEDIUM, BoundNetLog());
@@ -1136,7 +1113,7 @@ TEST_P(SpdySessionTest, CancelPendingCreateStream) {
base::MessageLoop::current()->RunUntilIdle();
}
-TEST_P(SpdySessionTest, SendInitialSettingsOnNewSession) {
+TEST_P(SpdySessionTest, SendInitialDataOnNewSession) {
session_deps_.host_resolver->set_synchronous_mode(true);
MockRead reads[] = {
@@ -1160,61 +1137,31 @@ TEST_P(SpdySessionTest, SendInitialSettingsOnNewSession) {
spdy_util_.ConstructSpdyWindowUpdate(
kSessionFlowControlStreamId,
kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize));
- MockWrite writes[] = {
- CreateMockWrite(*settings_frame),
- CreateMockWrite(*initial_window_update),
- };
- session_deps_.stream_initial_recv_window_size = kInitialRecvWindowSize;
- int num_writes = arraysize(writes);
- // We don't have session windows for SPDY versions less than 3.1.
- if (spdy_util_.protocol() < kProtoSPDY31) {
- --num_writes;
+ std::vector<MockWrite> writes;
+ if (GetParam() == kProtoHTTP2Draft04) {
+ writes.push_back(
+ MockWrite(ASYNC,
+ kHttp2ConnectionHeaderPrefix,
+ kHttp2ConnectionHeaderPrefixSize));
}
-
- StaticSocketDataProvider data(reads, arraysize(reads), writes, num_writes);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
-
- CreateNetworkSession();
-
- SpdySessionPoolPeer pool_peer(spdy_session_pool_);
- pool_peer.EnableSendingInitialSettings(true);
-
- base::WeakPtr<SpdySession> session =
- CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
-
- base::MessageLoop::current()->RunUntilIdle();
- EXPECT_TRUE(data.at_write_eof());
-}
-
-TEST_P(SpdySessionTest, SendSettingsOnNewSession) {
- session_deps_.host_resolver->set_synchronous_mode(true);
-
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
+ writes.push_back(CreateMockWrite(*settings_frame));
+ if (GetParam() >= kProtoSPDY31) {
+ writes.push_back(CreateMockWrite(*initial_window_update));
};
- // Create the bogus setting that we want to verify is sent out.
- // Note that it will be marked as SETTINGS_FLAG_PERSISTED when sent out. But
- // to persist it into the HttpServerProperties, we need to mark as
- // SETTINGS_FLAG_PLEASE_PERSIST.
- SettingsMap settings;
- const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_UPLOAD_BANDWIDTH;
- const uint32 kBogusSettingValue = 0xCDCD;
- settings[kSpdySettingsIds1] =
- SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED, kBogusSettingValue);
- MockConnect connect_data(SYNCHRONOUS, OK);
- scoped_ptr<SpdyFrame> settings_frame(
- spdy_util_.ConstructSpdySettings(settings));
- MockWrite writes[] = {
- CreateMockWrite(*settings_frame),
- };
+ SettingsMap server_settings;
+ const uint32 initial_max_concurrent_streams = 1;
+ server_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
+ SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED,
+ initial_max_concurrent_streams);
+ scoped_ptr<SpdyFrame> server_settings_frame(
+ spdy_util_.ConstructSpdySettings(server_settings));
+ writes.push_back(CreateMockWrite(*server_settings_frame));
- StaticSocketDataProvider data(
- reads, arraysize(reads), writes, arraysize(writes));
+ session_deps_.stream_initial_recv_window_size = kInitialRecvWindowSize;
+
+ StaticSocketDataProvider data(reads, arraysize(reads),
+ vector_as_array(&writes), writes.size());
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
@@ -1225,9 +1172,12 @@ TEST_P(SpdySessionTest, SendSettingsOnNewSession) {
spdy_session_pool_->http_server_properties()->SetSpdySetting(
test_host_port_pair_,
- kSpdySettingsIds1,
+ SETTINGS_MAX_CONCURRENT_STREAMS,
SETTINGS_FLAG_PLEASE_PERSIST,
- kBogusSettingValue);
+ initial_max_concurrent_streams);
+
+ SpdySessionPoolPeer pool_peer(spdy_session_pool_);
+ pool_peer.SetEnableSendingInitialData(true);
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
@@ -2085,7 +2035,8 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
SPDY_REQUEST_RESPONSE_STREAM,
session, url3, LOWEST, BoundNetLog(), callback3.callback()));
- EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+ EXPECT_EQ(0u, session->num_active_streams());
+ EXPECT_EQ(1u, session->num_created_streams());
EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST));
scoped_ptr<SpdyHeaderBlock> headers(
@@ -2093,15 +2044,23 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
- // Run until 1st stream is closed and 2nd one is opened.
+ // Run until 1st stream is activated and then closed.
EXPECT_EQ(0u, delegate1.stream_id());
data.RunFor(3);
- // Pump loop for SpdySession::ProcessPendingStreamRequests().
- base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(NULL, spdy_stream1.get());
EXPECT_EQ(1u, delegate1.stream_id());
- EXPECT_EQ(2u, session->num_active_streams() + session->num_created_streams());
- EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
+
+ EXPECT_EQ(0u, session->num_active_streams());
+ EXPECT_EQ(0u, session->num_created_streams());
+ EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
+
+ // Pump loop for SpdySession::ProcessPendingStreamRequests() to
+ // create the 2nd stream.
+ base::MessageLoop::current()->RunUntilIdle();
+
+ EXPECT_EQ(0u, session->num_active_streams());
+ EXPECT_EQ(1u, session->num_created_streams());
+ EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream();
test::StreamDelegateDoNothing delegate2(stream2);
@@ -2111,12 +2070,22 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(stream2->HasUrlFromHeaders());
- // Run until 2nd stream is closed.
+ // Run until 2nd stream is activated and then closed.
EXPECT_EQ(0u, delegate2.stream_id());
data.RunFor(3);
EXPECT_EQ(NULL, stream2.get());
EXPECT_EQ(3u, delegate2.stream_id());
- EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+
+ EXPECT_EQ(0u, session->num_active_streams());
+ EXPECT_EQ(0u, session->num_created_streams());
+ EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
+
+ // Pump loop for SpdySession::ProcessPendingStreamRequests() to
+ // create the 3rd stream.
+ base::MessageLoop::current()->RunUntilIdle();
+
+ EXPECT_EQ(0u, session->num_active_streams());
+ EXPECT_EQ(1u, session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream();
@@ -2127,11 +2096,14 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) {
stream3->SendRequestHeaders(headers3.Pass(), NO_MORE_DATA_TO_SEND);
EXPECT_TRUE(stream3->HasUrlFromHeaders());
+ // Run until 2nd stream is activated and then closed.
EXPECT_EQ(0u, delegate3.stream_id());
data.RunFor(3);
EXPECT_EQ(NULL, stream3.get());
EXPECT_EQ(5u, delegate3.stream_id());
- EXPECT_EQ(0u, session->num_active_streams() + session->num_created_streams());
+
+ EXPECT_EQ(0u, session->num_active_streams());
+ EXPECT_EQ(0u, session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
data.RunFor(1);
@@ -2155,16 +2127,17 @@ TEST_P(SpdySessionTest, CancelTwoStalledCreateStream) {
CreateNetworkSession();
- // Initialize the SpdySetting with 1 max concurrent streams.
- spdy_session_pool_->http_server_properties()->SetSpdySetting(
- test_host_port_pair_,
- SETTINGS_MAX_CONCURRENT_STREAMS,
- SETTINGS_FLAG_PLEASE_PERSIST,
- 1);
-
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
+ // Leave room for only one more stream to be created.
+ for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) {
+ base::WeakPtr<SpdyStream> spdy_stream =
+ CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
+ session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream != NULL);
+ }
+
GURL url1("http://www.google.com");
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
@@ -2188,30 +2161,36 @@ TEST_P(SpdySessionTest, CancelTwoStalledCreateStream) {
SPDY_BIDIRECTIONAL_STREAM, session, url3, LOWEST, BoundNetLog(),
callback3.callback()));
- EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+ EXPECT_EQ(0u, session->num_active_streams());
+ EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST));
- // Cancel the first stream, this will allow the second stream to be created.
+ // Cancel the first stream; this will allow the second stream to be created.
EXPECT_TRUE(spdy_stream1.get() != NULL);
spdy_stream1->Cancel();
EXPECT_EQ(NULL, spdy_stream1.get());
- callback2.WaitForResult();
- EXPECT_EQ(2u, session->num_active_streams() + session->num_created_streams());
- EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
+ EXPECT_EQ(OK, callback2.WaitForResult());
+ EXPECT_EQ(0u, session->num_active_streams());
+ EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
+ EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST));
- // Cancel the second stream, this will allow the third stream to be created.
+ // Cancel the second stream; this will allow the third stream to be created.
base::WeakPtr<SpdyStream> spdy_stream2 = request2.ReleaseStream();
spdy_stream2->Cancel();
EXPECT_EQ(NULL, spdy_stream2.get());
- EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
+
+ EXPECT_EQ(OK, callback3.WaitForResult());
+ EXPECT_EQ(0u, session->num_active_streams());
+ EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
// Cancel the third stream.
base::WeakPtr<SpdyStream> spdy_stream3 = request3.ReleaseStream();
spdy_stream3->Cancel();
EXPECT_EQ(NULL, spdy_stream3.get());
- EXPECT_EQ(0u, session->num_active_streams() + session->num_created_streams());
+ EXPECT_EQ(0u, session->num_active_streams());
+ EXPECT_EQ(kInitialMaxConcurrentStreams - 1, session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST));
}
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc
index 4c52751..4383db0 100644
--- a/net/spdy/spdy_test_util_common.cc
+++ b/net/spdy/spdy_test_util_common.cc
@@ -401,7 +401,7 @@ HttpNetworkSession* SpdySessionDependencies::SpdyCreateSession(
params.client_socket_factory = session_deps->socket_factory.get();
HttpNetworkSession* http_session = new HttpNetworkSession(params);
SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
- pool_peer.EnableSendingInitialSettings(false);
+ pool_peer.SetEnableSendingInitialData(false);
return http_session;
}
@@ -413,7 +413,7 @@ HttpNetworkSession* SpdySessionDependencies::SpdyCreateSessionDeterministic(
session_deps->deterministic_socket_factory.get();
HttpNetworkSession* http_session = new HttpNetworkSession(params);
SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
- pool_peer.EnableSendingInitialSettings(false);
+ pool_peer.SetEnableSendingInitialData(false);
return http_session;
}
@@ -476,7 +476,7 @@ SpdyURLRequestContext::SpdyURLRequestContext(NextProto protocol)
scoped_refptr<HttpNetworkSession> network_session(
new HttpNetworkSession(params));
SpdySessionPoolPeer pool_peer(network_session->spdy_session_pool());
- pool_peer.EnableSendingInitialSettings(false);
+ pool_peer.SetEnableSendingInitialData(false);
storage_.set_http_transaction_factory(new HttpCache(
network_session.get(), HttpCache::DefaultBackend::InMemory(0)));
}
@@ -686,8 +686,8 @@ void SpdySessionPoolPeer::DisableDomainAuthenticationVerification() {
pool_->verify_domain_authentication_ = false;
}
-void SpdySessionPoolPeer::EnableSendingInitialSettings(bool enabled) {
- pool_->enable_sending_initial_settings_ = enabled;
+void SpdySessionPoolPeer::SetEnableSendingInitialData(bool enabled) {
+ pool_->enable_sending_initial_data_ = enabled;
}
SpdyTestUtil::SpdyTestUtil(NextProto protocol)
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h
index 7f5f2ab..aa833ff 100644
--- a/net/spdy/spdy_test_util_common.h
+++ b/net/spdy/spdy_test_util_common.h
@@ -280,7 +280,7 @@ class SpdySessionPoolPeer {
void RemoveAliases(const SpdySessionKey& key);
void DisableDomainAuthenticationVerification();
- void EnableSendingInitialSettings(bool enabled);
+ void SetEnableSendingInitialData(bool enabled);
private:
SpdySessionPool* const pool_;
diff --git a/net/spdy/spdy_websocket_stream_unittest.cc b/net/spdy/spdy_websocket_stream_unittest.cc
index f05b34e..e0661a0 100644
--- a/net/spdy/spdy_websocket_stream_unittest.cc
+++ b/net/spdy/spdy_websocket_stream_unittest.cc
@@ -238,23 +238,11 @@ class SpdyWebSocketStreamTest
}
void InitSession(MockRead* reads, size_t reads_count,
- MockWrite* writes, size_t writes_count,
- bool throttling) {
+ MockWrite* writes, size_t writes_count) {
data_.reset(new OrderedSocketData(reads, reads_count,
writes, writes_count));
session_deps_.socket_factory->AddSocketDataProvider(data_.get());
http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
- SpdySessionPool* spdy_session_pool(http_session_->spdy_session_pool());
-
- if (throttling) {
- // Set max concurrent streams to 1.
- spdy_session_pool->http_server_properties()->SetSpdySetting(
- host_port_pair_,
- spdy_settings_id_to_set_,
- spdy_settings_flags_to_set_,
- spdy_settings_value_to_set_);
- }
-
session_ = CreateInsecureSpdySession(
http_session_, spdy_session_key_, BoundNetLog());
}
@@ -327,7 +315,7 @@ TEST_P(SpdyWebSocketStreamTest, Basic) {
MockRead(SYNCHRONOUS, 0, 8) // EOF cause OnCloseSpdyStream event.
};
- InitSession(reads, arraysize(reads), writes, arraysize(writes), false);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes));
SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
delegate.SetOnReceivedHeader(
@@ -399,7 +387,7 @@ TEST_P(SpdyWebSocketStreamTest, DestructionBeforeClose) {
MockRead(ASYNC, ERR_IO_PENDING, 5)
};
- InitSession(reads, arraysize(reads), writes, arraysize(writes), false);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes));
SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
delegate.SetOnReceivedHeader(
@@ -461,7 +449,7 @@ TEST_P(SpdyWebSocketStreamTest, DestructionAfterExplicitClose) {
MockRead(ASYNC, ERR_IO_PENDING, 6)
};
- InitSession(reads, arraysize(reads), writes, arraysize(writes), false);
+ InitSession(reads, arraysize(reads), writes, arraysize(writes));
SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
delegate.SetOnReceivedHeader(
@@ -512,24 +500,27 @@ TEST_P(SpdyWebSocketStreamTest, IOPending) {
scoped_ptr<SpdyFrame> settings_frame(
spdy_util_.ConstructSpdySettings(spdy_settings_to_send_));
MockWrite writes[] = {
- // Setting throttling make SpdySession send settings frame automatically.
- CreateMockWrite(*settings_frame.get(), 1),
- CreateMockWrite(*request_frame_.get(), 3),
- CreateMockWrite(*message_frame_.get(), 6),
- CreateMockWrite(*closing_frame_.get(), 9)
+ CreateMockWrite(*request_frame_.get(), 1),
+ CreateMockWrite(*message_frame_.get(), 3),
+ CreateMockWrite(*closing_frame_.get(), 5)
};
MockRead reads[] = {
- CreateMockRead(*settings_frame.get(), 2),
- CreateMockRead(*response_frame_.get(), 4),
- // Skip sequence 5 (I/O Pending)
- CreateMockRead(*message_frame_.get(), 7),
- // Skip sequence 8 (I/O Pending)
- CreateMockRead(*closing_frame_.get(), 10),
- MockRead(SYNCHRONOUS, 0, 11) // EOF cause OnCloseSpdyStream event.
+ CreateMockRead(*settings_frame.get(), 0),
+ CreateMockRead(*response_frame_.get(), 2),
+ CreateMockRead(*message_frame_.get(), 4),
+ CreateMockRead(*closing_frame_.get(), 6),
+ MockRead(SYNCHRONOUS, 0, 7) // EOF cause OnCloseSpdyStream event.
};
- InitSession(reads, arraysize(reads), writes, arraysize(writes), true);
+ DeterministicSocketData data(reads, arraysize(reads),
+ writes, arraysize(writes));
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+ http_session_ =
+ SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
+
+ session_ = CreateInsecureSpdySession(
+ http_session_, spdy_session_key_, BoundNetLog());
// Create a dummy WebSocketStream which cause ERR_IO_PENDING to another
// WebSocketStream under test.
@@ -542,6 +533,8 @@ TEST_P(SpdyWebSocketStreamTest, IOPending) {
ASSERT_EQ(OK,
block_stream->InitializeStream(block_url, HIGHEST, block_net_log));
+ data.RunFor(1);
+
// Create a WebSocketStream under test.
SpdyWebSocketStreamEventRecorder delegate(completion_callback_.callback());
delegate.SetOnCreated(
@@ -566,6 +559,7 @@ TEST_P(SpdyWebSocketStreamTest, IOPending) {
SendRequest();
+ data.RunFor(7);
completion_callback_.WaitForResult();
websocket_stream_.reset();
@@ -605,8 +599,8 @@ TEST_P(SpdyWebSocketStreamTest, IOPending) {
// EOF close SPDY session.
EXPECT_FALSE(
HasSpdySession(http_session_->spdy_session_pool(), spdy_session_key_));
- EXPECT_TRUE(data()->at_read_eof());
- EXPECT_TRUE(data()->at_write_eof());
+ EXPECT_TRUE(data.at_read_eof());
+ EXPECT_TRUE(data.at_write_eof());
}
} // namespace net