summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/http/http_proxy_client_socket_pool.cc10
-rw-r--r--net/http/http_proxy_client_socket_pool.h3
-rw-r--r--net/spdy/spdy_http_stream.cc23
-rw-r--r--net/spdy/spdy_http_stream.h3
-rw-r--r--net/spdy/spdy_proxy_client_socket_spdy2_unittest.cc8
-rw-r--r--net/spdy/spdy_proxy_client_socket_spdy3_unittest.cc8
-rw-r--r--net/spdy/spdy_session.cc293
-rw-r--r--net/spdy/spdy_session.h156
-rw-r--r--net/spdy/spdy_session_spdy2_unittest.cc275
-rw-r--r--net/spdy/spdy_session_spdy3_unittest.cc293
-rw-r--r--net/spdy/spdy_stream_spdy2_unittest.cc25
-rw-r--r--net/spdy/spdy_stream_spdy3_unittest.cc34
-rw-r--r--net/spdy/spdy_test_util_common.cc40
-rw-r--r--net/spdy/spdy_test_util_common.h39
-rw-r--r--net/spdy/spdy_websocket_stream.cc12
-rw-r--r--net/spdy/spdy_websocket_stream.h2
16 files changed, 647 insertions, 577 deletions
diff --git a/net/http/http_proxy_client_socket_pool.cc b/net/http/http_proxy_client_socket_pool.cc
index 3171685..a4ca49b 100644
--- a/net/http/http_proxy_client_socket_pool.cc
+++ b/net/http/http_proxy_client_socket_pool.cc
@@ -319,9 +319,9 @@ int HttpProxyConnectJob::DoSpdyProxyCreateStream() {
}
next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE;
- return spdy_session->CreateStream(
- params_->request_url(), params_->destination().priority(),
- &spdy_stream_, spdy_session->net_log(), callback_);
+ return spdy_stream_request_.StartRequest(
+ spdy_session, params_->request_url(), params_->destination().priority(),
+ spdy_session->net_log(), callback_);
}
int HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) {
@@ -329,8 +329,10 @@ int HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) {
return result;
next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
+ scoped_refptr<SpdyStream> stream = spdy_stream_request_.ReleaseStream();
+ DCHECK(stream);
transport_socket_.reset(
- new SpdyProxyClientSocket(spdy_stream_,
+ new SpdyProxyClientSocket(stream,
params_->user_agent(),
params_->endpoint(),
params_->request_url(),
diff --git a/net/http/http_proxy_client_socket_pool.h b/net/http/http_proxy_client_socket_pool.h
index be380af..c8be236 100644
--- a/net/http/http_proxy_client_socket_pool.h
+++ b/net/http/http_proxy_client_socket_pool.h
@@ -20,6 +20,7 @@
#include "net/socket/client_socket_pool_histograms.h"
#include "net/socket/client_socket_pool.h"
#include "net/socket/ssl_client_socket.h"
+#include "net/spdy/spdy_session.h"
namespace net {
@@ -164,7 +165,7 @@ class HttpProxyConnectJob : public ConnectJob {
HttpResponseInfo error_response_info_;
- scoped_refptr<SpdyStream> spdy_stream_;
+ SpdyStreamRequest spdy_stream_request_;
DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJob);
};
diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc
index ac4a3bf..9a83ffa 100644
--- a/net/spdy/spdy_http_stream.cc
+++ b/net/spdy/spdy_http_stream.cc
@@ -69,9 +69,16 @@ int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info,
if (stream_.get())
return OK;
- return spdy_session_->CreateStream(request_info_->url,
- request_info_->priority, &stream_,
- stream_net_log, callback);
+ int rv = stream_request_.StartRequest(
+ spdy_session_, request_info_->url, request_info_->priority,
+ stream_net_log,
+ base::Bind(&SpdyHttpStream::OnStreamCreated,
+ weak_factory_.GetWeakPtr(), callback));
+
+ if (rv == OK)
+ stream_ = stream_request_.ReleaseStream();
+
+ return rv;
}
const HttpResponseInfo* SpdyHttpStream::GetResponseInfo() const {
@@ -274,13 +281,19 @@ int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
}
void SpdyHttpStream::Cancel() {
- if (spdy_session_)
- spdy_session_->CancelPendingCreateStreams(&stream_);
callback_.Reset();
if (stream_)
stream_->Cancel();
}
+void SpdyHttpStream::OnStreamCreated(
+ const CompletionCallback& callback,
+ int rv) {
+ if (rv == OK)
+ stream_ = stream_request_.ReleaseStream();
+ callback.Run(rv);
+}
+
int SpdyHttpStream::SendData() {
CHECK(request_info_ && request_info_->upload_data_stream);
CHECK_EQ(0, request_body_buf_->BytesRemaining());
diff --git a/net/spdy/spdy_http_stream.h b/net/spdy/spdy_http_stream.h
index 5e2e55e..6968a9f 100644
--- a/net/spdy/spdy_http_stream.h
+++ b/net/spdy/spdy_http_stream.h
@@ -82,6 +82,8 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
virtual void OnClose(int status) OVERRIDE;
private:
+ void OnStreamCreated(const CompletionCallback& callback, int rv);
+
// Reads the data (whether chunked or not) from the request body stream and
// sends the data by calling WriteStreamData on the underlying SpdyStream.
int SendData();
@@ -98,6 +100,7 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
bool ShouldWaitForMoreBufferedData() const;
base::WeakPtrFactory<SpdyHttpStream> weak_factory_;
+ SpdyStreamRequest stream_request_;
scoped_refptr<SpdyStream> stream_;
scoped_refptr<SpdySession> spdy_session_;
diff --git a/net/spdy/spdy_proxy_client_socket_spdy2_unittest.cc b/net/spdy/spdy_proxy_client_socket_spdy2_unittest.cc
index 22cf8ae..f089357 100644
--- a/net/spdy/spdy_proxy_client_socket_spdy2_unittest.cc
+++ b/net/spdy/spdy_proxy_client_socket_spdy2_unittest.cc
@@ -23,6 +23,7 @@
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_protocol.h"
#include "net/spdy/spdy_session_pool.h"
+#include "net/spdy/spdy_test_util_common.h"
#include "net/spdy/spdy_test_util_spdy2.h"
#include "testing/platform_test.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -199,10 +200,9 @@ void SpdyProxyClientSocketSpdy2Test::Initialize(MockRead* reads,
spdy_session_->InitializeWithSocket(connection.release(), false, OK);
// Create the SPDY Stream.
- ASSERT_EQ(
- OK,
- spdy_session_->CreateStream(url_, LOWEST, &spdy_stream_, net_log_.bound(),
- CompletionCallback()));
+ spdy_stream_ =
+ CreateStreamSynchronously(spdy_session_, url_, LOWEST, net_log_.bound());
+ ASSERT_TRUE(spdy_stream_.get() != NULL);
// Create the SpdyProxyClientSocket.
sock_.reset(
diff --git a/net/spdy/spdy_proxy_client_socket_spdy3_unittest.cc b/net/spdy/spdy_proxy_client_socket_spdy3_unittest.cc
index 05dc3fd..77a1502 100644
--- a/net/spdy/spdy_proxy_client_socket_spdy3_unittest.cc
+++ b/net/spdy/spdy_proxy_client_socket_spdy3_unittest.cc
@@ -23,6 +23,7 @@
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_protocol.h"
#include "net/spdy/spdy_session_pool.h"
+#include "net/spdy/spdy_test_util_common.h"
#include "net/spdy/spdy_test_util_spdy3.h"
#include "testing/platform_test.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -199,10 +200,9 @@ void SpdyProxyClientSocketSpdy3Test::Initialize(MockRead* reads,
spdy_session_->InitializeWithSocket(connection.release(), false, OK);
// Create the SPDY Stream.
- ASSERT_EQ(
- OK,
- spdy_session_->CreateStream(url_, LOWEST, &spdy_stream_, net_log_.bound(),
- CompletionCallback()));
+ spdy_stream_ =
+ CreateStreamSynchronously(spdy_session_, url_, LOWEST, net_log_.bound());
+ ASSERT_TRUE(spdy_stream_.get() != NULL);
// Create the SpdyProxyClientSocket.
sock_.reset(
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 714b4f0..a2b5da4 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -4,6 +4,7 @@
#include "net/spdy/spdy_session.h"
+#include <algorithm>
#include <map>
#include "base/basictypes.h"
@@ -201,6 +202,74 @@ const size_t kDefaultInitialRecvWindowSize = 10 * 1024 * 1024; // 10MB
} // namespace
+SpdyStreamRequest::SpdyStreamRequest() {
+ Reset();
+}
+
+SpdyStreamRequest::~SpdyStreamRequest() {
+ CancelRequest();
+}
+
+int SpdyStreamRequest::StartRequest(
+ const scoped_refptr<SpdySession>& session,
+ const GURL& url,
+ RequestPriority priority,
+ const BoundNetLog& net_log,
+ const CompletionCallback& callback) {
+ DCHECK(session);
+ DCHECK(!session_);
+ DCHECK(!stream_);
+ DCHECK(callback_.is_null());
+
+ session_ = session;
+ url_ = url;
+ priority_ = priority;
+ net_log_ = net_log;
+ callback_ = callback;
+
+ scoped_refptr<SpdyStream> stream;
+ int rv = session->TryCreateStream(this, &stream);
+ if (rv == OK) {
+ Reset();
+ stream_ = stream;
+ }
+ return rv;
+}
+
+void SpdyStreamRequest::CancelRequest() {
+ if (session_)
+ session_->CancelStreamRequest(this);
+ Reset();
+}
+
+scoped_refptr<SpdyStream> SpdyStreamRequest::ReleaseStream() {
+ DCHECK(!session_.get());
+ scoped_refptr<SpdyStream> stream = stream_;
+ DCHECK(stream.get());
+ Reset();
+ return stream;
+}
+
+void SpdyStreamRequest::OnRequestComplete(
+ const scoped_refptr<SpdyStream>& stream,
+ int rv) {
+ DCHECK(session_.get());
+ DCHECK(!callback_.is_null());
+ CompletionCallback callback = callback_;
+ Reset();
+ stream_ = stream;
+ callback.Run(rv);
+}
+
+void SpdyStreamRequest::Reset() {
+ session_ = NULL;
+ stream_ = NULL;
+ url_ = GURL();
+ priority_ = MINIMUM_PRIORITY;
+ net_log_ = BoundNetLog();
+ callback_.Reset();
+}
+
// static
void SpdySession::SpdyIOBufferProducer::ActivateStream(
SpdySession* spdy_session,
@@ -302,28 +371,6 @@ SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair,
// TODO(mbelshe): consider randomization of the stream_hi_water_mark.
}
-SpdySession::PendingCreateStream::PendingCreateStream(
- const GURL& url, RequestPriority priority,
- scoped_refptr<SpdyStream>* spdy_stream,
- const BoundNetLog& stream_net_log,
- const CompletionCallback& callback)
- : url(&url),
- priority(priority),
- spdy_stream(spdy_stream),
- stream_net_log(&stream_net_log),
- callback(callback) {
-}
-
-SpdySession::PendingCreateStream::~PendingCreateStream() {}
-
-SpdySession::CallbackResultPair::CallbackResultPair(
- const CompletionCallback& callback_in, int result_in)
- : callback(callback_in),
- result(result_in) {
-}
-
-SpdySession::CallbackResultPair::~CallbackResultPair() {}
-
SpdySession::~SpdySession() {
if (state_ != STATE_CLOSED) {
state_ = STATE_CLOSED;
@@ -341,7 +388,10 @@ SpdySession::~SpdySession() {
DCHECK_EQ(0u, num_active_streams());
DCHECK_EQ(0u, num_unclaimed_pushed_streams());
- DCHECK(pending_callback_map_.empty());
+ for (int i = NUM_PRIORITIES - 1; i >= MINIMUM_PRIORITY; --i) {
+ DCHECK(pending_create_stream_queues_[i].empty());
+ }
+ DCHECK(pending_stream_request_completions_.empty());
RecordHistograms();
@@ -460,95 +510,29 @@ int SpdySession::GetPushStream(
return 0;
}
-int SpdySession::CreateStream(
- const GURL& url,
- RequestPriority priority,
- scoped_refptr<SpdyStream>* spdy_stream,
- const BoundNetLog& stream_net_log,
- const CompletionCallback& callback) {
+int SpdySession::TryCreateStream(SpdyStreamRequest* request,
+ scoped_refptr<SpdyStream>* stream) {
if (!max_concurrent_streams_ ||
(active_streams_.size() + created_streams_.size() <
max_concurrent_streams_)) {
- return CreateStreamImpl(url, priority, spdy_stream, stream_net_log);
+ return CreateStream(*request, stream);
}
stalled_streams_++;
net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS);
- pending_create_stream_queues_[priority].push(
- PendingCreateStream(url, priority, spdy_stream,
- stream_net_log, callback));
+ pending_create_stream_queues_[request->priority()].push_back(request);
return ERR_IO_PENDING;
}
-void SpdySession::ProcessPendingCreateStreams() {
- 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()) {
- PendingCreateStream pending_create =
- pending_create_stream_queues_[i].front();
- pending_create_stream_queues_[i].pop();
- no_pending_create_streams = false;
- int error = CreateStreamImpl(*pending_create.url,
- pending_create.priority,
- pending_create.spdy_stream,
- *pending_create.stream_net_log);
- scoped_refptr<SpdyStream>* stream = pending_create.spdy_stream;
- DCHECK(!ContainsKey(pending_callback_map_, stream));
- pending_callback_map_.insert(std::make_pair(stream,
- CallbackResultPair(pending_create.callback, error)));
- MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&SpdySession::InvokeUserStreamCreationCallback,
- weak_factory_.GetWeakPtr(), stream));
- break;
- }
- }
- if (no_pending_create_streams)
- return; // there were no streams in any queue
- }
-}
-
-void SpdySession::CancelPendingCreateStreams(
- const scoped_refptr<SpdyStream>* spdy_stream) {
- PendingCallbackMap::iterator it = pending_callback_map_.find(spdy_stream);
- if (it != pending_callback_map_.end()) {
- pending_callback_map_.erase(it);
- return;
- }
-
- for (int i = 0; i < NUM_PRIORITIES; ++i) {
- PendingCreateStreamQueue tmp;
- // Make a copy removing this trans
- while (!pending_create_stream_queues_[i].empty()) {
- PendingCreateStream pending_create =
- pending_create_stream_queues_[i].front();
- pending_create_stream_queues_[i].pop();
- if (pending_create.spdy_stream != spdy_stream)
- tmp.push(pending_create);
- }
- // Now copy it back
- while (!tmp.empty()) {
- pending_create_stream_queues_[i].push(tmp.front());
- tmp.pop();
- }
- }
-}
-
-int SpdySession::CreateStreamImpl(
- const GURL& url,
- RequestPriority priority,
- scoped_refptr<SpdyStream>* spdy_stream,
- const BoundNetLog& stream_net_log) {
- DCHECK_GE(priority, MINIMUM_PRIORITY);
- DCHECK_LT(priority, NUM_PRIORITIES);
+int SpdySession::CreateStream(const SpdyStreamRequest& request,
+ scoped_refptr<SpdyStream>* stream) {
+ DCHECK_GE(request.priority(), MINIMUM_PRIORITY);
+ DCHECK_LT(request.priority(), NUM_PRIORITIES);
// Make sure that we don't try to send https/wss over an unauthenticated, but
// encrypted SSL socket.
if (is_secure_ && certificate_error_code_ != OK &&
- (url.SchemeIs("https") || url.SchemeIs("wss"))) {
+ (request.url().SchemeIs("https") || request.url().SchemeIs("wss"))) {
RecordProtocolErrorHistogram(
PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION);
CloseSessionOnError(
@@ -559,27 +543,81 @@ int SpdySession::CreateStreamImpl(
return ERR_SPDY_PROTOCOL_ERROR;
}
- const std::string& path = url.PathForRequest();
+ const std::string& path = request.url().PathForRequest();
- *spdy_stream = new SpdyStream(this,
- false,
- stream_net_log);
- const scoped_refptr<SpdyStream>& stream = *spdy_stream;
+ *stream = new SpdyStream(this, false, request.net_log());
- stream->set_priority(priority);
- stream->set_path(path);
- stream->set_send_window_size(stream_initial_send_window_size_);
- stream->set_recv_window_size(stream_initial_recv_window_size_);
- created_streams_.insert(stream);
+ (*stream)->set_priority(request.priority());
+ (*stream)->set_path(path);
+ (*stream)->set_send_window_size(stream_initial_send_window_size_);
+ (*stream)->set_recv_window_size(stream_initial_recv_window_size_);
+ created_streams_.insert(*stream);
- UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyPriorityCount",
- static_cast<int>(priority), 0, 10, 11);
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Net.SpdyPriorityCount",
+ static_cast<int>(request.priority()), 0, 10, 11);
// TODO(mbelshe): Optimize memory allocations
return OK;
}
+void SpdySession::CancelStreamRequest(SpdyStreamRequest* request) {
+ if (DCHECK_IS_ON()) {
+ // |request| should not be in a queue not matching its priority.
+ for (int i = 0; i < NUM_PRIORITIES; ++i) {
+ if (request->priority() == i)
+ continue;
+ PendingStreamRequestQueue* queue = &pending_create_stream_queues_[i];
+ DCHECK(std::find(queue->begin(), queue->end(), request) == queue->end());
+ }
+ }
+
+ PendingStreamRequestQueue* queue =
+ &pending_create_stream_queues_[request->priority()];
+ // Remove |request| from |queue| while preserving the order of the
+ // other elements.
+ PendingStreamRequestQueue::iterator it =
+ std::find(queue->begin(), queue->end(), request);
+ if (it != queue->end()) {
+ it = queue->erase(it);
+ // |request| should be in the queue at most once, and if it is
+ // present, should not be pending completion.
+ DCHECK(std::find(it, queue->end(), request) == queue->end());
+ DCHECK(!ContainsKey(pending_stream_request_completions_,
+ request));
+ return;
+ }
+
+ pending_stream_request_completions_.erase(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();
+ 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);
+ 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
+ }
+}
+
bool SpdySession::NeedsCredentials() const {
if (!is_secure_)
return false;
@@ -778,7 +816,7 @@ void SpdySession::CloseStream(SpdyStreamId stream_id, int status) {
void SpdySession::CloseCreatedStream(SpdyStream* stream, int status) {
DCHECK_EQ(0u, stream->stream_id());
created_streams_.erase(scoped_refptr<SpdyStream>(stream));
- ProcessPendingCreateStreams();
+ ProcessPendingStreamRequests();
}
void SpdySession::ResetStream(SpdyStreamId stream_id,
@@ -1053,11 +1091,11 @@ void SpdySession::CloseAllStreams(net::Error status) {
}
for (int i = 0; i < NUM_PRIORITIES; ++i) {
- while (!pending_create_stream_queues_[i].empty()) {
- PendingCreateStream pending_create =
- pending_create_stream_queues_[i].front();
- pending_create_stream_queues_[i].pop();
- pending_create.callback.Run(ERR_ABORTED);
+ PendingStreamRequestQueue queue;
+ queue.swap(pending_create_stream_queues_[i]);
+ for (PendingStreamRequestQueue::const_iterator it = queue.begin();
+ it != queue.end(); ++it) {
+ (*it)->OnRequestComplete(NULL, ERR_ABORTED);
}
}
@@ -1274,7 +1312,7 @@ void SpdySession::DeleteStream(SpdyStreamId id, int status) {
active_streams_.erase(it2);
if (stream)
stream->OnClose(status);
- ProcessPendingCreateStreams();
+ ProcessPendingStreamRequests();
}
void SpdySession::RemoveFromPool() {
@@ -1861,7 +1899,7 @@ void SpdySession::HandleSetting(uint32 id, uint32 value) {
case SETTINGS_MAX_CONCURRENT_STREAMS:
max_concurrent_streams_ = std::min(static_cast<size_t>(value),
kMaxConcurrentStreamLimit);
- ProcessPendingCreateStreams();
+ ProcessPendingStreamRequests();
break;
case SETTINGS_INITIAL_WINDOW_SIZE: {
if (flow_control_state_ < FLOW_CONTROL_STREAM) {
@@ -2087,18 +2125,19 @@ void SpdySession::RecordHistograms() {
}
}
-void SpdySession::InvokeUserStreamCreationCallback(
- scoped_refptr<SpdyStream>* stream) {
- PendingCallbackMap::iterator it = pending_callback_map_.find(stream);
+void SpdySession::CompleteStreamRequest(SpdyStreamRequest* pending_request) {
+ PendingStreamRequestCompletionSet::iterator it =
+ pending_stream_request_completions_.find(pending_request);
- // Exit if the request has already been cancelled.
- if (it == pending_callback_map_.end())
+ // Abort if the request has already been cancelled.
+ if (it == pending_stream_request_completions_.end())
return;
- CompletionCallback callback = it->second.callback;
- int result = it->second.result;
- pending_callback_map_.erase(it);
- callback.Run(result);
+ scoped_refptr<SpdyStream> stream;
+ int rv = CreateStream(*pending_request, &stream);
+ pending_stream_request_completions_.erase(it);
+
+ pending_request->OnRequestComplete(stream, rv);
}
SSLClientSocket* SpdySession::GetSSLClientSocket() const {
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 865589d..b025bdf 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -5,10 +5,10 @@
#ifndef NET_SPDY_SPDY_SESSION_H_
#define NET_SPDY_SPDY_SESSION_H_
-#include <algorithm>
+#include <deque>
#include <list>
#include <map>
-#include <queue>
+#include <set>
#include <string>
#include "base/gtest_prod_util.h"
@@ -98,6 +98,66 @@ COMPILE_ASSERT(PROTOCOL_ERROR_UNEXPECTED_PING ==
RST_STREAM_NUM_STATUS_CODES + STATUS_CODE_INVALID),
SpdyProtocolErrorDetails_SpdyErrors_mismatch);
+// A helper class used to manage a request to create a stream.
+class NET_EXPORT_PRIVATE SpdyStreamRequest {
+ public:
+ SpdyStreamRequest();
+ // Calls CancelRequest().
+ ~SpdyStreamRequest();
+
+ // Starts the request to create a stream. If OK is returned, then
+ // ReleaseStream() may be called. If ERR_IO_PENDING is returned,
+ // then when the stream is created, |callback| will be called, at
+ // which point ReleaseStream() may be called. Otherwise, the stream
+ // is not created, an error is returned, and ReleaseStream() may not
+ // be called.
+ //
+ // If OK is returned, must not be called again without
+ // ReleaseStream() being called first. If ERR_IO_PENDING is
+ // returned, must not be called again without CancelRequest() or
+ // ReleaseStream() being called first. Otherwise, in case of an
+ // immediate error, this may be called again.
+ int StartRequest(const scoped_refptr<SpdySession>& session,
+ const GURL& url,
+ RequestPriority priority,
+ const BoundNetLog& net_log,
+ const CompletionCallback& callback);
+
+ // Cancels any pending stream creation request. May be called
+ // repeatedly.
+ void CancelRequest();
+
+ // Transfers the created stream (guaranteed to not be NULL) to the
+ // caller. Must be called at most once after StartRequest() returns
+ // OK or |callback| is called with OK.
+ scoped_refptr<SpdyStream> ReleaseStream();
+
+ private:
+ friend class SpdySession;
+
+ // Called by |session_| when the stream attempt is
+ // finished. |stream| is non-NULL exactly when |rv| is OK. Also
+ // called with a NULL stream and ERR_ABORTED if |session_| is
+ // destroyed while the stream attempt is still pending.
+ void OnRequestComplete(const scoped_refptr<SpdyStream>& stream, int rv);
+
+ // Accessors called by |session_|.
+ const GURL& url() const { return url_; }
+ RequestPriority priority() const { return priority_; }
+ const BoundNetLog& net_log() const { return net_log_; }
+
+ void Reset();
+
+ scoped_refptr<SpdySession> session_;
+ scoped_refptr<SpdyStream> stream_;
+ GURL url_;
+ RequestPriority priority_;
+ BoundNetLog net_log_;
+ CompletionCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(SpdyStreamRequest);
+};
+
class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
public BufferedSpdyFramerVisitorInterface {
public:
@@ -177,18 +237,6 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
scoped_refptr<SpdyStream>* spdy_stream,
const BoundNetLog& stream_net_log);
- // Create a new stream for a given |url|. Writes it out to |spdy_stream|.
- // Returns a net error code, possibly ERR_IO_PENDING.
- int CreateStream(
- const GURL& url,
- RequestPriority priority,
- scoped_refptr<SpdyStream>* spdy_stream,
- const BoundNetLog& stream_net_log,
- const CompletionCallback& callback);
-
- // Remove PendingCreateStream objects on transaction deletion
- void CancelPendingCreateStreams(const scoped_refptr<SpdyStream>* spdy_stream);
-
// Used by SpdySessionPool to initialize with a pre-existing SSL socket. For
// testing, setting is_secure to false allows initialization with a
// pre-existing TCP socket.
@@ -384,6 +432,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
private:
friend class base::RefCounted<SpdySession>;
+ friend class SpdyStreamRequest;
// Allow tests to access our innards for testing purposes.
FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy2Test, ClientPing);
@@ -402,22 +451,9 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy3Test, AdjustSendWindowSize31);
FRIEND_TEST_ALL_PREFIXES(SpdySessionSpdy3Test, SessionFlowControlEndToEnd31);
- struct PendingCreateStream {
- PendingCreateStream(const GURL& url, RequestPriority priority,
- scoped_refptr<SpdyStream>* spdy_stream,
- const BoundNetLog& stream_net_log,
- const CompletionCallback& callback);
+ typedef std::deque<SpdyStreamRequest*> PendingStreamRequestQueue;
+ typedef std::set<SpdyStreamRequest*> PendingStreamRequestCompletionSet;
- ~PendingCreateStream();
-
- const GURL* url;
- RequestPriority priority;
- scoped_refptr<SpdyStream>* spdy_stream;
- const BoundNetLog* stream_net_log;
- CompletionCallback callback;
- };
- typedef std::queue<PendingCreateStream, std::list<PendingCreateStream> >
- PendingCreateStreamQueue;
typedef std::map<int, scoped_refptr<SpdyStream> > ActiveStreamMap;
typedef std::map<std::string,
std::pair<scoped_refptr<SpdyStream>, base::TimeTicks> > PushedStreamMap;
@@ -425,6 +461,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
typedef std::set<scoped_refptr<SpdyStream> > CreatedStreamSet;
typedef std::map<SpdyIOBufferProducer*, SpdyStream*> StreamProducerMap;
+
class SpdyIOBufferProducerCompare {
public:
bool operator() (const SpdyIOBufferProducer* lhs,
@@ -432,21 +469,11 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
return lhs->GetPriority() < rhs->GetPriority();
}
};
+
typedef std::priority_queue<SpdyIOBufferProducer*,
std::vector<SpdyIOBufferProducer*>,
SpdyIOBufferProducerCompare> WriteQueue;
- struct CallbackResultPair {
- CallbackResultPair(const CompletionCallback& callback_in, int result_in);
- ~CallbackResultPair();
-
- CompletionCallback callback;
- int result;
- };
-
- typedef std::map<const scoped_refptr<SpdyStream>*, CallbackResultPair>
- PendingCallbackMap;
-
enum State {
STATE_IDLE,
STATE_CONNECTING,
@@ -457,12 +484,28 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
virtual ~SpdySession();
- void ProcessPendingCreateStreams();
- int CreateStreamImpl(
- const GURL& url,
- RequestPriority priority,
- scoped_refptr<SpdyStream>* spdy_stream,
- const BoundNetLog& stream_net_log);
+ // Called by SpdyStreamRequest to start a request to create a
+ // stream. If OK is returned, then |stream| will be filled in with a
+ // valid stream. If ERR_IO_PENDING is returned, then
+ // |request->OnRequestComplete()| will be called when the stream is
+ // created (unless it is cancelled). Otherwise, no stream is created
+ // and the error is returned.
+ int TryCreateStream(SpdyStreamRequest* request,
+ scoped_refptr<SpdyStream>* stream);
+
+ // Actually create a stream into |stream|. Returns OK if successful;
+ // otherwise, returns an error and |stream| is not filled.
+ int CreateStream(const SpdyStreamRequest& request,
+ scoped_refptr<SpdyStream>* stream);
+
+ // Called by SpdyStreamRequest to remove |request| from the stream
+ // creation queue.
+ void CancelStreamRequest(SpdyStreamRequest* request);
+
+ // Called when there is room to create more streams (e.g., a stream
+ // was closed). Processes as many pending stream requests as
+ // possible.
+ void ProcessPendingStreamRequests();
// Start the DoLoop to read data from socket.
void StartRead();
@@ -493,7 +536,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
// SETTINGS control frame, update our SpdySession accordingly.
void HandleSetting(uint32 id, uint32 value);
- // Adjust the send window size of all ActiveStreams and PendingCreateStreams.
+ // Adjust the send window size of all ActiveStreams and PendingStreamRequests.
void UpdateStreamsSendWindowSize(int32 delta_window_size);
// Send the PING (preface-PING) frame.
@@ -558,7 +601,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
// Invokes a user callback for stream creation. We provide this method so it
// can be deferred to the MessageLoop, so we avoid re-entrancy problems.
- void InvokeUserStreamCreationCallback(scoped_refptr<SpdyStream>* stream);
+ void CompleteStreamRequest(SpdyStreamRequest* pending_request);
// Remove old unclaimed pushed streams.
void DeleteExpiredPushedStreams();
@@ -651,11 +694,6 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
// method.
base::WeakPtrFactory<SpdySession> weak_factory_;
- // Map of the SpdyStreams for which we have a pending Task to invoke a
- // callback. This is necessary since, before we invoke said callback, it's
- // possible that the request is cancelled.
- PendingCallbackMap pending_callback_map_;
-
// The domain this session is connected to.
const HostPortProxyPair host_port_proxy_pair_;
@@ -676,9 +714,15 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
int stream_hi_water_mark_; // The next stream id to use.
- // Queue, for each priority, of pending Create Streams that have not
- // yet been satisfied
- PendingCreateStreamQueue pending_create_stream_queues_[NUM_PRIORITIES];
+ // Queue, for each priority, of pending stream requests that have
+ // not yet been satisfied.
+ PendingStreamRequestQueue pending_create_stream_queues_[NUM_PRIORITIES];
+
+ // A set of requests that are waiting to be completed (i.e., for the
+ // stream to actually be created). This is necessary since we kick
+ // off the stream creation asynchronously, and so the request may be
+ // cancelled before the asynchronous task to create the stream runs.
+ PendingStreamRequestCompletionSet pending_stream_request_completions_;
// Map from stream id to all active streams. Streams are active in the sense
// that they have a consumer (typically SpdyNetworkTransaction and regardless
diff --git a/net/spdy/spdy_session_spdy2_unittest.cc b/net/spdy/spdy_session_spdy2_unittest.cc
index 93263b3..65cc61f 100644
--- a/net/spdy/spdy_session_spdy2_unittest.cc
+++ b/net/spdy/spdy_session_spdy2_unittest.cc
@@ -17,6 +17,7 @@
#include "net/spdy/spdy_session_pool.h"
#include "net/spdy/spdy_session_test_util.h"
#include "net/spdy/spdy_stream.h"
+#include "net/spdy/spdy_test_util_common.h"
#include "net/spdy/spdy_test_util_spdy2.h"
#include "testing/platform_test.h"
@@ -272,11 +273,10 @@ TEST_F(SpdySessionSpdy2Test, ClientPing) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
TestCompletionCallback callback1;
- EXPECT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
-
scoped_ptr<TestSpdyStreamDelegate> delegate(
new TestSpdyStreamDelegate(callback1.callback()));
spdy_stream1->SetDelegate(delegate.get());
@@ -328,10 +328,10 @@ TEST_F(SpdySessionSpdy2Test, ServerPing) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
TestCompletionCallback callback1;
- EXPECT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
scoped_ptr<TestSpdyStreamDelegate> delegate(
new TestSpdyStreamDelegate(callback1.callback()));
spdy_stream1->SetDelegate(delegate.get());
@@ -420,10 +420,10 @@ TEST_F(SpdySessionSpdy2Test, FailedPing) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
TestCompletionCallback callback1;
- EXPECT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
scoped_ptr<TestSpdyStreamDelegate> delegate(
new TestSpdyStreamDelegate(callback1.callback()));
spdy_stream1->SetDelegate(delegate.get());
@@ -457,40 +457,6 @@ TEST_F(SpdySessionSpdy2Test, FailedPing) {
session = NULL;
}
-class StreamReleaserCallback : public TestCompletionCallbackBase {
- public:
- StreamReleaserCallback(SpdySession* session,
- SpdyStream* first_stream)
- : session_(session),
- first_stream_(first_stream),
- ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
- base::Bind(&StreamReleaserCallback::OnComplete,
- base::Unretained(this)))) {
- }
-
- virtual ~StreamReleaserCallback() {}
-
- scoped_refptr<SpdyStream>* stream() { return &stream_; }
-
- const CompletionCallback& callback() const { return callback_; }
-
- private:
- void OnComplete(int result) {
- session_->CloseSessionOnError(ERR_FAILED, false, "On complete.");
- session_ = NULL;
- first_stream_->Cancel();
- first_stream_ = NULL;
- stream_->Cancel();
- stream_ = NULL;
- SetResult(result);
- }
-
- scoped_refptr<SpdySession> session_;
- scoped_refptr<SpdyStream> first_stream_;
- scoped_refptr<SpdyStream> stream_;
- CompletionCallback callback_;
-};
-
// TODO(kristianm): Could also test with more sessions where some are idle,
// and more than one session to a HostPortPair.
TEST_F(SpdySessionSpdy2Test, CloseIdleSessions) {
@@ -501,33 +467,30 @@ TEST_F(SpdySessionSpdy2Test, CloseIdleSessions) {
HostPortPair test_host_port_pair1(kTestHost1, 80);
HostPortProxyPair pair1(test_host_port_pair1, ProxyServer::Direct());
scoped_refptr<SpdySession> session1 = GetSession(pair1);
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1(kTestHost1);
- EXPECT_EQ(OK, session1->CreateStream(url1, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session1, url1, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
// Set up session 2
const std::string kTestHost2("http://www.b.com");
HostPortPair test_host_port_pair2(kTestHost2, 80);
HostPortProxyPair pair2(test_host_port_pair2, ProxyServer::Direct());
scoped_refptr<SpdySession> session2 = GetSession(pair2);
- scoped_refptr<SpdyStream> spdy_stream2;
- TestCompletionCallback callback2;
GURL url2(kTestHost2);
- EXPECT_EQ(OK, session2->CreateStream(url2, MEDIUM, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ scoped_refptr<SpdyStream> spdy_stream2 =
+ CreateStreamSynchronously(session2, url2, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream2.get() != NULL);
// Set up session 3
const std::string kTestHost3("http://www.c.com");
HostPortPair test_host_port_pair3(kTestHost3, 80);
HostPortProxyPair pair3(test_host_port_pair3, ProxyServer::Direct());
scoped_refptr<SpdySession> session3 = GetSession(pair3);
- scoped_refptr<SpdyStream> spdy_stream3;
- TestCompletionCallback callback3;
GURL url3(kTestHost3);
- EXPECT_EQ(OK, session3->CreateStream(url3, MEDIUM, &spdy_stream3,
- BoundNetLog(), callback3.callback()));
+ scoped_refptr<SpdyStream> spdy_stream3 =
+ CreateStreamSynchronously(session3, url3, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream3.get() != NULL);
// All sessions are active and not closed
EXPECT_TRUE(session1->is_active());
@@ -624,17 +587,17 @@ TEST_F(SpdySessionSpdy2Test, OnSettings) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
// Create 2 streams. First will succeed. Second will be pending.
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
- EXPECT_EQ(OK,
- session->CreateStream(test_url_, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
StreamReleaserCallback stream_releaser(session, spdy_stream1);
+ SpdyStreamRequest request;
ASSERT_EQ(ERR_IO_PENDING,
- session->CreateStream(test_url_, MEDIUM, stream_releaser.stream(),
- BoundNetLog(), stream_releaser.callback()));
+ request.StartRequest(session, test_url_, MEDIUM,
+ BoundNetLog(),
+ stream_releaser.MakeCallback(&request)));
// Make sure |stream_releaser| holds the last refs.
session = NULL;
@@ -674,25 +637,26 @@ TEST_F(SpdySessionSpdy2Test, CancelPendingCreateStream) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
+ // Create 2 streams. First will succeed. Second will be pending.
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
+
// Use scoped_ptr to let us invalidate the memory when we want to, to trigger
// a valgrind error if the callback is invoked when it's not supposed to be.
scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
- // Create 2 streams. First will succeed. Second will be pending.
- scoped_refptr<SpdyStream> spdy_stream1;
- ASSERT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback->callback()));
-
- scoped_refptr<SpdyStream> spdy_stream2;
+ SpdyStreamRequest request;
ASSERT_EQ(ERR_IO_PENDING,
- session->CreateStream(test_url_, MEDIUM, &spdy_stream2,
- BoundNetLog(), callback->callback()));
+ request.StartRequest(session, test_url_, MEDIUM,
+ BoundNetLog(),
+ callback->callback()));
// Release the first one, this will allow the second to be created.
spdy_stream1->Cancel();
spdy_stream1 = NULL;
- session->CancelPendingCreateStreams(&spdy_stream2);
+ request.CancelRequest();
callback.reset();
// Should not crash when running the pending callback.
@@ -1028,17 +992,16 @@ TEST_F(SpdySessionSpdy2Test, OutOfOrderSynStreams) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url, LOWEST, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- scoped_refptr<SpdyStream> spdy_stream2;
- TestCompletionCallback callback2;
- EXPECT_EQ(OK, session->CreateStream(url, HIGHEST, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ scoped_refptr<SpdyStream> spdy_stream2 =
+ CreateStreamSynchronously(session, url, HIGHEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream2.get() != NULL);
EXPECT_EQ(0u, spdy_stream2->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -1101,18 +1064,16 @@ TEST_F(SpdySessionSpdy2Test, CancelStream) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, HIGHEST, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, HIGHEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- scoped_refptr<SpdyStream> spdy_stream2;
- TestCompletionCallback callback2;
GURL url2("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url2, LOWEST, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ scoped_refptr<SpdyStream> spdy_stream2 =
+ CreateStreamSynchronously(session, url2, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream2.get() != NULL);
EXPECT_EQ(0u, spdy_stream2->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -1176,18 +1137,16 @@ TEST_F(SpdySessionSpdy2Test, CloseSessionWithTwoCreatedStreams) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, HIGHEST, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, HIGHEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- scoped_refptr<SpdyStream> spdy_stream2;
- TestCompletionCallback callback2;
GURL url2("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url2, LOWEST, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ scoped_refptr<SpdyStream> spdy_stream2 =
+ CreateStreamSynchronously(session, url2, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream2.get() != NULL);
EXPECT_EQ(0u, spdy_stream2->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -1422,27 +1381,27 @@ TEST_F(SpdySessionSpdy2Test, CloseTwoStalledCreateStream) {
// Read the settings frame.
data.RunFor(1);
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, LOWEST, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
-
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- scoped_refptr<SpdyStream> spdy_stream2;
TestCompletionCallback callback2;
GURL url2("http://www.google.com");
- EXPECT_EQ(ERR_IO_PENDING,
- session->CreateStream(url2, LOWEST, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ SpdyStreamRequest request2;
+ ASSERT_EQ(ERR_IO_PENDING,
+ request2.StartRequest(session, url2, LOWEST,
+ BoundNetLog(),
+ callback2.callback()));
- scoped_refptr<SpdyStream> spdy_stream3;
TestCompletionCallback callback3;
GURL url3("http://www.google.com");
- EXPECT_EQ(ERR_IO_PENDING,
- session->CreateStream(url3, LOWEST, &spdy_stream3,
- BoundNetLog(), callback3.callback()));
+ SpdyStreamRequest request3;
+ ASSERT_EQ(ERR_IO_PENDING,
+ request3.StartRequest(session, url3, LOWEST,
+ BoundNetLog(),
+ callback3.callback()));
EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(2u, session->pending_create_stream_queues(LOWEST));
@@ -1462,33 +1421,34 @@ TEST_F(SpdySessionSpdy2Test, CloseTwoStalledCreateStream) {
EXPECT_TRUE(spdy_stream1->HasUrl());
spdy_stream1->SendRequest(false);
- // Run until 1st stream is closed.
+ // Run until 1st stream is closed and 2nd one is opened.
EXPECT_EQ(0u, spdy_stream1->stream_id());
data.RunFor(3);
EXPECT_EQ(1u, spdy_stream1->stream_id());
- EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
- EXPECT_EQ(1u, session->pending_create_stream_queues(LOWEST));
+ EXPECT_EQ(2u, session->num_active_streams() + session->num_created_streams());
+ EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
- EXPECT_TRUE(spdy_stream2.get() != NULL);
- spdy_stream2->set_spdy_headers(headers2.Pass());
- EXPECT_TRUE(spdy_stream2->HasUrl());
- spdy_stream2->SendRequest(false);
+ scoped_refptr<SpdyStream> stream2 = request2.ReleaseStream();
+ stream2->set_spdy_headers(headers2.Pass());
+ EXPECT_TRUE(stream2->HasUrl());
+ stream2->SendRequest(false);
// Run until 2nd stream is closed.
- EXPECT_EQ(0u, spdy_stream2->stream_id());
+ EXPECT_EQ(0u, stream2->stream_id());
data.RunFor(3);
- EXPECT_EQ(3u, spdy_stream2->stream_id());
+ EXPECT_EQ(3u, stream2->stream_id());
EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
- EXPECT_TRUE(spdy_stream3.get() != NULL);
- spdy_stream3->set_spdy_headers(headers3.Pass());
- EXPECT_TRUE(spdy_stream3->HasUrl());
- spdy_stream3->SendRequest(false);
+ scoped_refptr<SpdyStream> stream3 = request3.ReleaseStream();
+ ASSERT_TRUE(stream3.get() != NULL);
+ stream3->set_spdy_headers(headers3.Pass());
+ EXPECT_TRUE(stream3->HasUrl());
+ stream3->SendRequest(false);
- EXPECT_EQ(0u, spdy_stream3->stream_id());
+ EXPECT_EQ(0u, stream3->stream_id());
data.RunFor(4);
- EXPECT_EQ(5u, spdy_stream3->stream_id());
+ EXPECT_EQ(5u, stream3->stream_id());
EXPECT_EQ(0u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
}
@@ -1520,27 +1480,27 @@ TEST_F(SpdySessionSpdy2Test, CancelTwoStalledCreateStream) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- ASSERT_EQ(OK,
- session->CreateStream(url1, LOWEST, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- scoped_refptr<SpdyStream> spdy_stream2;
TestCompletionCallback callback2;
GURL url2("http://www.google.com");
+ SpdyStreamRequest request2;
ASSERT_EQ(ERR_IO_PENDING,
- session->CreateStream(url2, LOWEST, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ request2.StartRequest(session, url2, LOWEST,
+ BoundNetLog(),
+ callback2.callback()));
- scoped_refptr<SpdyStream> spdy_stream3;
TestCompletionCallback callback3;
GURL url3("http://www.google.com");
+ SpdyStreamRequest request3;
ASSERT_EQ(ERR_IO_PENDING,
- session->CreateStream(url3, LOWEST, &spdy_stream3,
- BoundNetLog(), callback3.callback()));
+ request3.StartRequest(session, url3, LOWEST,
+ BoundNetLog(),
+ callback3.callback()));
EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(2u, session->pending_create_stream_queues(LOWEST));
@@ -1549,23 +1509,18 @@ TEST_F(SpdySessionSpdy2Test, CancelTwoStalledCreateStream) {
EXPECT_TRUE(spdy_stream1.get() != NULL);
spdy_stream1->Cancel();
spdy_stream1 = NULL;
- session->CancelPendingCreateStreams(&spdy_stream1);
- EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
- EXPECT_EQ(1u, session->pending_create_stream_queues(LOWEST));
+
+ callback2.WaitForResult();
+ EXPECT_EQ(2u, session->num_active_streams() + session->num_created_streams());
+ EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
// Cancel the second stream, this will allow the third stream to be created.
- EXPECT_TRUE(spdy_stream2.get() != NULL);
- spdy_stream2->Cancel();
- spdy_stream2 = NULL;
- session->CancelPendingCreateStreams(&spdy_stream2);
+ request2.ReleaseStream()->Cancel();
EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
// Cancel the third stream.
- EXPECT_TRUE(spdy_stream3.get() != NULL);
- spdy_stream3->Cancel();
- spdy_stream3 = NULL;
- session->CancelPendingCreateStreams(&spdy_stream3);
+ request3.ReleaseStream()->Cancel();
EXPECT_EQ(0u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
}
@@ -1682,11 +1637,10 @@ TEST_F(SpdySessionSpdy2Test, ReadDataWithoutYielding) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -1773,11 +1727,10 @@ TEST_F(SpdySessionSpdy2Test, TestYieldingDuringReadData) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -1887,11 +1840,10 @@ TEST_F(SpdySessionSpdy2Test, TestYieldingDuringAsyncReadData) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -1963,11 +1915,10 @@ TEST_F(SpdySessionSpdy2Test, GoAwayWhileInDoLoop) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
diff --git a/net/spdy/spdy_session_spdy3_unittest.cc b/net/spdy/spdy_session_spdy3_unittest.cc
index 6dc72d4..a0d8583 100644
--- a/net/spdy/spdy_session_spdy3_unittest.cc
+++ b/net/spdy/spdy_session_spdy3_unittest.cc
@@ -22,6 +22,7 @@
#include "net/spdy/spdy_session_test_util.h"
#include "net/spdy/spdy_stream.h"
#include "net/spdy/spdy_stream_test_util.h"
+#include "net/spdy/spdy_test_util_common.h"
#include "net/spdy/spdy_test_util_spdy3.h"
#include "testing/platform_test.h"
@@ -277,10 +278,10 @@ TEST_F(SpdySessionSpdy3Test, ClientPing) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
TestCompletionCallback callback1;
- EXPECT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
scoped_ptr<TestSpdyStreamDelegate> delegate(
new TestSpdyStreamDelegate(callback1.callback()));
@@ -333,10 +334,10 @@ TEST_F(SpdySessionSpdy3Test, ServerPing) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
TestCompletionCallback callback1;
- EXPECT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
scoped_ptr<TestSpdyStreamDelegate> delegate(
new TestSpdyStreamDelegate(callback1.callback()));
spdy_stream1->SetDelegate(delegate.get());
@@ -429,10 +430,10 @@ TEST_F(SpdySessionSpdy3Test, FailedPing) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
TestCompletionCallback callback1;
- EXPECT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
scoped_ptr<TestSpdyStreamDelegate> delegate(
new TestSpdyStreamDelegate(callback1.callback()));
spdy_stream1->SetDelegate(delegate.get());
@@ -466,40 +467,6 @@ TEST_F(SpdySessionSpdy3Test, FailedPing) {
session = NULL;
}
-class StreamReleaserCallback : public TestCompletionCallbackBase {
- public:
- StreamReleaserCallback(SpdySession* session,
- SpdyStream* first_stream)
- : session_(session),
- first_stream_(first_stream),
- ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
- base::Bind(&StreamReleaserCallback::OnComplete,
- base::Unretained(this)))) {
- }
-
- virtual ~StreamReleaserCallback() {}
-
- scoped_refptr<SpdyStream>* stream() { return &stream_; }
-
- const CompletionCallback& callback() const { return callback_; }
-
- private:
- void OnComplete(int result) {
- session_->CloseSessionOnError(ERR_FAILED, false, "On complete.");
- session_ = NULL;
- first_stream_->Cancel();
- first_stream_ = NULL;
- stream_->Cancel();
- stream_ = NULL;
- SetResult(result);
- }
-
- scoped_refptr<SpdySession> session_;
- scoped_refptr<SpdyStream> first_stream_;
- scoped_refptr<SpdyStream> stream_;
- CompletionCallback callback_;
-};
-
// TODO(kristianm): Could also test with more sessions where some are idle,
// and more than one session to a HostPortPair.
TEST_F(SpdySessionSpdy3Test, CloseIdleSessions) {
@@ -510,33 +477,30 @@ TEST_F(SpdySessionSpdy3Test, CloseIdleSessions) {
HostPortPair test_host_port_pair1(kTestHost1, 80);
HostPortProxyPair pair1(test_host_port_pair1, ProxyServer::Direct());
scoped_refptr<SpdySession> session1 = GetSession(pair1);
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1(kTestHost1);
- EXPECT_EQ(OK, session1->CreateStream(url1, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session1, url1, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
// Set up session 2
const std::string kTestHost2("http://www.b.com");
HostPortPair test_host_port_pair2(kTestHost2, 80);
HostPortProxyPair pair2(test_host_port_pair2, ProxyServer::Direct());
scoped_refptr<SpdySession> session2 = GetSession(pair2);
- scoped_refptr<SpdyStream> spdy_stream2;
- TestCompletionCallback callback2;
GURL url2(kTestHost2);
- EXPECT_EQ(OK, session2->CreateStream(url2, MEDIUM, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ scoped_refptr<SpdyStream> spdy_stream2 =
+ CreateStreamSynchronously(session2, url2, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream2.get() != NULL);
// Set up session 3
const std::string kTestHost3("http://www.c.com");
HostPortPair test_host_port_pair3(kTestHost3, 80);
HostPortProxyPair pair3(test_host_port_pair3, ProxyServer::Direct());
scoped_refptr<SpdySession> session3 = GetSession(pair3);
- scoped_refptr<SpdyStream> spdy_stream3;
- TestCompletionCallback callback3;
GURL url3(kTestHost3);
- EXPECT_EQ(OK, session3->CreateStream(url3, MEDIUM, &spdy_stream3,
- BoundNetLog(), callback3.callback()));
+ scoped_refptr<SpdyStream> spdy_stream3 =
+ CreateStreamSynchronously(session3, url3, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream3.get() != NULL);
// All sessions are active and not closed
EXPECT_TRUE(session1->is_active());
@@ -633,17 +597,17 @@ TEST_F(SpdySessionSpdy3Test, OnSettings) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
// Create 2 streams. First will succeed. Second will be pending.
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
- EXPECT_EQ(OK,
- session->CreateStream(test_url_, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
StreamReleaserCallback stream_releaser(session, spdy_stream1);
+ SpdyStreamRequest request;
ASSERT_EQ(ERR_IO_PENDING,
- session->CreateStream(test_url_, MEDIUM, stream_releaser.stream(),
- BoundNetLog(), stream_releaser.callback()));
+ request.StartRequest(session, test_url_, MEDIUM,
+ BoundNetLog(),
+ stream_releaser.MakeCallback(&request)));
// Make sure |stream_releaser| holds the last refs.
session = NULL;
@@ -683,25 +647,26 @@ TEST_F(SpdySessionSpdy3Test, CancelPendingCreateStream) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
+ // Create 2 streams. First will succeed. Second will be pending.
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
+
// Use scoped_ptr to let us invalidate the memory when we want to, to trigger
// a valgrind error if the callback is invoked when it's not supposed to be.
scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
- // Create 2 streams. First will succeed. Second will be pending.
- scoped_refptr<SpdyStream> spdy_stream1;
- ASSERT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback->callback()));
-
- scoped_refptr<SpdyStream> spdy_stream2;
+ SpdyStreamRequest request;
ASSERT_EQ(ERR_IO_PENDING,
- session->CreateStream(test_url_, MEDIUM, &spdy_stream2,
- BoundNetLog(), callback->callback()));
+ request.StartRequest(session, test_url_, MEDIUM,
+ BoundNetLog(),
+ callback->callback()));
// Release the first one, this will allow the second to be created.
spdy_stream1->Cancel();
spdy_stream1 = NULL;
- session->CancelPendingCreateStreams(&spdy_stream2);
+ request.CancelRequest();
callback.reset();
// Should not crash when running the pending callback.
@@ -1044,17 +1009,16 @@ TEST_F(SpdySessionSpdy3Test, OutOfOrderSynStreams) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url, LOWEST, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- scoped_refptr<SpdyStream> spdy_stream2;
- TestCompletionCallback callback2;
- EXPECT_EQ(OK, session->CreateStream(url, HIGHEST, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ scoped_refptr<SpdyStream> spdy_stream2 =
+ CreateStreamSynchronously(session, url, HIGHEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream2.get() != NULL);
EXPECT_EQ(0u, spdy_stream2->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -1117,18 +1081,16 @@ TEST_F(SpdySessionSpdy3Test, CancelStream) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, HIGHEST, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, HIGHEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- scoped_refptr<SpdyStream> spdy_stream2;
- TestCompletionCallback callback2;
GURL url2("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url2, LOWEST, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ scoped_refptr<SpdyStream> spdy_stream2 =
+ CreateStreamSynchronously(session, url2, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream2.get() != NULL);
EXPECT_EQ(0u, spdy_stream2->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -1192,18 +1154,16 @@ TEST_F(SpdySessionSpdy3Test, CloseSessionWithTwoCreatedStreams) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, HIGHEST, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, HIGHEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- scoped_refptr<SpdyStream> spdy_stream2;
- TestCompletionCallback callback2;
GURL url2("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url2, LOWEST, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ scoped_refptr<SpdyStream> spdy_stream2 =
+ CreateStreamSynchronously(session, url2, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream2.get() != NULL);
EXPECT_EQ(0u, spdy_stream2->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -1438,27 +1398,27 @@ TEST_F(SpdySessionSpdy3Test, CloseTwoStalledCreateStream) {
// Read the settings frame.
data.RunFor(1);
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, LOWEST, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
-
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- scoped_refptr<SpdyStream> spdy_stream2;
TestCompletionCallback callback2;
GURL url2("http://www.google.com");
- EXPECT_EQ(ERR_IO_PENDING,
- session->CreateStream(url2, LOWEST, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ SpdyStreamRequest request2;
+ ASSERT_EQ(ERR_IO_PENDING,
+ request2.StartRequest(session, url2, LOWEST,
+ BoundNetLog(),
+ callback2.callback()));
- scoped_refptr<SpdyStream> spdy_stream3;
TestCompletionCallback callback3;
GURL url3("http://www.google.com");
- EXPECT_EQ(ERR_IO_PENDING,
- session->CreateStream(url3, LOWEST, &spdy_stream3,
- BoundNetLog(), callback3.callback()));
+ SpdyStreamRequest request3;
+ ASSERT_EQ(ERR_IO_PENDING,
+ request3.StartRequest(session, url3, LOWEST,
+ BoundNetLog(),
+ callback3.callback()));
EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(2u, session->pending_create_stream_queues(LOWEST));
@@ -1478,33 +1438,33 @@ TEST_F(SpdySessionSpdy3Test, CloseTwoStalledCreateStream) {
EXPECT_TRUE(spdy_stream1->HasUrl());
spdy_stream1->SendRequest(false);
- // Run until 1st stream is closed.
+ // Run until 1st stream is closed and 2nd one is opened.
EXPECT_EQ(0u, spdy_stream1->stream_id());
data.RunFor(3);
EXPECT_EQ(1u, spdy_stream1->stream_id());
- EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
- EXPECT_EQ(1u, session->pending_create_stream_queues(LOWEST));
+ EXPECT_EQ(2u, session->num_active_streams() + session->num_created_streams());
+ EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
- EXPECT_TRUE(spdy_stream2.get() != NULL);
- spdy_stream2->set_spdy_headers(headers2.Pass());
- EXPECT_TRUE(spdy_stream2->HasUrl());
- spdy_stream2->SendRequest(false);
+ scoped_refptr<SpdyStream> stream2 = request2.ReleaseStream();
+ stream2->set_spdy_headers(headers2.Pass());
+ EXPECT_TRUE(stream2->HasUrl());
+ stream2->SendRequest(false);
// Run until 2nd stream is closed.
- EXPECT_EQ(0u, spdy_stream2->stream_id());
+ EXPECT_EQ(0u, stream2->stream_id());
data.RunFor(3);
- EXPECT_EQ(3u, spdy_stream2->stream_id());
+ EXPECT_EQ(3u, stream2->stream_id());
EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
- EXPECT_TRUE(spdy_stream3.get() != NULL);
- spdy_stream3->set_spdy_headers(headers3.Pass());
- EXPECT_TRUE(spdy_stream3->HasUrl());
- spdy_stream3->SendRequest(false);
+ scoped_refptr<SpdyStream> stream3 = request3.ReleaseStream();
+ stream3->set_spdy_headers(headers3.Pass());
+ EXPECT_TRUE(stream3->HasUrl());
+ stream3->SendRequest(false);
- EXPECT_EQ(0u, spdy_stream3->stream_id());
+ EXPECT_EQ(0u, stream3->stream_id());
data.RunFor(4);
- EXPECT_EQ(5u, spdy_stream3->stream_id());
+ EXPECT_EQ(5u, stream3->stream_id());
EXPECT_EQ(0u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
}
@@ -1536,27 +1496,27 @@ TEST_F(SpdySessionSpdy3Test, CancelTwoStalledCreateStream) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- ASSERT_EQ(OK,
- session->CreateStream(url1, LOWEST, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, LOWEST, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
- scoped_refptr<SpdyStream> spdy_stream2;
TestCompletionCallback callback2;
GURL url2("http://www.google.com");
+ SpdyStreamRequest request2;
ASSERT_EQ(ERR_IO_PENDING,
- session->CreateStream(url2, LOWEST, &spdy_stream2,
- BoundNetLog(), callback2.callback()));
+ request2.StartRequest(session, url2, LOWEST,
+ BoundNetLog(),
+ callback2.callback()));
- scoped_refptr<SpdyStream> spdy_stream3;
TestCompletionCallback callback3;
GURL url3("http://www.google.com");
+ SpdyStreamRequest request3;
ASSERT_EQ(ERR_IO_PENDING,
- session->CreateStream(url3, LOWEST, &spdy_stream3,
- BoundNetLog(), callback3.callback()));
+ request3.StartRequest(session, url3, LOWEST,
+ BoundNetLog(),
+ callback3.callback()));
EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(2u, session->pending_create_stream_queues(LOWEST));
@@ -1565,23 +1525,18 @@ TEST_F(SpdySessionSpdy3Test, CancelTwoStalledCreateStream) {
EXPECT_TRUE(spdy_stream1.get() != NULL);
spdy_stream1->Cancel();
spdy_stream1 = NULL;
- session->CancelPendingCreateStreams(&spdy_stream1);
- EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
- EXPECT_EQ(1u, session->pending_create_stream_queues(LOWEST));
+
+ callback2.WaitForResult();
+ EXPECT_EQ(2u, session->num_active_streams() + session->num_created_streams());
+ EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
// Cancel the second stream, this will allow the third stream to be created.
- EXPECT_TRUE(spdy_stream2.get() != NULL);
- spdy_stream2->Cancel();
- spdy_stream2 = NULL;
- session->CancelPendingCreateStreams(&spdy_stream2);
+ request2.ReleaseStream()->Cancel();
EXPECT_EQ(1u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
// Cancel the third stream.
- EXPECT_TRUE(spdy_stream3.get() != NULL);
- spdy_stream3->Cancel();
- spdy_stream3 = NULL;
- session->CancelPendingCreateStreams(&spdy_stream3);
+ request3.ReleaseStream()->Cancel();
EXPECT_EQ(0u, session->num_active_streams() + session->num_created_streams());
EXPECT_EQ(0u, session->pending_create_stream_queues(LOWEST));
}
@@ -1738,10 +1693,10 @@ TEST_F(SpdySessionSpdy3Test, UpdateStreamsSendWindowSize) {
CreateDeterministicNetworkSession();
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
TestCompletionCallback callback1;
- EXPECT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
EXPECT_NE(spdy_stream1->send_window_size(), window_size);
data->RunFor(1); // Process the SETTINGS frame, but not the EOF
@@ -1753,10 +1708,9 @@ TEST_F(SpdySessionSpdy3Test, UpdateStreamsSendWindowSize) {
spdy_stream1->Cancel();
spdy_stream1 = NULL;
- scoped_refptr<SpdyStream> spdy_stream2;
- EXPECT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream2,
- BoundNetLog(), callback1.callback()));
-
+ scoped_refptr<SpdyStream> spdy_stream2 =
+ CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream2.get() != NULL);
EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
spdy_stream2->Cancel();
spdy_stream2 = NULL;
@@ -1815,11 +1769,10 @@ TEST_F(SpdySessionSpdy3Test, ReadDataWithoutYielding) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -1906,11 +1859,10 @@ TEST_F(SpdySessionSpdy3Test, TestYieldingDuringReadData) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -2020,11 +1972,10 @@ TEST_F(SpdySessionSpdy3Test, TestYieldingDuringAsyncReadData) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -2096,11 +2047,10 @@ TEST_F(SpdySessionSpdy3Test, GoAwayWhileInDoLoop) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> spdy_stream1;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
EXPECT_EQ(0u, spdy_stream1->stream_id());
scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
@@ -2405,11 +2355,10 @@ TEST_F(SpdySessionSpdy3Test, SessionFlowControlEndToEnd31) {
scoped_refptr<SpdySession> session = CreateInitializedSession();
- scoped_refptr<SpdyStream> stream;
- TestCompletionCallback callback1;
GURL url1("http://www.google.com");
- EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &stream,
- BoundNetLog(), callback1.callback()));
+ scoped_refptr<SpdyStream> stream =
+ CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(stream.get() != NULL);
EXPECT_EQ(0u, stream->stream_id());
scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(msg_data_size));
diff --git a/net/spdy/spdy_stream_spdy2_unittest.cc b/net/spdy/spdy_stream_spdy2_unittest.cc
index 4473d02..1e85308 100644
--- a/net/spdy/spdy_stream_spdy2_unittest.cc
+++ b/net/spdy/spdy_stream_spdy2_unittest.cc
@@ -10,6 +10,7 @@
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_stream_test_util.h"
+#include "net/spdy/spdy_test_util_common.h"
#include "net/spdy/spdy_test_util_spdy2.h"
#include "net/spdy/spdy_websocket_test_util_spdy2.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -129,11 +130,9 @@ TEST_F(SpdyStreamSpdy2Test, SendDataAfterOpen) {
BoundNetLog()));
session->InitializeWithSocket(connection.release(), false, OK);
- scoped_refptr<SpdyStream> stream;
- ASSERT_EQ(
- OK,
- session->CreateStream(url, LOWEST, &stream, BoundNetLog(),
- CompletionCallback()));
+ scoped_refptr<SpdyStream> stream =
+ CreateStreamSynchronously(session, url, LOWEST, BoundNetLog());
+ ASSERT_TRUE(stream.get() != NULL);
scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
memcpy(buf->data(), "\0hello!\xff", 8);
TestCompletionCallback callback;
@@ -223,11 +222,9 @@ TEST_F(SpdyStreamSpdy2Test, SendHeaderAndDataAfterOpen) {
BoundNetLog()));
session->InitializeWithSocket(connection.release(), false, OK);
- scoped_refptr<SpdyStream> stream;
- ASSERT_EQ(
- OK,
- session->CreateStream(url, HIGHEST, &stream, BoundNetLog(),
- CompletionCallback()));
+ scoped_refptr<SpdyStream> stream =
+ CreateStreamSynchronously(session, url, HIGHEST, BoundNetLog());
+ ASSERT_TRUE(stream.get() != NULL);
scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(6));
memcpy(buf->data(), "hello!", 6);
TestCompletionCallback callback;
@@ -402,11 +399,9 @@ TEST_F(SpdyStreamSpdy2Test, StreamError) {
log.bound()));
session->InitializeWithSocket(connection.release(), false, OK);
- scoped_refptr<SpdyStream> stream;
- ASSERT_EQ(
- OK,
- session->CreateStream(url, LOWEST, &stream, log.bound(),
- CompletionCallback()));
+ scoped_refptr<SpdyStream> stream =
+ CreateStreamSynchronously(session, url, LOWEST, log.bound());
+ ASSERT_TRUE(stream.get() != NULL);
scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
memcpy(buf->data(), "\0hello!\xff", 8);
TestCompletionCallback callback;
diff --git a/net/spdy/spdy_stream_spdy3_unittest.cc b/net/spdy/spdy_stream_spdy3_unittest.cc
index 0bb7da6..e0cbc3a 100644
--- a/net/spdy/spdy_stream_spdy3_unittest.cc
+++ b/net/spdy/spdy_stream_spdy3_unittest.cc
@@ -10,6 +10,7 @@
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_stream_test_util.h"
+#include "net/spdy/spdy_test_util_common.h"
#include "net/spdy/spdy_test_util_spdy3.h"
#include "net/spdy/spdy_websocket_test_util_spdy3.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -130,11 +131,10 @@ TEST_F(SpdyStreamSpdy3Test, SendDataAfterOpen) {
BoundNetLog()));
session->InitializeWithSocket(connection.release(), false, OK);
- scoped_refptr<SpdyStream> stream;
- ASSERT_EQ(
- OK,
- session->CreateStream(url, LOWEST, &stream, BoundNetLog(),
- CompletionCallback()));
+
+ scoped_refptr<SpdyStream> stream =
+ CreateStreamSynchronously(session, url, LOWEST, BoundNetLog());
+ ASSERT_TRUE(stream.get() != NULL);
scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
memcpy(buf->data(), "\0hello!\xff", 8);
TestCompletionCallback callback;
@@ -224,11 +224,9 @@ TEST_F(SpdyStreamSpdy3Test, SendHeaderAndDataAfterOpen) {
BoundNetLog()));
session->InitializeWithSocket(connection.release(), false, OK);
- scoped_refptr<SpdyStream> stream;
- ASSERT_EQ(
- OK,
- session->CreateStream(url, HIGHEST, &stream, BoundNetLog(),
- CompletionCallback()));
+ scoped_refptr<SpdyStream> stream =
+ CreateStreamSynchronously(session, url, HIGHEST, BoundNetLog());
+ ASSERT_TRUE(stream.get() != NULL);
scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(6));
memcpy(buf->data(), "hello!", 6);
TestCompletionCallback callback;
@@ -407,11 +405,9 @@ TEST_F(SpdyStreamSpdy3Test, StreamError) {
log.bound()));
session->InitializeWithSocket(connection.release(), false, OK);
- scoped_refptr<SpdyStream> stream;
- ASSERT_EQ(
- OK,
- session->CreateStream(url, LOWEST, &stream, log.bound(),
- CompletionCallback()));
+ scoped_refptr<SpdyStream> stream =
+ CreateStreamSynchronously(session, url, LOWEST, log.bound());
+ ASSERT_TRUE(stream.get() != NULL);
scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(8));
memcpy(buf->data(), "\0hello!\xff", 8);
TestCompletionCallback callback;
@@ -509,11 +505,9 @@ TEST_F(SpdyStreamSpdy3Test, IncreaseSendWindowSizeOverflow) {
log.bound()));
session->InitializeWithSocket(connection.release(), false, OK);
- scoped_refptr<SpdyStream> stream;
- ASSERT_EQ(
- OK,
- session->CreateStream(url, LOWEST, &stream, log.bound(),
- CompletionCallback()));
+ scoped_refptr<SpdyStream> stream =
+ CreateStreamSynchronously(session, url, LOWEST, log.bound());
+ ASSERT_TRUE(stream.get() != NULL);
TestCompletionCallback callback;
scoped_ptr<TestSpdyStreamDelegate> delegate(
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc
index e46ef9f..0f38c1d 100644
--- a/net/spdy/spdy_test_util_common.cc
+++ b/net/spdy/spdy_test_util_common.cc
@@ -8,6 +8,8 @@
#include "base/compiler_specific.h"
#include "net/spdy/buffered_spdy_framer.h"
+#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_stream.h"
namespace net {
@@ -77,4 +79,40 @@ bool GetSpdyPriority(int version,
return true;
}
-} // namespace net
+scoped_refptr<SpdyStream> CreateStreamSynchronously(
+ const scoped_refptr<SpdySession>& session,
+ const GURL& url,
+ RequestPriority priority,
+ const BoundNetLog& net_log) {
+ SpdyStreamRequest stream_request;
+ int rv = stream_request.StartRequest(session, url, priority, net_log,
+ CompletionCallback());
+ return (rv == OK) ? stream_request.ReleaseStream() : NULL;
+}
+
+StreamReleaserCallback::StreamReleaserCallback(
+ SpdySession* session,
+ SpdyStream* first_stream)
+ : session_(session),
+ first_stream_(first_stream) {}
+
+StreamReleaserCallback::~StreamReleaserCallback() {}
+
+CompletionCallback StreamReleaserCallback::MakeCallback(
+ SpdyStreamRequest* request) {
+ return base::Bind(&StreamReleaserCallback::OnComplete,
+ base::Unretained(this),
+ request);
+}
+
+void StreamReleaserCallback::OnComplete(
+ SpdyStreamRequest* request, int result) {
+ session_->CloseSessionOnError(ERR_FAILED, false, "On complete.");
+ session_ = NULL;
+ first_stream_->Cancel();
+ first_stream_ = NULL;
+ request->ReleaseStream()->Cancel();
+ SetResult(result);
+}
+
+} // namespace net
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h
index 4f45bc6..ff857ca 100644
--- a/net/spdy/spdy_test_util_common.h
+++ b/net/spdy/spdy_test_util_common.h
@@ -5,16 +5,55 @@
#ifndef NET_SPDY_SPDY_TEST_UTIL_COMMON_H_
#define NET_SPDY_SPDY_TEST_UTIL_COMMON_H_
+#include "base/memory/ref_counted.h"
+#include "net/base/completion_callback.h"
+#include "net/base/request_priority.h"
+#include "net/base/test_completion_callback.h"
#include "net/spdy/spdy_protocol.h"
+class GURL;
+
namespace net {
+class BoundNetLog;
+class SpdySession;
+class SpdyStream;
+class SpdyStreamRequest;
+
// Returns the SpdyPriority embedded in the given frame. Returns true
// and fills in |priority| on success.
bool GetSpdyPriority(int version,
const SpdyFrame& frame,
SpdyPriority* priority);
+// Tries to create a stream in |session| synchronously. Returns NULL
+// on failure.
+scoped_refptr<SpdyStream> CreateStreamSynchronously(
+ const scoped_refptr<SpdySession>& session,
+ const GURL& url,
+ RequestPriority priority,
+ const BoundNetLog& net_log);
+
+// Helper class used by some tests to release two streams as soon as
+// one is created.
+class StreamReleaserCallback : public TestCompletionCallbackBase {
+ public:
+ StreamReleaserCallback(SpdySession* session,
+ SpdyStream* first_stream);
+
+ virtual ~StreamReleaserCallback();
+
+ // Returns a callback that releases |request|'s stream as well as
+ // |first_stream|.
+ CompletionCallback MakeCallback(SpdyStreamRequest* request);
+
+ private:
+ void OnComplete(SpdyStreamRequest* request, int result);
+
+ scoped_refptr<SpdySession> session_;
+ scoped_refptr<SpdyStream> first_stream_;
+};
+
} // namespace net
#endif // NET_SPDY_SPDY_TEST_UTIL_COMMON_H_
diff --git a/net/spdy/spdy_websocket_stream.cc b/net/spdy/spdy_websocket_stream.cc
index 6323b71..fe02b54 100644
--- a/net/spdy/spdy_websocket_stream.cc
+++ b/net/spdy/spdy_websocket_stream.cc
@@ -42,16 +42,17 @@ int SpdyWebSocketStream::InitializeStream(const GURL& url,
if (spdy_session_->IsClosed())
return ERR_SOCKET_NOT_CONNECTED;
- int result = spdy_session_->CreateStream(
- url, request_priority, &stream_, net_log,
+ int rv = stream_request_.StartRequest(
+ spdy_session_, url, request_priority, net_log,
base::Bind(&SpdyWebSocketStream::OnSpdyStreamCreated,
base::Unretained(this)));
- if (result == OK) {
+ if (rv == OK) {
+ stream_ = stream_request_.ReleaseStream();
DCHECK(stream_);
stream_->SetDelegate(this);
}
- return result;
+ return rv;
}
int SpdyWebSocketStream::SendRequest(scoped_ptr<SpdyHeaderBlock> headers) {
@@ -77,8 +78,6 @@ int SpdyWebSocketStream::SendData(const char* data, int length) {
}
void SpdyWebSocketStream::Close() {
- if (spdy_session_)
- spdy_session_->CancelPendingCreateStreams(&stream_);
if (stream_)
stream_->Close();
}
@@ -137,6 +136,7 @@ void SpdyWebSocketStream::OnClose(int status) {
void SpdyWebSocketStream::OnSpdyStreamCreated(int result) {
DCHECK_NE(ERR_IO_PENDING, result);
if (result == OK) {
+ stream_ = stream_request_.ReleaseStream();
DCHECK(stream_);
stream_->SetDelegate(this);
}
diff --git a/net/spdy/spdy_websocket_stream.h b/net/spdy/spdy_websocket_stream.h
index 5ab4c48..c003a4b 100644
--- a/net/spdy/spdy_websocket_stream.h
+++ b/net/spdy/spdy_websocket_stream.h
@@ -14,6 +14,7 @@
#include "net/base/request_priority.h"
#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_header_block.h"
+#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_stream.h"
namespace net {
@@ -91,6 +92,7 @@ class NET_EXPORT_PRIVATE SpdyWebSocketStream
void OnSpdyStreamCreated(int status);
+ SpdyStreamRequest stream_request_;
scoped_refptr<SpdyStream> stream_;
scoped_refptr<SpdySession> spdy_session_;
Delegate* delegate_;