| 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 4ce799e8135cfe7d7a8db0808af86314a751577d..26f392a9f86f4fff76578c46f3689d76bd69db3a 100644
|
| --- a/net/http/http_stream_factory_impl_job.cc
|
| +++ b/net/http/http_stream_factory_impl_job.cc
|
| @@ -539,9 +539,14 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) {
|
| return ERR_IO_PENDING;
|
|
|
| default:
|
| + DCHECK(result != ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN ||
|
| + 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(
|
| @@ -626,6 +631,8 @@ int HttpStreamFactoryImpl::Job::DoStart() {
|
| }
|
| origin_url_ =
|
| stream_factory_->ApplyHostMappingRules(request_info_.url, &server_);
|
| + valid_spdy_session_pool_.reset(new ValidSpdySessionPool(
|
| + session_->spdy_session_pool(), origin_url_, IsSpdyAlternate()));
|
|
|
| net_log_.BeginEvent(
|
| NetLog::TYPE_HTTP_STREAM_JOB,
|
| @@ -805,9 +812,11 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
|
| // Check first if we have a spdy session for this group. If so, then go
|
| // straight to using that.
|
| if (CanUseExistingSpdySession()) {
|
| - base::WeakPtr<SpdySession> spdy_session =
|
| - session_->spdy_session_pool()->FindAvailableSession(spdy_session_key,
|
| - net_log_);
|
| + base::WeakPtr<SpdySession> spdy_session;
|
| + int result = valid_spdy_session_pool_->FindAvailableSession(
|
| + spdy_session_key, net_log_, &spdy_session);
|
| + if (result != OK)
|
| + return result;
|
| 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.
|
| @@ -996,6 +1005,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;
|
| }
|
| @@ -1118,21 +1130,24 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
|
| return set_result;
|
| }
|
|
|
| - SpdySessionPool* spdy_pool = session_->spdy_session_pool();
|
| SpdySessionKey spdy_session_key = GetSpdySessionKey();
|
| - base::WeakPtr<SpdySession> spdy_session =
|
| - spdy_pool->FindAvailableSession(spdy_session_key, net_log_);
|
| -
|
| + base::WeakPtr<SpdySession> spdy_session;
|
| + int result = valid_spdy_session_pool_->FindAvailableSession(
|
| + spdy_session_key, net_log_, &spdy_session);
|
| + if (result != OK) {
|
| + return result;
|
| + }
|
| 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_);
|
| + result = valid_spdy_session_pool_->CreateAvailableSessionFromSocket(
|
| + spdy_session_key, connection_.Pass(), net_log_, spdy_certificate_error_,
|
| + using_ssl_, &spdy_session);
|
| + if (result != OK) {
|
| + return result;
|
| + }
|
| +
|
| if (!spdy_session->HasAcceptableTransportSecurity()) {
|
| spdy_session->CloseSessionOnError(
|
| ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY, "");
|
| @@ -1468,6 +1483,48 @@ void HttpStreamFactoryImpl::Job::MaybeMarkAlternativeServiceBroken() {
|
| }
|
| }
|
|
|
| +HttpStreamFactoryImpl::Job::ValidSpdySessionPool::ValidSpdySessionPool(
|
| + SpdySessionPool* spdy_session_pool,
|
| + GURL& origin_url,
|
| + bool is_spdy_alternate)
|
| + : spdy_session_pool_(spdy_session_pool),
|
| + origin_url_(origin_url),
|
| + is_spdy_alternate_(is_spdy_alternate) {
|
| +}
|
| +
|
| +int HttpStreamFactoryImpl::Job::ValidSpdySessionPool::FindAvailableSession(
|
| + const SpdySessionKey& key,
|
| + const BoundNetLog& net_log,
|
| + base::WeakPtr<SpdySession>* spdy_session) {
|
| + *spdy_session = spdy_session_pool_->FindAvailableSession(key, net_log);
|
| + return CheckAlternativeServiceValidityForOrigin(*spdy_session);
|
| +}
|
| +
|
| +int HttpStreamFactoryImpl::Job::ValidSpdySessionPool::
|
| + CreateAvailableSessionFromSocket(const SpdySessionKey& key,
|
| + scoped_ptr<ClientSocketHandle> connection,
|
| + const BoundNetLog& net_log,
|
| + int certificate_error_code,
|
| + bool is_secure,
|
| + base::WeakPtr<SpdySession>* spdy_session) {
|
| + *spdy_session = spdy_session_pool_->CreateAvailableSessionFromSocket(
|
| + key, connection.Pass(), net_log, certificate_error_code, is_secure);
|
| + return CheckAlternativeServiceValidityForOrigin(*spdy_session);
|
| +}
|
| +
|
| +int HttpStreamFactoryImpl::Job::ValidSpdySessionPool::
|
| + CheckAlternativeServiceValidityForOrigin(
|
| + base::WeakPtr<SpdySession> spdy_session) {
|
| + // For a SPDY alternate Job, server_.host() might be different than
|
| + // origin_url_.host(), therefore it needs to be verified that the former
|
| + // provides a certificate that is valid for the latter.
|
| + if (!is_spdy_alternate_ || !spdy_session ||
|
| + spdy_session->VerifyDomainAuthentication(origin_url_.host())) {
|
| + return OK;
|
| + }
|
| + return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN;
|
| +}
|
| +
|
| ClientSocketPoolManager::SocketGroupType
|
| HttpStreamFactoryImpl::Job::GetSocketGroup() const {
|
| std::string scheme = origin_url_.scheme();
|
|
|