Chromium Code Reviews| 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 78f4eedb1a19300346cca7428e756a73c41d2279..bdbc0ecf4af09090de6b1a00775f4ec581797637 100644 |
| --- a/net/http/http_stream_factory_impl_job.cc |
| +++ b/net/http/http_stream_factory_impl_job.cc |
| @@ -271,12 +271,11 @@ SpdySessionKey HttpStreamFactoryImpl::Job::GetSpdySessionKey() const { |
| // In the case that we're using an HTTPS proxy for an HTTP url, |
| // we look for a SPDY session *to* the proxy, instead of to the |
| // origin server. |
| - PrivacyMode privacy_mode = request_info_.privacy_mode; |
| if (IsHttpsProxyAndHttpUrl()) { |
| return SpdySessionKey(proxy_info_.proxy_server().host_port_pair(), |
| - ProxyServer::Direct(), |
| - privacy_mode); |
| + ProxyServer::Direct(), PRIVACY_MODE_DISABLED); |
| } |
| + PrivacyMode privacy_mode = request_info_.privacy_mode; |
| return SpdySessionKey(server_, proxy_info_.proxy_server(), privacy_mode); |
|
Ryan Hamilton
2015/04/13 18:29:56
I recommend doing this cleanup in a different CL s
Bence
2015/04/15 21:07:46
Done: https://crrev.com/1063873003.
|
| } |
| @@ -536,9 +535,14 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) { |
| return ERR_IO_PENDING; |
| default: |
| + DCHECK((result != ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN) || |
|
Ryan Hamilton
2015/04/13 18:29:56
No need for the 2nd set of ()s. Feel free to put I
Bence
2015/04/15 21:07:46
Done.
|
| + IsSpdyAlternate()); |
| if (job_status_ != STATUS_BROKEN) { |
| DCHECK_EQ(STATUS_RUNNING, job_status_); |
| job_status_ = STATUS_FAILED; |
| + // TODO(bnc): If (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN), |
| + // then instead of marking alternative service broken, mark (origin, |
| + // alternative service) couple as invalid. |
| MaybeMarkAlternativeServiceBroken(); |
| } |
| base::MessageLoop::current()->PostTask( |
| @@ -623,6 +627,8 @@ int HttpStreamFactoryImpl::Job::DoStart() { |
| } |
| origin_url_ = |
| stream_factory_->ApplyHostMappingRules(request_info_.url, &server_); |
| + valid_spdy_session_pool_.reset( |
| + new ValidSpdySessionPool(session_, origin_url_, IsSpdyAlternate())); |
| net_log_.BeginEvent( |
| NetLog::TYPE_HTTP_STREAM_JOB, |
| @@ -797,29 +803,36 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| return rv; |
| } |
| + SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| + |
| // Check first if we have a spdy session for this group. If so, then go |
| // straight to using that. |
| - SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| - base::WeakPtr<SpdySession> spdy_session = |
| - session_->spdy_session_pool()->FindAvailableSession( |
| - spdy_session_key, net_log_); |
| - if (spdy_session && CanUseExistingSpdySession()) { |
| - // If we're preconnecting, but we already have a SpdySession, we don't |
| - // actually need to preconnect any sockets, so we're done. |
| - if (IsPreconnecting()) |
| + if (CanUseExistingSpdySession()) { |
| + bool is_valid; |
| + base::WeakPtr<SpdySession> spdy_session = |
| + valid_spdy_session_pool_->FindAvailableSession(spdy_session_key, |
| + net_log_, &is_valid); |
| + if (!is_valid) { |
| + return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; |
| + } |
| + if (spdy_session) { |
| + // If we're preconnecting, but we already have a SpdySession, we don't |
| + // actually need to preconnect any sockets, so we're done. |
| + if (IsPreconnecting()) |
| + return OK; |
| + using_spdy_ = true; |
| + next_state_ = STATE_CREATE_STREAM; |
| + existing_spdy_session_ = spdy_session; |
| return OK; |
| - using_spdy_ = true; |
| - next_state_ = STATE_CREATE_STREAM; |
| - existing_spdy_session_ = spdy_session; |
| - return OK; |
| - } else if (request_ && !request_->HasSpdySessionKey() && using_ssl_) { |
| + } |
| + } |
| + if (request_ && !request_->HasSpdySessionKey() && using_ssl_) { |
| // Update the spdy session key for the request that launched this job. |
| request_->SetSpdySessionKey(spdy_session_key); |
| } |
| // OK, there's no available SPDY session. Let |waiting_job_| resume if it's |
| // paused. |
| - |
| if (waiting_job_) { |
| waiting_job_->Resume(this); |
| waiting_job_ = NULL; |
| @@ -864,10 +877,11 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| // If we can't use a SPDY session, don't bother checking for one after |
| // the hostname is resolved. |
| - OnHostResolutionCallback resolution_callback = CanUseExistingSpdySession() ? |
| - base::Bind(&Job::OnHostResolution, session_->spdy_session_pool(), |
| - GetSpdySessionKey()) : |
| - OnHostResolutionCallback(); |
| + OnHostResolutionCallback resolution_callback = |
| + CanUseExistingSpdySession() |
| + ? base::Bind(&Job::OnHostResolution, session_->spdy_session_pool(), |
| + spdy_session_key) |
| + : OnHostResolutionCallback(); |
| if (stream_factory_->for_websockets_) { |
| // TODO(ricea): Re-enable NPN when WebSockets over SPDY is supported. |
| SSLConfig websocket_server_ssl_config = server_ssl_config_; |
| @@ -989,6 +1003,9 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { |
| if (!ssl_started && result < 0 && IsAlternate()) { |
| job_status_ = STATUS_BROKEN; |
| + // TODO(bnc): if (result == ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN), then |
| + // instead of marking alternative service broken, mark (origin, alternative |
| + // service) couple as invalid. |
| MaybeMarkAlternativeServiceBroken(); |
| return result; |
| } |
| @@ -1099,12 +1116,7 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { |
| CHECK(!stream_.get()); |
| - bool direct = true; |
| - const ProxyServer& proxy_server = proxy_info_.proxy_server(); |
| - PrivacyMode privacy_mode = request_info_.privacy_mode; |
| - if (IsHttpsProxyAndHttpUrl()) |
| - direct = false; |
| - |
| + bool direct = !IsHttpsProxyAndHttpUrl(); |
| if (existing_spdy_session_.get()) { |
| // We picked up an existing session, so we don't need our socket. |
| if (connection_->socket()) |
| @@ -1116,30 +1128,25 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { |
| return set_result; |
| } |
| - SpdySessionKey spdy_session_key(server_, proxy_server, privacy_mode); |
| - if (IsHttpsProxyAndHttpUrl()) { |
| - // If we don't have a direct SPDY session, and we're using an HTTPS |
| - // proxy, then we might have a SPDY session to the proxy. |
| - // We never use privacy mode for connection to proxy server. |
| - spdy_session_key = SpdySessionKey(proxy_server.host_port_pair(), |
| - ProxyServer::Direct(), |
| - PRIVACY_MODE_DISABLED); |
| - } |
| - |
| - SpdySessionPool* spdy_pool = session_->spdy_session_pool(); |
| + SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| + bool is_valid; |
| base::WeakPtr<SpdySession> spdy_session = |
| - spdy_pool->FindAvailableSession(spdy_session_key, net_log_); |
| - |
| + valid_spdy_session_pool_->FindAvailableSession(spdy_session_key, net_log_, |
| + &is_valid); |
| + if (!is_valid) { |
|
Ryan Hamilton
2015/04/13 18:29:56
Hm. I'm not in love with this API. Instead, I woul
Bence
2015/04/15 21:07:46
Done.
|
| + return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; |
| + } |
| if (spdy_session) { |
| return SetSpdyHttpStream(spdy_session, direct); |
| } |
| - spdy_session = |
| - spdy_pool->CreateAvailableSessionFromSocket(spdy_session_key, |
| - connection_.Pass(), |
| - net_log_, |
| - spdy_certificate_error_, |
| - using_ssl_); |
| + spdy_session = valid_spdy_session_pool_->CreateAvailableSessionFromSocket( |
| + spdy_session_key, connection_.Pass(), net_log_, spdy_certificate_error_, |
| + using_ssl_, &is_valid); |
| + if (!is_valid) { |
| + return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; |
| + } |
| + |
| if (!spdy_session->HasAcceptableTransportSecurity()) { |
| spdy_session->CloseSessionOnError( |
| ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, ""); |
| @@ -1475,6 +1482,48 @@ void HttpStreamFactoryImpl::Job::MaybeMarkAlternativeServiceBroken() { |
| } |
| } |
| +HttpStreamFactoryImpl::Job::ValidSpdySessionPool::ValidSpdySessionPool( |
| + HttpNetworkSession* session, |
|
Ryan Hamilton
2015/04/13 18:29:56
Looks like you can just take the Pool instead of s
Bence
2015/04/15 21:07:46
Done.
|
| + GURL& origin_url, |
| + bool is_spdy_alternate) |
| + : session_(session), |
| + origin_url_(origin_url), |
| + is_spdy_alternate_(is_spdy_alternate) { |
| +} |
| + |
| +base::WeakPtr<SpdySession> |
| +HttpStreamFactoryImpl::Job::ValidSpdySessionPool::FindAvailableSession( |
| + const SpdySessionKey& key, |
| + const BoundNetLog& net_log, |
| + bool* is_valid) { |
| + base::WeakPtr<SpdySession> spdy_session = |
| + session_->spdy_session_pool()->FindAvailableSession(key, net_log); |
| + *is_valid = IsAlternativeCertificateValidForOrigin(spdy_session); |
| + return spdy_session; |
| +} |
| + |
| +base::WeakPtr<SpdySession> HttpStreamFactoryImpl::Job::ValidSpdySessionPool:: |
| + CreateAvailableSessionFromSocket(const SpdySessionKey& key, |
| + scoped_ptr<ClientSocketHandle> connection, |
| + const BoundNetLog& net_log, |
| + int certificate_error_code, |
| + bool is_secure, |
| + bool* is_valid) { |
| + base::WeakPtr<SpdySession> spdy_session = |
| + session_->spdy_session_pool()->CreateAvailableSessionFromSocket( |
| + key, connection.Pass(), net_log, certificate_error_code, is_secure); |
| + *is_valid = IsAlternativeCertificateValidForOrigin(spdy_session); |
| + return spdy_session; |
| +} |
| + |
| +bool HttpStreamFactoryImpl::Job::ValidSpdySessionPool:: |
| + IsAlternativeCertificateValidForOrigin( |
| + base::WeakPtr<SpdySession> spdy_session) { |
| + return !is_spdy_alternate_ || !spdy_session || |
|
Ryan Hamilton
2015/04/13 18:29:56
It seems like is_spdy_alternate_ is not adding any
Bence
2015/04/15 21:07:46
Per your other comment, I removed hostname checkin
Ryan Hamilton
2015/04/15 21:24:34
Can you add a comment about why you don't need to
Bence
2015/04/23 17:17:07
Done.
|
| + (origin_url_.host() == spdy_session->host_port_pair().host()) || |
| + spdy_session->VerifyDomainAuthentication(origin_url_.host()); |
| +} |
| + |
| ClientSocketPoolManager::SocketGroupType |
| HttpStreamFactoryImpl::Job::GetSocketGroup() const { |
| std::string scheme = origin_url_.scheme(); |