| Index: net/http/http_stream_factory_impl_job.cc
|
| diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc
|
| index 6bfef1ec7bdad300bb0477c494e404f564d2a80b..eecf2c8373abd09123a40e5c4f39ceef9b8e18b3 100644
|
| --- a/net/http/http_stream_factory_impl_job.cc
|
| +++ b/net/http/http_stream_factory_impl_job.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "net/http/http_stream_factory_impl_job.h"
|
|
|
| +#include <string>
|
| +
|
| #include "base/bind.h"
|
| #include "base/bind_helpers.h"
|
| #include "base/logging.h"
|
| @@ -207,12 +209,22 @@ void HttpStreamFactoryImpl::Job::Resume(Job* job) {
|
| void HttpStreamFactoryImpl::Job::Orphan(const Request* request) {
|
| DCHECK_EQ(request_, request);
|
| request_ = NULL;
|
| - // We've been orphaned, but there's a job we're blocked on. Don't bother
|
| - // racing, just cancel ourself.
|
| if (blocking_job_) {
|
| + // We've been orphaned, but there's a job we're blocked on. Don't bother
|
| + // racing, just cancel ourself.
|
| DCHECK(blocking_job_->waiting_job_);
|
| blocking_job_->waiting_job_ = NULL;
|
| blocking_job_ = NULL;
|
| + if (stream_factory_->for_websockets_ &&
|
| + connection_ && connection_->socket())
|
| + connection_->socket()->Disconnect();
|
| + stream_factory_->OnOrphanedJobComplete(this);
|
| + } else if (stream_factory_->for_websockets_) {
|
| + // We cancel this job because WebSocketStream can't be created
|
| + // without a WebSocketStreamBase::Factory which is stored in Request class
|
| + // and isn't accessible from this job.
|
| + if (connection_ && connection_->socket())
|
| + connection_->socket()->Disconnect();
|
| stream_factory_->OnOrphanedJobComplete(this);
|
| }
|
| }
|
| @@ -274,6 +286,7 @@ bool HttpStreamFactoryImpl::Job::CanUseExistingSpdySession() const {
|
| // https (the normal case) or if we're connection to a SPDY proxy, or
|
| // if we're running with force_spdy_always_. crbug.com/133176
|
| return request_info_.url.SchemeIs("https") ||
|
| + request_info_.url.SchemeIs("wss") ||
|
| proxy_info_.proxy_server().is_https() ||
|
| force_spdy_always_;
|
| }
|
| @@ -281,6 +294,7 @@ bool HttpStreamFactoryImpl::Job::CanUseExistingSpdySession() const {
|
| void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() {
|
| DCHECK(stream_.get());
|
| DCHECK(!IsPreconnecting());
|
| + DCHECK(!stream_factory_->for_websockets_);
|
| if (IsOrphaned()) {
|
| stream_factory_->OnOrphanedJobComplete(this);
|
| } else {
|
| @@ -294,7 +308,25 @@ void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() {
|
| // |this| may be deleted after this call.
|
| }
|
|
|
| -void HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback() {
|
| +void HttpStreamFactoryImpl::Job::OnWebSocketStreamReadyCallback() {
|
| + DCHECK(websocket_stream_);
|
| + DCHECK(!IsPreconnecting());
|
| + DCHECK(stream_factory_->for_websockets_);
|
| + // An orphaned WebSocket job will be closed immediately and
|
| + // never be ready.
|
| + DCHECK(!IsOrphaned());
|
| + request_->Complete(was_npn_negotiated(),
|
| + protocol_negotiated(),
|
| + using_spdy(),
|
| + net_log_);
|
| + request_->OnWebSocketStreamReady(this,
|
| + server_ssl_config_,
|
| + proxy_info_,
|
| + websocket_stream_.release());
|
| + // |this| may be deleted after this call.
|
| +}
|
| +
|
| +void HttpStreamFactoryImpl::Job::OnNewSpdySessionReadyCallback() {
|
| DCHECK(!stream_.get());
|
| DCHECK(!IsPreconnecting());
|
| DCHECK(using_spdy());
|
| @@ -302,12 +334,12 @@ void HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback() {
|
| scoped_refptr<SpdySession> spdy_session = new_spdy_session_;
|
| new_spdy_session_ = NULL;
|
| if (IsOrphaned()) {
|
| - stream_factory_->OnSpdySessionReady(
|
| + stream_factory_->OnNewSpdySessionReady(
|
| spdy_session, spdy_session_direct_, server_ssl_config_, proxy_info_,
|
| was_npn_negotiated(), protocol_negotiated(), using_spdy(), net_log_);
|
| stream_factory_->OnOrphanedJobComplete(this);
|
| } else {
|
| - request_->OnSpdySessionReady(this, spdy_session, spdy_session_direct_);
|
| + request_->OnNewSpdySessionReady(this, spdy_session, spdy_session_direct_);
|
| }
|
| // |this| may be deleted after this call.
|
| }
|
| @@ -367,15 +399,11 @@ void HttpStreamFactoryImpl::Job::OnHttpsProxyTunnelResponseCallback(
|
|
|
| void HttpStreamFactoryImpl::Job::OnPreconnectsComplete() {
|
| DCHECK(!request_);
|
| - if (new_spdy_session_.get()) {
|
| - stream_factory_->OnSpdySessionReady(new_spdy_session_,
|
| - spdy_session_direct_,
|
| - server_ssl_config_,
|
| - proxy_info_,
|
| - was_npn_negotiated(),
|
| - protocol_negotiated(),
|
| - using_spdy(),
|
| - net_log_);
|
| + if (new_spdy_session_) {
|
| + stream_factory_->OnNewSpdySessionReady(
|
| + new_spdy_session_, spdy_session_direct_, server_ssl_config_,
|
| + proxy_info_, was_npn_negotiated(), protocol_negotiated(), using_spdy(),
|
| + net_log_);
|
| }
|
| stream_factory_->OnPreconnectsComplete(this);
|
| // |this| may be deleted after this call.
|
| @@ -448,7 +476,7 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) {
|
| base::MessageLoop::current()->PostTask(
|
| FROM_HERE,
|
| base::Bind(
|
| - &HttpStreamFactoryImpl::Job::OnNeedsProxyAuthCallback,
|
| + &Job::OnNeedsProxyAuthCallback,
|
| ptr_factory_.GetWeakPtr(),
|
| *tunnel_auth_response,
|
| proxy_socket->GetAuthController()));
|
| @@ -459,7 +487,7 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) {
|
| base::MessageLoop::current()->PostTask(
|
| FROM_HERE,
|
| base::Bind(
|
| - &HttpStreamFactoryImpl::Job::OnNeedsClientAuthCallback,
|
| + &Job::OnNeedsClientAuthCallback,
|
| ptr_factory_.GetWeakPtr(),
|
| connection_->ssl_error_response_info().cert_request_info));
|
| return ERR_IO_PENDING;
|
| @@ -475,7 +503,7 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) {
|
| base::MessageLoop::current()->PostTask(
|
| FROM_HERE,
|
| base::Bind(
|
| - &HttpStreamFactoryImpl::Job::OnHttpsProxyTunnelResponseCallback,
|
| + &Job::OnHttpsProxyTunnelResponseCallback,
|
| ptr_factory_.GetWeakPtr(),
|
| *proxy_socket->GetConnectResponseInfo(),
|
| proxy_socket->CreateConnectResponseStream()));
|
| @@ -484,16 +512,25 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) {
|
|
|
| case OK:
|
| next_state_ = STATE_DONE;
|
| - if (new_spdy_session_.get()) {
|
| + if (new_spdy_session_) {
|
| base::MessageLoop::current()->PostTask(
|
| FROM_HERE,
|
| - base::Bind(&HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback,
|
| - ptr_factory_.GetWeakPtr()));
|
| + base::Bind(
|
| + &Job::OnNewSpdySessionReadyCallback,
|
| + ptr_factory_.GetWeakPtr()));
|
| + } else if (stream_factory_->for_websockets_) {
|
| + DCHECK(websocket_stream_);
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(
|
| + &Job::OnWebSocketStreamReadyCallback,
|
| + ptr_factory_.GetWeakPtr()));
|
| } else {
|
| + DCHECK(stream_.get());
|
| base::MessageLoop::current()->PostTask(
|
| FROM_HERE,
|
| base::Bind(
|
| - &HttpStreamFactoryImpl::Job::OnStreamReadyCallback,
|
| + &Job::OnStreamReadyCallback,
|
| ptr_factory_.GetWeakPtr()));
|
| }
|
| return ERR_IO_PENDING;
|
| @@ -502,7 +539,7 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) {
|
| base::MessageLoop::current()->PostTask(
|
| FROM_HERE,
|
| base::Bind(
|
| - &HttpStreamFactoryImpl::Job::OnStreamFailedCallback,
|
| + &Job::OnStreamFailedCallback,
|
| ptr_factory_.GetWeakPtr(),
|
| result));
|
| return ERR_IO_PENDING;
|
| @@ -689,7 +726,8 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
|
| DCHECK(proxy_info_.proxy_server().is_valid());
|
| next_state_ = STATE_INIT_CONNECTION_COMPLETE;
|
|
|
| - using_ssl_ = request_info_.url.SchemeIs("https") || ShouldForceSpdySSL();
|
| + using_ssl_ = request_info_.url.SchemeIs("https") ||
|
| + request_info_.url.SchemeIs("wss") || ShouldForceSpdySSL();
|
| using_spdy_ = false;
|
|
|
| if (ShouldForceQuic())
|
| @@ -774,6 +812,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
|
| }
|
|
|
| if (IsPreconnecting()) {
|
| + DCHECK(!stream_factory_->for_websockets_);
|
| return PreconnectSocketsForHttpRequest(
|
| origin_url_,
|
| request_info_.extra_headers,
|
| @@ -795,6 +834,14 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
|
| base::Bind(&Job::OnHostResolution, session_->spdy_session_pool(),
|
| GetSpdySessionKey()) :
|
| OnHostResolutionCallback();
|
| + if (stream_factory_->for_websockets_) {
|
| + return InitSocketHandleForWebSocketRequest(
|
| + origin_url_, request_info_.extra_headers, request_info_.load_flags,
|
| + priority_, session_, proxy_info_, ShouldForceSpdySSL(),
|
| + want_spdy_over_npn, server_ssl_config_, proxy_ssl_config_,
|
| + request_info_.privacy_mode, net_log_,
|
| + connection_.get(), resolution_callback, io_callback_);
|
| + }
|
| return InitSocketHandleForHttpRequest(
|
| origin_url_, request_info_.extra_headers, request_info_.load_flags,
|
| priority_, session_, proxy_info_, ShouldForceSpdySSL(),
|
| @@ -864,9 +911,9 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
|
| SSLClientSocket::NextProtoFromString(proto);
|
| protocol_negotiated_ = protocol_negotiated;
|
| net_log_.AddEvent(
|
| - NetLog::TYPE_HTTP_STREAM_REQUEST_PROTO,
|
| - base::Bind(&NetLogHttpStreamProtoCallback,
|
| - status, &proto, &server_protos));
|
| + NetLog::TYPE_HTTP_STREAM_REQUEST_PROTO,
|
| + base::Bind(&NetLogHttpStreamProtoCallback,
|
| + status, &proto, &server_protos));
|
| if (ssl_socket->was_spdy_negotiated())
|
| SwitchToSpdyMode();
|
| }
|
| @@ -982,10 +1029,17 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
|
| request_info_.url.SchemeIs("ftp"));
|
| if (stream_factory_->http_pipelined_host_pool_.
|
| IsExistingPipelineAvailableForKey(*http_pipelining_key_.get())) {
|
| + DCHECK(!stream_factory_->for_websockets_);
|
| stream_.reset(stream_factory_->http_pipelined_host_pool_.
|
| CreateStreamOnExistingPipeline(
|
| *http_pipelining_key_.get()));
|
| CHECK(stream_.get());
|
| + } else if (stream_factory_->for_websockets_) {
|
| + DCHECK(request_);
|
| + DCHECK(request_->websocket_stream_factory());
|
| + websocket_stream_.reset(
|
| + request_->websocket_stream_factory()->CreateBasicStream(
|
| + connection_.release(), using_proxy));
|
| } else if (!using_proxy && IsRequestEligibleForPipelining()) {
|
| // TODO(simonjam): Support proxies.
|
| stream_.reset(
|
| @@ -1057,8 +1111,17 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
|
| // HttpStreamFactoryImpl will be creating all the SpdyHttpStreams, since it
|
| // will know when SpdySessions become available.
|
|
|
| - bool use_relative_url = direct || request_info_.url.SchemeIs("https");
|
| - stream_.reset(new SpdyHttpStream(spdy_session.get(), use_relative_url));
|
| + if (stream_factory_->for_websockets_) {
|
| + DCHECK(request_);
|
| + DCHECK(request_->websocket_stream_factory());
|
| + bool use_relative_url = direct || request_info_.url.SchemeIs("wss");
|
| + websocket_stream_.reset(
|
| + request_->websocket_stream_factory()->CreateSpdyStream(
|
| + spdy_session, use_relative_url));
|
| + } else {
|
| + bool use_relative_url = direct || request_info_.url.SchemeIs("https");
|
| + stream_.reset(new SpdyHttpStream(spdy_session, use_relative_url));
|
| + }
|
| return OK;
|
| }
|
|
|
| @@ -1359,6 +1422,9 @@ bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() {
|
| if (IsPreconnecting() || !request_) {
|
| return false;
|
| }
|
| + if (stream_factory_->for_websockets_) {
|
| + return false;
|
| + }
|
| if (session_->force_http_pipelining()) {
|
| return true;
|
| }
|
|
|