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 c97829f54020485fc1c5c6008383ab3a1e2759d9..d05fef613726c48c5064b2043a04688b2e565f00 100644 |
--- a/net/http/http_stream_factory_impl_job.cc |
+++ b/net/http/http_stream_factory_impl_job.cc |
@@ -224,6 +224,7 @@ HttpStreamFactoryImpl::Job::Job(Delegate* delegate, |
!(proxy_info.is_https() && origin_url_.SchemeIs(url::kHttpScheme))), |
spdy_session_key_(GetSpdySessionKey()), |
stream_type_(HttpStreamRequest::BIDIRECTIONAL_STREAM), |
+ init_connection_already_resumed_(false), |
ptr_factory_(this) { |
DCHECK(session); |
// The job can't have alternative service and alternative proxy server set at |
@@ -556,6 +557,7 @@ void HttpStreamFactoryImpl::Job::RunLoop(int result) { |
return; |
if (job_type_ == PRECONNECT) { |
+ session_->spdy_session_pool()->ResumeAllPendingRequests(spdy_session_key_); |
base::ThreadTaskRunnerHandle::Get()->PostTask( |
FROM_HERE, |
base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, |
@@ -686,6 +688,10 @@ int HttpStreamFactoryImpl::Job::DoLoop(int result) { |
case STATE_WAIT_COMPLETE: |
rv = DoWaitComplete(rv); |
break; |
+ case STATE_EVALUATE_THROTTLE: |
+ DCHECK_EQ(OK, rv); |
+ rv = DoEvaluateThrottle(); |
+ break; |
case STATE_INIT_CONNECTION: |
DCHECK_EQ(OK, rv); |
rv = DoInitConnection(); |
@@ -772,10 +778,43 @@ int HttpStreamFactoryImpl::Job::DoWait() { |
int HttpStreamFactoryImpl::Job::DoWaitComplete(int result) { |
net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB_WAITING); |
DCHECK_EQ(OK, result); |
- next_state_ = STATE_INIT_CONNECTION; |
+ next_state_ = STATE_EVALUATE_THROTTLE; |
return OK; |
} |
+int HttpStreamFactoryImpl::Job::DoEvaluateThrottle() { |
+ next_state_ = STATE_INIT_CONNECTION; |
+ // Throttle connect to an HTTP/2 supported server, if there are pending |
+ // requests with the same SpdySessionKey. |
+ if (session_->http_server_properties()->RequiresHTTP11( |
+ spdy_session_key_.host_port_pair())) |
+ return OK; |
+ url::SchemeHostPort scheme_host_port( |
+ using_ssl_ ? url::kHttpsScheme : url::kHttpScheme, |
+ spdy_session_key_.host_port_pair().host(), |
+ spdy_session_key_.host_port_pair().port()); |
+ if (!session_->http_server_properties()->GetSupportsSpdy(scheme_host_port)) |
+ return OK; |
+ base::Closure callback = |
+ base::Bind(&HttpStreamFactoryImpl::Job::ResumeInitConnection, |
+ ptr_factory_.GetWeakPtr()); |
+ if (session_->spdy_session_pool()->StartRequest(spdy_session_key_, |
+ callback)) { |
+ return OK; |
+ } |
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
+ FROM_HERE, callback, base::TimeDelta::FromMilliseconds(kHTTP2ThrottleMs)); |
+ return ERR_IO_PENDING; |
+} |
+ |
+void HttpStreamFactoryImpl::Job::ResumeInitConnection() { |
+ if (init_connection_already_resumed_) |
+ return; |
+ CHECK_EQ(next_state_, STATE_INIT_CONNECTION); |
+ init_connection_already_resumed_ = true; |
+ OnIOComplete(OK); |
+} |
+ |
int HttpStreamFactoryImpl::Job::DoInitConnection() { |
net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB_INIT_CONNECTION); |
int result = DoInitConnectionImpl(); |