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 8d864f54ea81146607f634496c5612fdc0e59972..e4bfacd9945904af026b544a76c958e2274548a3 100644 |
--- a/net/http/http_stream_factory_impl_job.cc |
+++ b/net/http/http_stream_factory_impl_job.cc |
@@ -334,20 +334,23 @@ void HttpStreamFactoryImpl::Job::OnWebSocketHandshakeStreamReadyCallback() { |
} |
void HttpStreamFactoryImpl::Job::OnNewSpdySessionReadyCallback() { |
- DCHECK(!stream_.get()); |
+ DCHECK(stream_.get()); |
DCHECK(!IsPreconnecting()); |
DCHECK(using_spdy()); |
- if (!new_spdy_session_) |
- return; |
+ // Note: an event loop iteration has passed, so |new_spdy_session_| may be |
+ // NULL at this point if the SpdySession closed immediately after creation. |
base::WeakPtr<SpdySession> spdy_session = new_spdy_session_; |
new_spdy_session_.reset(); |
if (IsOrphaned()) { |
- stream_factory_->OnNewSpdySessionReady( |
- spdy_session, spdy_session_direct_, server_ssl_config_, proxy_info_, |
- was_npn_negotiated(), protocol_negotiated(), using_spdy(), net_log_); |
+ if (spdy_session) { |
+ 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_->OnNewSpdySessionReady(this, spdy_session, spdy_session_direct_); |
+ request_->OnNewSpdySessionReady( |
+ this, stream_.Pass(), spdy_session, spdy_session_direct_); |
} |
// |this| may be deleted after this call. |
} |
@@ -1122,21 +1125,27 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { |
SpdySessionPool* spdy_pool = session_->spdy_session_pool(); |
spdy_session = spdy_pool->FindAvailableSession(spdy_session_key, net_log_); |
if (!spdy_session) { |
- int error = |
+ new_spdy_session_ = |
spdy_pool->CreateAvailableSessionFromSocket(spdy_session_key, |
connection_.Pass(), |
net_log_, |
spdy_certificate_error_, |
- &new_spdy_session_, |
using_ssl_); |
- if (error != OK) |
- return error; |
const HostPortPair& host_port_pair = spdy_session_key.host_port_pair(); |
base::WeakPtr<HttpServerProperties> http_server_properties = |
session_->http_server_properties(); |
if (http_server_properties) |
http_server_properties->SetSupportsSpdy(host_port_pair, true); |
spdy_session_direct_ = direct; |
+ |
+ // Create a SpdyHttpStream attached to the session; |
+ // OnNewSpdySessionReadyCallback is not called until an event loop |
+ // iteration later, so if the SpdySession is closed between then, allow |
+ // reuse state from the underlying socket, sampled by SpdyHttpStream, |
+ // bubble up to the request. |
+ bool use_relative_url = direct || request_info_.url.SchemeIs("https"); |
+ stream_.reset(new SpdyHttpStream(new_spdy_session_, use_relative_url)); |
+ |
return OK; |
} |
} |