1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be 3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file. 4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/http/http_stream_factory_impl_request.h" 6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/logging.h" 8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/stl_util-inl.h" 9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/http/http_stream_factory_impl_job.h" 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/spdy/spdy_http_stream.h" 11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/spdy/spdy_session.h" 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace net { 14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 15dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenHttpStreamFactoryImpl::Request::Request(const GURL& url, 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpStreamFactoryImpl* factory, 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpStreamRequest::Delegate* delegate, 18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const BoundNetLog& net_log) 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : url_(url), 20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen factory_(factory), 21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delegate_(delegate), 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen net_log_(net_log), 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen completed_(false), 24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen was_npn_negotiated_(false), 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen using_spdy_(false) { 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(factory_); 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(delegate_); 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_REQUEST, NULL); 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 32dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenHttpStreamFactoryImpl::Request::~Request() { 33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (bound_job_.get()) 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(jobs_.empty()); 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen else 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!jobs_.empty()); 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen net_log_.EndEvent(NetLog::TYPE_HTTP_STREAM_REQUEST, NULL); 39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (std::set<Job*>::iterator it = jobs_.begin(); it != jobs_.end(); ++it) 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen factory_->request_map_.erase(*it); 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen STLDeleteElements(&jobs_); 44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen RemoveRequestFromSpdySessionRequestMap(); 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::SetSpdySessionKey( 49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HostPortProxyPair& spdy_session_key) { 50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!spdy_session_key_.get()); 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_key_.reset(new HostPortProxyPair(spdy_session_key)); 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen RequestSet& request_set = 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen factory_->spdy_session_request_map_[spdy_session_key]; 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!ContainsKey(request_set, this)); 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen request_set.insert(this); 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::AttachJob(Job* job) { 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(job); 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen jobs_.insert(job); 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen factory_->request_map_[job] = this; 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::Complete( 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool was_npn_negotiated, 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool using_spdy, 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const NetLog::Source& job_source) { 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!completed_); 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen completed_ = true; 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen was_npn_negotiated_ = was_npn_negotiated; 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen using_spdy_ = using_spdy; 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen net_log_.AddEvent( 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NetLog::TYPE_HTTP_STREAM_REQUEST_BOUND_TO_JOB, 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen make_scoped_refptr(new NetLogSourceParameter( 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "source_dependency", job_source))); 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::OnStreamReady( 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Job* job, 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const SSLConfig& used_ssl_config, 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const ProxyInfo& used_proxy_info, 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpStream* stream) { 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(stream); 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(completed_); 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // |job| should only be NULL if we're being serviced by a late bound 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // SpdySession (one that was not created by a job in our |jobs_| set). 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!job) { 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!bound_job_.get()); 90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!jobs_.empty()); 91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // NOTE(willchan): We do *NOT* call OrphanJobs() here. The reason is because 92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // we *WANT* to cancel the unnecessary Jobs from other requests if another 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Job completes first. 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // TODO(mbelshe): Revisit this when we implement ip connection pooling of 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // SpdySessions. Do we want to orphan the jobs for a different hostname so 96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // they complete? Or do we want to prevent connecting a new SpdySession if 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // we've already got one available for a different hostname where the ip 98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // address matches up? 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else if (!bound_job_.get()) { 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // We may have other jobs in |jobs_|. For example, if we start multiple jobs 101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // for Alternate-Protocol. 102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OrphanJobsExcept(job); 103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(jobs_.empty()); 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delegate_->OnStreamReady(used_ssl_config, used_proxy_info, stream); 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::OnStreamFailed( 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Job* job, 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int status, 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const SSLConfig& used_ssl_config) { 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_NE(OK, status); 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!bound_job_.get()) { 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Hey, we've got other jobs! Maybe one of them will succeed, let's just 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // ignore this failure. 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (jobs_.size() > 1) { 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen jobs_.erase(job); 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen factory_->request_map_.erase(job); 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen delete job; 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bound_job_.reset(job); 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen jobs_.erase(job); 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(jobs_.empty()); 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen factory_->request_map_.erase(job); 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(jobs_.empty()); 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delegate_->OnStreamFailed(status, used_ssl_config); 132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::OnCertificateError( 135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Job* job, 136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int status, 137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const SSLConfig& used_ssl_config, 138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const SSLInfo& ssl_info) { 139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_NE(OK, status); 140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!bound_job_.get()) 141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OrphanJobsExcept(job); 142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen else 143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(jobs_.empty()); 144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delegate_->OnCertificateError(status, used_ssl_config, ssl_info); 145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::OnNeedsProxyAuth( 148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Job* job, 149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpResponseInfo& proxy_response, 150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const SSLConfig& used_ssl_config, 151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const ProxyInfo& used_proxy_info, 152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpAuthController* auth_controller) { 153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!bound_job_.get()) 154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OrphanJobsExcept(job); 155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen else 156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(jobs_.empty()); 157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delegate_->OnNeedsProxyAuth( 158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen proxy_response, used_ssl_config, used_proxy_info, auth_controller); 159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::OnNeedsClientAuth( 162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Job* job, 163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const SSLConfig& used_ssl_config, 164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSLCertRequestInfo* cert_info) { 165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!bound_job_.get()) 166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OrphanJobsExcept(job); 167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen else 168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(jobs_.empty()); 169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delegate_->OnNeedsClientAuth(used_ssl_config, cert_info); 170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 172dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::OnHttpsProxyTunnelResponse( 173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Job *job, 174dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HttpResponseInfo& response_info, 175dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const SSLConfig& used_ssl_config, 176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const ProxyInfo& used_proxy_info, 177dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpStream* stream) { 178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!bound_job_.get()) 179dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OrphanJobsExcept(job); 180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen else 181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(jobs_.empty()); 182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delegate_->OnHttpsProxyTunnelResponse( 183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen response_info, used_ssl_config, used_proxy_info, stream); 184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 185dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenint HttpStreamFactoryImpl::Request::RestartTunnelWithProxyAuth( 187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const string16& username, 188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const string16& password) { 189dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(bound_job_.get()); 190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return bound_job_->RestartTunnelWithProxyAuth(username, password); 191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 193dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenLoadState HttpStreamFactoryImpl::Request::GetLoadState() const { 194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (bound_job_.get()) 195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return bound_job_->GetLoadState(); 196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!jobs_.empty()); 197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Just pick the first one. 199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return (*jobs_.begin())->GetLoadState(); 200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool HttpStreamFactoryImpl::Request::was_npn_negotiated() const { 203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(completed_); 204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return was_npn_negotiated_; 205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool HttpStreamFactoryImpl::Request::using_spdy() const { 208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(completed_); 209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return using_spdy_; 210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid 213dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenHttpStreamFactoryImpl::Request::RemoveRequestFromSpdySessionRequestMap() { 214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (spdy_session_key_.get()) { 215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SpdySessionRequestMap& spdy_session_request_map = 216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen factory_->spdy_session_request_map_; 217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(ContainsKey(spdy_session_request_map, *spdy_session_key_)); 218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen RequestSet& request_set = 219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_request_map[*spdy_session_key_]; 220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(ContainsKey(request_set, this)); 221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen request_set.erase(this); 222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (request_set.empty()) 223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_request_map.erase(*spdy_session_key_); 224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session_key_.reset(); 225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::OnSpdySessionReady( 229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Job* job, 230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_refptr<SpdySession> spdy_session, 231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool direct) { 232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(job); 233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(job->using_spdy()); 234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 235dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // The first case is the usual case. 236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!bound_job_.get()) { 237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OrphanJobsExcept(job); 238dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { // This is the case for HTTPS proxy tunneling. 239dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_EQ(bound_job_.get(), job); 240dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(jobs_.empty()); 241dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 242dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 243dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Cache these values in case the job gets deleted. 244dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const SSLConfig used_ssl_config = job->ssl_config(); 245dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const ProxyInfo used_proxy_info = job->proxy_info(); 246dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const bool was_npn_negotiated = job->was_npn_negotiated(); 247dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const bool using_spdy = job->using_spdy(); 248dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const NetLog::Source source = job->net_log().source(); 249dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Complete(was_npn_negotiated, 251dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen using_spdy, 252dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen source); 253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 254dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Cache this so we can still use it if the request is deleted. 255dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen HttpStreamFactoryImpl* factory = factory_; 256dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool use_relative_url = direct || url().SchemeIs("https"); 258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delegate_->OnStreamReady( 259dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen job->ssl_config(), 260dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen job->proxy_info(), 261dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new SpdyHttpStream(spdy_session, use_relative_url)); 262dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // |this| may be deleted after this point. 263dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen factory->OnSpdySessionReady( 264dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen spdy_session, direct, used_ssl_config, used_proxy_info, 265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen was_npn_negotiated, using_spdy, source); 266dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 267dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 268dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::OrphanJobsExcept(Job* job) { 269dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(job); 270dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!bound_job_.get()); 271dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(ContainsKey(jobs_, job)); 272dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bound_job_.reset(job); 273dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen jobs_.erase(job); 274dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen factory_->request_map_.erase(job); 275dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 276dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OrphanJobs(); 277dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 278dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 279dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid HttpStreamFactoryImpl::Request::OrphanJobs() { 280dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen RemoveRequestFromSpdySessionRequestMap(); 281dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 282dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::set<Job*> tmp; 283dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen tmp.swap(jobs_); 284dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 285dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (std::set<Job*>::iterator it = tmp.begin(); it != tmp.end(); ++it) 286dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen factory_->OrphanJob(*it, this); 287dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 288dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 289dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} // namespace net 290