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 d9e7f24501c343475d710f6f46e36c65404c3c77..45462caa5809990c5ff44a48fbcf17ed9ee9b6db 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" |
@@ -291,6 +293,42 @@ void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { |
// |this| may be deleted after this call. |
} |
+void HttpStreamFactoryImpl::Job::OnSocketReadyCallback() { |
+ DCHECK(request_->for_websocket()); |
+ DCHECK(connection_.get()); |
+ DCHECK(!IsPreconnecting()); |
+ if (IsOrphaned()) { |
+ stream_factory_->OnOrphanedJobComplete(this); |
+ } else { |
+ request_->Complete(was_npn_negotiated(), |
+ protocol_negotiated(), |
+ using_spdy(), |
+ net_log_); |
+ request_->OnSocketReady(this, server_ssl_config_, proxy_info_, |
+ connection_.release()); |
+ } |
+ // |this| may be deleted after this call. |
+} |
+ |
+void HttpStreamFactoryImpl::Job::OnSpdySessionReadyForWSCallback() { |
+ DCHECK(request_->for_websocket()); |
+ DCHECK(spdy_session_to_pass_); |
+ DCHECK(!IsPreconnecting()); |
+ scoped_refptr<SpdySession> session = spdy_session_to_pass_; |
+ spdy_session_to_pass_ = NULL; |
+ if (IsOrphaned()) { |
+ stream_factory_->OnOrphanedJobComplete(this); |
+ } else { |
+ request_->Complete(was_npn_negotiated(), |
+ protocol_negotiated(), |
+ using_spdy(), |
+ net_log_); |
+ request_->OnSpdySessionReadyForWS(this, server_ssl_config_, proxy_info_, |
+ session); |
+ } |
+ // |this| may be deleted after this call. |
+} |
+ |
void HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback() { |
DCHECK(!stream_.get()); |
DCHECK(!IsPreconnecting()); |
@@ -477,7 +515,23 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) { |
case OK: |
next_state_ = STATE_DONE; |
- if (new_spdy_session_) { |
+ if (request_->for_websocket()) { |
+ if (spdy_session_to_pass_) { |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind( |
+ &HttpStreamFactoryImpl::Job::OnSpdySessionReadyForWSCallback, |
+ ptr_factory_.GetWeakPtr())); |
+ } else if (connection_ && connection_->is_initialized()) { |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind( |
+ &HttpStreamFactoryImpl::Job::OnSocketReadyCallback, |
+ ptr_factory_.GetWeakPtr())); |
+ } else { |
+ return ERR_FAILED; |
+ } |
+ } else if (new_spdy_session_) { |
MessageLoop::current()->PostTask( |
FROM_HERE, |
base::Bind( |
@@ -854,9 +908,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(); |
} |
@@ -970,10 +1024,14 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { |
request_info_.url.SchemeIs("ftp")); |
if (stream_factory_->http_pipelined_host_pool_. |
IsExistingPipelineAvailableForKey(*http_pipelining_key_.get())) { |
+ DCHECK(!request_->for_websocket()); |
stream_.reset(stream_factory_->http_pipelined_host_pool_. |
CreateStreamOnExistingPipeline( |
*http_pipelining_key_.get())); |
CHECK(stream_.get()); |
+ } else if (request_->for_websocket()) { |
+ // Do nothing. |
+ // connection_ will be passed to the delegate. |
} else if (!using_proxy && IsRequestEligibleForPipelining()) { |
// TODO(simonjam): Support proxies. |
stream_.reset( |
@@ -1028,6 +1086,10 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { |
if (http_server_properties) |
http_server_properties->SetSupportsSpdy(host_port_pair, true); |
spdy_session_direct_ = direct; |
+ if (request_->for_websocket()) { |
+ DCHECK(!spdy_session_to_pass_); |
+ spdy_session_to_pass_.swap(new_spdy_session_); |
+ } |
return OK; |
} |
} |
@@ -1035,6 +1097,12 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { |
if (spdy_session->IsClosed()) |
return ERR_CONNECTION_CLOSED; |
+ if (request_->for_websocket()) { |
+ DCHECK(!spdy_session_to_pass_); |
+ spdy_session_to_pass_.swap(spdy_session); |
+ return OK; |
+ } |
+ |
// TODO(willchan): Delete this code, because eventually, the |
// HttpStreamFactoryImpl will be creating all the SpdyHttpStreams, since it |
// will know when SpdySessions become available. |
@@ -1337,6 +1405,9 @@ bool HttpStreamFactoryImpl::Job::IsRequestEligibleForPipelining() { |
if (IsPreconnecting() || !request_) { |
return false; |
} |
+ if (request_->for_websocket()) { |
+ return false; |
+ } |
if (session_->force_http_pipelining()) { |
return true; |
} |