Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/http_stream_factory_impl_job_controller.h" | 5 #include "net/http/http_stream_factory_impl_job_controller.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 #include "net/log/net_log_capture_mode.h" | 22 #include "net/log/net_log_capture_mode.h" |
| 23 #include "net/log/net_log_event_type.h" | 23 #include "net/log/net_log_event_type.h" |
| 24 #include "net/log/net_log_source.h" | 24 #include "net/log/net_log_source.h" |
| 25 #include "net/log/net_log_with_source.h" | 25 #include "net/log/net_log_with_source.h" |
| 26 #include "net/proxy/proxy_server.h" | 26 #include "net/proxy/proxy_server.h" |
| 27 #include "net/spdy/chromium/spdy_session.h" | 27 #include "net/spdy/chromium/spdy_session.h" |
| 28 #include "url/url_constants.h" | 28 #include "url/url_constants.h" |
| 29 | 29 |
| 30 namespace net { | 30 namespace net { |
| 31 | 31 |
| 32 namespace { | |
| 33 // Returns parameters associated with the proxy resolution. | |
| 34 std::unique_ptr<base::Value> NetLogHttpStreamJobProxyServerResolved( | |
| 35 const ProxyServer& proxy_server, | |
| 36 NetLogCaptureMode /* capture_mode */) { | |
| 37 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | |
| 38 | |
| 39 dict->SetString("proxy_server", proxy_server.is_valid() | |
| 40 ? proxy_server.ToPacString() | |
| 41 : std::string()); | |
| 42 return std::move(dict); | |
| 43 } | |
| 44 | |
| 45 } // namespace | |
| 46 | |
| 32 // The maximum time to wait for the alternate job to complete before resuming | 47 // The maximum time to wait for the alternate job to complete before resuming |
| 33 // the main job. | 48 // the main job. |
| 34 const int kMaxDelayTimeForMainJobSecs = 3; | 49 const int kMaxDelayTimeForMainJobSecs = 3; |
| 35 | 50 |
| 36 std::unique_ptr<base::Value> NetLogJobControllerCallback( | 51 std::unique_ptr<base::Value> NetLogJobControllerCallback( |
| 37 const GURL* url, | 52 const GURL* url, |
| 38 bool is_preconnect, | 53 bool is_preconnect, |
| 39 NetLogCaptureMode /* capture_mode */) { | 54 NetLogCaptureMode /* capture_mode */) { |
| 40 auto dict = base::MakeUnique<base::DictionaryValue>(); | 55 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 41 dict->SetString("url", url->possibly_invalid_spec()); | 56 dict->SetString("url", url->possibly_invalid_spec()); |
| 42 dict->SetBoolean("is_preconnect", is_preconnect); | 57 dict->SetBoolean("is_preconnect", is_preconnect); |
| 43 return std::move(dict); | 58 return std::move(dict); |
| 44 } | 59 } |
| 45 | 60 |
| 46 HttpStreamFactoryImpl::JobController::JobController( | 61 HttpStreamFactoryImpl::JobController::JobController( |
| 47 HttpStreamFactoryImpl* factory, | 62 HttpStreamFactoryImpl* factory, |
| 48 HttpStreamRequest::Delegate* delegate, | 63 HttpStreamRequest::Delegate* delegate, |
| 49 HttpNetworkSession* session, | 64 HttpNetworkSession* session, |
| 50 JobFactory* job_factory, | 65 JobFactory* job_factory, |
| 51 const HttpRequestInfo& request_info, | 66 const HttpRequestInfo& request_info, |
| 52 bool is_preconnect, | 67 bool is_preconnect, |
| 53 bool enable_ip_based_pooling, | 68 bool enable_ip_based_pooling, |
| 54 bool enable_alternative_services) | 69 bool enable_alternative_services, |
| 70 const SSLConfig& server_ssl_config, | |
| 71 const SSLConfig& proxy_ssl_config) | |
| 55 : factory_(factory), | 72 : factory_(factory), |
| 56 session_(session), | 73 session_(session), |
| 57 job_factory_(job_factory), | 74 job_factory_(job_factory), |
| 58 request_(nullptr), | 75 request_(nullptr), |
| 59 delegate_(delegate), | 76 delegate_(delegate), |
| 60 is_preconnect_(is_preconnect), | 77 is_preconnect_(is_preconnect), |
| 61 enable_ip_based_pooling_(enable_ip_based_pooling), | 78 enable_ip_based_pooling_(enable_ip_based_pooling), |
| 62 enable_alternative_services_(enable_alternative_services), | 79 enable_alternative_services_(enable_alternative_services), |
| 63 alternative_job_net_error_(OK), | 80 alternative_job_net_error_(OK), |
| 64 job_bound_(false), | 81 job_bound_(false), |
| 65 main_job_is_blocked_(false), | 82 main_job_is_blocked_(false), |
| 66 main_job_is_resumed_(false), | 83 main_job_is_resumed_(false), |
| 67 bound_job_(nullptr), | 84 bound_job_(nullptr), |
| 68 can_start_alternative_proxy_job_(false), | 85 can_start_alternative_proxy_job_(true), |
| 69 privacy_mode_(PRIVACY_MODE_DISABLED), | 86 privacy_mode_(PRIVACY_MODE_DISABLED), |
| 87 next_state_(STATE_RESOLVE_PROXY), | |
| 88 pac_request_(nullptr), | |
| 70 net_log_( | 89 net_log_( |
| 71 NetLogWithSource::Make(session->net_log(), | 90 NetLogWithSource::Make(session->net_log(), |
| 72 NetLogSourceType::HTTP_STREAM_JOB_CONTROLLER)), | 91 NetLogSourceType::HTTP_STREAM_JOB_CONTROLLER)), |
| 92 io_callback_( | |
| 93 base::Bind(&JobController::OnIOComplete, base::Unretained(this))), | |
| 94 request_info_(request_info), | |
| 95 server_ssl_config_(server_ssl_config), | |
| 96 proxy_ssl_config_(proxy_ssl_config), | |
| 97 num_streams_(0), | |
| 98 priority_(IDLE), | |
| 73 ptr_factory_(this) { | 99 ptr_factory_(this) { |
| 74 DCHECK(factory); | 100 DCHECK(factory); |
| 75 net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER, | 101 net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER, |
| 76 base::Bind(&NetLogJobControllerCallback, | 102 base::Bind(&NetLogJobControllerCallback, |
| 77 &request_info.url, is_preconnect)); | 103 &request_info.url, is_preconnect)); |
| 78 } | 104 } |
| 79 | 105 |
| 80 HttpStreamFactoryImpl::JobController::~JobController() { | 106 HttpStreamFactoryImpl::JobController::~JobController() { |
| 81 main_job_.reset(); | 107 main_job_.reset(); |
| 82 alternative_job_.reset(); | 108 alternative_job_.reset(); |
| 83 bound_job_ = nullptr; | 109 bound_job_ = nullptr; |
| 110 if (pac_request_) | |
| 111 session_->proxy_service()->CancelPacRequest(pac_request_); | |
| 84 net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER); | 112 net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER); |
| 85 } | 113 } |
| 86 | 114 |
| 87 bool HttpStreamFactoryImpl::JobController::for_websockets() { | 115 bool HttpStreamFactoryImpl::JobController::for_websockets() { |
| 88 return factory_->for_websockets_; | 116 return factory_->for_websockets_; |
| 89 } | 117 } |
| 90 | 118 |
| 91 HttpStreamFactoryImpl::Request* HttpStreamFactoryImpl::JobController::Start( | 119 HttpStreamFactoryImpl::Request* HttpStreamFactoryImpl::JobController::Start( |
| 92 const HttpRequestInfo& request_info, | |
| 93 HttpStreamRequest::Delegate* delegate, | 120 HttpStreamRequest::Delegate* delegate, |
| 94 WebSocketHandshakeStreamBase::CreateHelper* | 121 WebSocketHandshakeStreamBase::CreateHelper* |
| 95 websocket_handshake_stream_create_helper, | 122 websocket_handshake_stream_create_helper, |
| 96 const NetLogWithSource& source_net_log, | 123 const NetLogWithSource& source_net_log, |
| 97 HttpStreamRequest::StreamType stream_type, | 124 HttpStreamRequest::StreamType stream_type, |
| 98 RequestPriority priority, | 125 RequestPriority priority) { |
| 99 const SSLConfig& server_ssl_config, | |
| 100 const SSLConfig& proxy_ssl_config) { | |
| 101 DCHECK(factory_); | 126 DCHECK(factory_); |
| 102 DCHECK(!request_); | 127 DCHECK(!request_); |
| 103 | 128 |
| 104 privacy_mode_ = request_info.privacy_mode; | 129 privacy_mode_ = request_info_.privacy_mode; |
| 130 stream_type_ = stream_type; | |
| 131 priority_ = priority; | |
| 105 | 132 |
| 106 request_ = new Request(request_info.url, this, delegate, | 133 request_ = new Request(request_info_.url, this, delegate, |
| 107 websocket_handshake_stream_create_helper, | 134 websocket_handshake_stream_create_helper, |
| 108 source_net_log, stream_type); | 135 source_net_log, stream_type); |
| 109 // Associates |net_log_| with |source_net_log|. | 136 // Associates |net_log_| with |source_net_log|. |
| 110 source_net_log.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, | 137 source_net_log.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, |
| 111 net_log_.source().ToEventParametersCallback()); | 138 net_log_.source().ToEventParametersCallback()); |
| 112 net_log_.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, | 139 net_log_.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, |
| 113 source_net_log.source().ToEventParametersCallback()); | 140 source_net_log.source().ToEventParametersCallback()); |
| 114 | 141 |
| 115 CreateJobs(request_info, priority, server_ssl_config, proxy_ssl_config, | 142 RunLoop(OK); |
| 116 delegate, stream_type); | |
| 117 | |
| 118 return request_; | 143 return request_; |
| 119 } | 144 } |
| 120 | 145 |
| 121 void HttpStreamFactoryImpl::JobController::Preconnect( | 146 void HttpStreamFactoryImpl::JobController::Preconnect(int num_streams) { |
| 122 int num_streams, | |
| 123 const HttpRequestInfo& request_info, | |
| 124 const SSLConfig& server_ssl_config, | |
| 125 const SSLConfig& proxy_ssl_config) { | |
| 126 DCHECK(!main_job_); | 147 DCHECK(!main_job_); |
| 127 DCHECK(!alternative_job_); | 148 DCHECK(!alternative_job_); |
| 128 DCHECK(is_preconnect_); | 149 DCHECK(is_preconnect_); |
| 129 | 150 |
| 130 privacy_mode_ = request_info.privacy_mode; | 151 privacy_mode_ = request_info_.privacy_mode; |
| 152 num_streams_ = num_streams; | |
| 131 | 153 |
| 132 HostPortPair destination(HostPortPair::FromURL(request_info.url)); | 154 HostPortPair destination(HostPortPair::FromURL(request_info_.url)); |
| 133 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); | 155 GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination); |
| 134 | 156 |
| 135 const AlternativeService alternative_service = GetAlternativeServiceFor( | 157 const AlternativeService alternative_service = GetAlternativeServiceFor( |
| 136 request_info, nullptr, HttpStreamRequest::HTTP_STREAM); | 158 request_info_, nullptr, HttpStreamRequest::HTTP_STREAM); |
| 137 | 159 |
| 138 if (alternative_service.protocol != kProtoUnknown) { | 160 if (alternative_service.protocol != kProtoUnknown) { |
| 139 destination = alternative_service.host_port_pair(); | 161 destination = alternative_service.host_port_pair(); |
| 140 ignore_result(ApplyHostMappingRules(request_info.url, &destination)); | 162 ignore_result(ApplyHostMappingRules(request_info_.url, &destination)); |
| 141 } | 163 } |
| 142 | 164 RunLoop(OK); |
| 143 // Due to how the socket pools handle priorities and idle sockets, only IDLE | |
| 144 // priority currently makes sense for preconnects. The priority for | |
| 145 // preconnects is currently ignored (see RequestSocketsForPool()), but could | |
| 146 // be used at some point for proxy resolution or something. | |
| 147 main_job_.reset(job_factory_->CreateJob( | |
| 148 this, PRECONNECT, session_, request_info, IDLE, server_ssl_config, | |
| 149 proxy_ssl_config, destination, origin_url, alternative_service, | |
| 150 enable_ip_based_pooling_, session_->net_log())); | |
| 151 main_job_->Preconnect(num_streams); | |
| 152 } | 165 } |
| 153 | 166 |
| 154 LoadState HttpStreamFactoryImpl::JobController::GetLoadState() const { | 167 LoadState HttpStreamFactoryImpl::JobController::GetLoadState() const { |
| 168 // FIXME | |
| 169 if (next_state_ == STATE_RESOLVE_PROXY_COMPLETE) | |
| 170 return session_->proxy_service()->GetLoadState(pac_request_); | |
| 155 DCHECK(request_); | 171 DCHECK(request_); |
| 156 DCHECK(main_job_ || alternative_job_); | 172 DCHECK(main_job_ || alternative_job_); |
| 157 if (bound_job_) | 173 if (bound_job_) |
| 158 return bound_job_->GetLoadState(); | 174 return bound_job_->GetLoadState(); |
| 159 | 175 |
| 160 // Just pick the first one. | 176 // Just pick the first one. |
| 161 return main_job_ ? main_job_->GetLoadState() | 177 return main_job_ ? main_job_->GetLoadState() |
| 162 : alternative_job_->GetLoadState(); | 178 : alternative_job_->GetLoadState(); |
| 163 } | 179 } |
| 164 | 180 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 180 bound_job_ = nullptr; | 196 bound_job_ = nullptr; |
| 181 } | 197 } |
| 182 MaybeNotifyFactoryOfCompletion(); | 198 MaybeNotifyFactoryOfCompletion(); |
| 183 } | 199 } |
| 184 | 200 |
| 185 int HttpStreamFactoryImpl::JobController::RestartTunnelWithProxyAuth() { | 201 int HttpStreamFactoryImpl::JobController::RestartTunnelWithProxyAuth() { |
| 186 DCHECK(bound_job_); | 202 DCHECK(bound_job_); |
| 187 return bound_job_->RestartTunnelWithProxyAuth(); | 203 return bound_job_->RestartTunnelWithProxyAuth(); |
| 188 } | 204 } |
| 189 | 205 |
| 206 int HttpStreamFactoryImpl::JobController::ReconsiderProxyAfterError(Job* job, | |
| 207 int error) { | |
| 208 DCHECK(!pac_request_); | |
| 209 DCHECK(session_); | |
| 210 | |
| 211 if (!job->reconsider_proxy()) | |
| 212 return error; | |
| 213 | |
| 214 // Do not bypass non-QUIC proxy on ERR_MSG_TOO_BIG. | |
| 215 if (!proxy_info_.is_quic() && error == ERR_MSG_TOO_BIG) | |
| 216 return error; | |
| 217 | |
| 218 if (request_info_.load_flags & LOAD_BYPASS_PROXY) | |
| 219 return error; | |
| 220 | |
| 221 if (proxy_info_.is_https() && proxy_ssl_config_.send_client_cert) { | |
| 222 session_->ssl_client_auth_cache()->Remove( | |
| 223 proxy_info_.proxy_server().host_port_pair()); | |
| 224 } | |
| 225 | |
| 226 int rv = session_->proxy_service()->ReconsiderProxyAfterError( | |
| 227 request_info_.url, request_info_.method, error, &proxy_info_, | |
| 228 io_callback_, &pac_request_, session_->params().proxy_delegate, net_log_); | |
| 229 if (rv == OK || rv == ERR_IO_PENDING) { | |
| 230 RemoveRequestFromSpdySessionRequestMap(); | |
| 231 // Abandon all Jobs and start over. | |
| 232 job_bound_ = false; | |
| 233 bound_job_ = nullptr; | |
| 234 alternative_job_.reset(); | |
| 235 main_job_.reset(); | |
| 236 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; | |
| 237 } else { | |
| 238 // If ReconsiderProxyAfterError() failed synchronously, it means | |
| 239 // there was nothing left to fall-back to, so fail the transaction | |
| 240 // with the last connection error we got. | |
| 241 // TODO(eroman): This is a confusing contract, make it more obvious. | |
| 242 rv = error; | |
| 243 } | |
| 244 return rv; | |
| 245 } | |
| 246 | |
| 190 void HttpStreamFactoryImpl::JobController::SetPriority( | 247 void HttpStreamFactoryImpl::JobController::SetPriority( |
| 191 RequestPriority priority) { | 248 RequestPriority priority) { |
| 192 if (main_job_) { | 249 if (main_job_) { |
| 193 main_job_->SetPriority(priority); | 250 main_job_->SetPriority(priority); |
| 194 } | 251 } |
| 195 if (alternative_job_) { | 252 if (alternative_job_) { |
| 196 alternative_job_->SetPriority(priority); | 253 alternative_job_->SetPriority(priority); |
| 197 } | 254 } |
| 198 } | 255 } |
| 199 | 256 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 271 stream); | 328 stream); |
| 272 } | 329 } |
| 273 | 330 |
| 274 void HttpStreamFactoryImpl::JobController::OnStreamFailed( | 331 void HttpStreamFactoryImpl::JobController::OnStreamFailed( |
| 275 Job* job, | 332 Job* job, |
| 276 int status, | 333 int status, |
| 277 const SSLConfig& used_ssl_config) { | 334 const SSLConfig& used_ssl_config) { |
| 278 if (job->job_type() == ALTERNATIVE) { | 335 if (job->job_type() == ALTERNATIVE) { |
| 279 DCHECK_EQ(alternative_job_.get(), job); | 336 DCHECK_EQ(alternative_job_.get(), job); |
| 280 OnAlternativeJobFailed(status); | 337 OnAlternativeJobFailed(status); |
| 338 OnAlternativeProxyJobFailed(status); | |
| 281 } | 339 } |
| 282 | 340 |
| 283 MaybeResumeMainJob(job, base::TimeDelta()); | 341 MaybeResumeMainJob(job, base::TimeDelta()); |
| 284 | 342 |
| 285 if (IsJobOrphaned(job)) { | 343 if (IsJobOrphaned(job)) { |
| 286 // We have bound a job to the associated Request, |job| has been orphaned. | 344 // We have bound a job to the associated Request, |job| has been orphaned. |
| 287 OnOrphanedJobComplete(job); | 345 OnOrphanedJobComplete(job); |
| 288 return; | 346 return; |
| 289 } | 347 } |
| 290 | 348 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 302 } else { | 360 } else { |
| 303 DCHECK(job->job_type() == ALTERNATIVE); | 361 DCHECK(job->job_type() == ALTERNATIVE); |
| 304 alternative_job_.reset(); | 362 alternative_job_.reset(); |
| 305 } | 363 } |
| 306 return; | 364 return; |
| 307 } else { | 365 } else { |
| 308 BindJob(job); | 366 BindJob(job); |
| 309 } | 367 } |
| 310 } | 368 } |
| 311 | 369 |
| 370 status = ReconsiderProxyAfterError(job, status); | |
| 371 if (next_state_ == STATE_RESOLVE_PROXY_COMPLETE) { | |
| 372 RunLoop(OK); | |
| 373 return; | |
| 374 } | |
| 312 request_->OnStreamFailed(status, used_ssl_config); | 375 request_->OnStreamFailed(status, used_ssl_config); |
| 313 } | 376 } |
| 314 | 377 |
| 315 void HttpStreamFactoryImpl::JobController::OnCertificateError( | 378 void HttpStreamFactoryImpl::JobController::OnCertificateError( |
| 316 Job* job, | 379 Job* job, |
| 317 int status, | 380 int status, |
| 318 const SSLConfig& used_ssl_config, | 381 const SSLConfig& used_ssl_config, |
| 319 const SSLInfo& ssl_info) { | 382 const SSLInfo& ssl_info) { |
| 320 MaybeResumeMainJob(job, base::TimeDelta()); | 383 MaybeResumeMainJob(job, base::TimeDelta()); |
| 321 | 384 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 BindJob(job); | 458 BindJob(job); |
| 396 request_->OnNeedsProxyAuth(proxy_response, used_ssl_config, used_proxy_info, | 459 request_->OnNeedsProxyAuth(proxy_response, used_ssl_config, used_proxy_info, |
| 397 auth_controller); | 460 auth_controller); |
| 398 } | 461 } |
| 399 | 462 |
| 400 bool HttpStreamFactoryImpl::JobController::OnInitConnection( | 463 bool HttpStreamFactoryImpl::JobController::OnInitConnection( |
| 401 const ProxyInfo& proxy_info) { | 464 const ProxyInfo& proxy_info) { |
| 402 return factory_->OnInitConnection(*this, proxy_info, privacy_mode_); | 465 return factory_->OnInitConnection(*this, proxy_info, privacy_mode_); |
| 403 } | 466 } |
| 404 | 467 |
| 405 void HttpStreamFactoryImpl::JobController::OnResolveProxyComplete( | |
| 406 Job* job, | |
| 407 const HttpRequestInfo& request_info, | |
| 408 RequestPriority priority, | |
| 409 const SSLConfig& server_ssl_config, | |
| 410 const SSLConfig& proxy_ssl_config, | |
| 411 HttpStreamRequest::StreamType stream_type) { | |
| 412 DCHECK(job); | |
| 413 | |
| 414 ProxyServer alternative_proxy_server; | |
| 415 if (!ShouldCreateAlternativeProxyServerJob(job, job->proxy_info(), | |
| 416 request_info.url, | |
| 417 &alternative_proxy_server)) { | |
| 418 return; | |
| 419 } | |
| 420 | |
| 421 DCHECK(main_job_); | |
| 422 DCHECK_EQ(MAIN, job->job_type()); | |
| 423 DCHECK(!alternative_job_); | |
| 424 DCHECK(!main_job_is_blocked_); | |
| 425 | |
| 426 HostPortPair destination(HostPortPair::FromURL(request_info.url)); | |
| 427 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); | |
| 428 | |
| 429 alternative_job_.reset(job_factory_->CreateJob( | |
| 430 this, ALTERNATIVE, session_, request_info, priority, server_ssl_config, | |
| 431 proxy_ssl_config, destination, origin_url, alternative_proxy_server, | |
| 432 enable_ip_based_pooling_, job->net_log().net_log())); | |
| 433 | |
| 434 can_start_alternative_proxy_job_ = false; | |
| 435 main_job_is_blocked_ = true; | |
| 436 | |
| 437 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 438 FROM_HERE, | |
| 439 base::Bind( | |
| 440 &HttpStreamFactoryImpl::JobController::StartAlternativeProxyServerJob, | |
| 441 ptr_factory_.GetWeakPtr())); | |
| 442 } | |
| 443 | |
| 444 void HttpStreamFactoryImpl::JobController::OnNewSpdySessionReady( | 468 void HttpStreamFactoryImpl::JobController::OnNewSpdySessionReady( |
| 445 Job* job, | 469 Job* job, |
| 446 const base::WeakPtr<SpdySession>& spdy_session, | 470 const base::WeakPtr<SpdySession>& spdy_session, |
| 447 bool direct) { | 471 bool direct) { |
| 448 DCHECK(job); | 472 DCHECK(job); |
| 449 DCHECK(job->using_spdy()); | 473 DCHECK(job->using_spdy()); |
| 450 DCHECK(!is_preconnect_); | 474 DCHECK(!is_preconnect_); |
| 451 | 475 |
| 452 bool is_job_orphaned = IsJobOrphaned(job); | 476 bool is_job_orphaned = IsJobOrphaned(job); |
| 453 | 477 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 682 return base::trace_event::EstimateMemoryUsage(main_job_) + | 706 return base::trace_event::EstimateMemoryUsage(main_job_) + |
| 683 base::trace_event::EstimateMemoryUsage(alternative_job_); | 707 base::trace_event::EstimateMemoryUsage(alternative_job_); |
| 684 } | 708 } |
| 685 | 709 |
| 686 WebSocketHandshakeStreamBase::CreateHelper* HttpStreamFactoryImpl:: | 710 WebSocketHandshakeStreamBase::CreateHelper* HttpStreamFactoryImpl:: |
| 687 JobController::websocket_handshake_stream_create_helper() { | 711 JobController::websocket_handshake_stream_create_helper() { |
| 688 DCHECK(request_); | 712 DCHECK(request_); |
| 689 return request_->websocket_handshake_stream_create_helper(); | 713 return request_->websocket_handshake_stream_create_helper(); |
| 690 } | 714 } |
| 691 | 715 |
| 692 void HttpStreamFactoryImpl::JobController::CreateJobs( | 716 void HttpStreamFactoryImpl::JobController::OnIOComplete(int result) { |
| 693 const HttpRequestInfo& request_info, | 717 RunLoop(result); |
| 694 RequestPriority priority, | 718 } |
| 695 const SSLConfig& server_ssl_config, | 719 |
| 696 const SSLConfig& proxy_ssl_config, | 720 void HttpStreamFactoryImpl::JobController::OnResolveProxyError(int error) { |
| 697 HttpStreamRequest::Delegate* delegate, | |
| 698 HttpStreamRequest::StreamType stream_type) { | |
| 699 DCHECK(!main_job_); | 721 DCHECK(!main_job_); |
| 700 DCHECK(!alternative_job_); | 722 DCHECK(!alternative_job_); |
| 701 HostPortPair destination(HostPortPair::FromURL(request_info.url)); | |
| 702 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); | |
| 703 | 723 |
| 704 main_job_.reset(job_factory_->CreateJob( | 724 if (!request_) |
| 705 this, MAIN, session_, request_info, priority, server_ssl_config, | 725 return; |
| 706 proxy_ssl_config, destination, origin_url, enable_ip_based_pooling_, | 726 request_->OnStreamFailed(error, server_ssl_config_); |
| 707 net_log_.net_log())); | 727 } |
| 728 | |
| 729 void HttpStreamFactoryImpl::JobController::RunLoop(int result) { | |
| 730 DCHECK_NE(next_state_, STATE_NONE); | |
| 731 do { | |
| 732 State state = next_state_; | |
| 733 next_state_ = STATE_NONE; | |
| 734 switch (state) { | |
| 735 case STATE_RESOLVE_PROXY: | |
| 736 DoResolveProxy(); | |
| 737 break; | |
| 738 case STATE_RESOLVE_PROXY_COMPLETE: | |
| 739 DoResolveProxyComplete(result); | |
| 740 break; | |
| 741 case STATE_CREATE_JOBS: | |
| 742 DoCreateJobs(); | |
| 743 break; | |
| 744 default: | |
| 745 NOTREACHED() << "bad state"; | |
| 746 break; | |
| 747 } | |
| 748 } while (next_state_ != STATE_NONE); | |
|
Bence
2017/04/26 13:55:39
Do you not need to exit the loop if ResolveProxy r
xunjieli
2017/04/27 18:15:54
Done. Good catch. I have added a test case for thi
| |
| 749 } | |
| 750 | |
| 751 void HttpStreamFactoryImpl::JobController::DoResolveProxy() { | |
| 752 DCHECK(!pac_request_); | |
| 753 DCHECK(session_); | |
| 754 | |
| 755 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; | |
| 756 | |
| 757 if (request_info_.load_flags & LOAD_BYPASS_PROXY) { | |
| 758 proxy_info_.UseDirect(); | |
| 759 return; | |
| 760 } | |
| 761 | |
| 762 HostPortPair destination(HostPortPair::FromURL(request_info_.url)); | |
| 763 GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination); | |
| 764 | |
| 765 int rv = session_->proxy_service()->ResolveProxy( | |
| 766 origin_url, request_info_.method, &proxy_info_, io_callback_, | |
| 767 &pac_request_, session_->params().proxy_delegate, net_log_); | |
| 768 if (rv != OK && rv != ERR_IO_PENDING) { | |
| 769 // Proxy resolution failed synchronously. | |
| 770 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 771 FROM_HERE, | |
| 772 base::Bind(&HttpStreamFactoryImpl::JobController::OnResolveProxyError, | |
| 773 ptr_factory_.GetWeakPtr(), rv)); | |
| 774 } | |
| 775 } | |
| 776 | |
| 777 void HttpStreamFactoryImpl::JobController::DoResolveProxyComplete(int rv) { | |
| 778 DCHECK_NE(ERR_IO_PENDING, rv); | |
| 779 | |
| 780 pac_request_ = nullptr; | |
| 781 net_log_.AddEvent( | |
| 782 NetLogEventType::HTTP_STREAM_JOB_PROXY_SERVER_RESOLVED, | |
| 783 base::Bind( | |
| 784 &NetLogHttpStreamJobProxyServerResolved, | |
| 785 proxy_info_.is_empty() ? ProxyServer() : proxy_info_.proxy_server())); | |
| 786 | |
| 787 if (rv != OK) { | |
| 788 OnResolveProxyError(rv); | |
| 789 return; | |
| 790 } | |
| 791 | |
| 792 next_state_ = STATE_CREATE_JOBS; | |
| 793 return; | |
| 794 } | |
| 795 | |
| 796 void HttpStreamFactoryImpl::JobController::DoCreateJobs() { | |
| 797 DCHECK(!main_job_); | |
| 798 DCHECK(!alternative_job_); | |
| 799 | |
| 800 HostPortPair destination(HostPortPair::FromURL(request_info_.url)); | |
| 801 GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination); | |
| 708 | 802 |
| 709 // Create an alternative job if alternative service is set up for this domain. | 803 // Create an alternative job if alternative service is set up for this domain. |
| 710 const AlternativeService alternative_service = | 804 const AlternativeService alternative_service = |
| 711 GetAlternativeServiceFor(request_info, delegate, stream_type); | 805 GetAlternativeServiceFor(request_info_, delegate_, stream_type_); |
| 712 | 806 |
| 713 if (alternative_service.protocol != kProtoUnknown) { | 807 // Remove unsupported proxies from the list. ProxyServer::SCHEME_QUIC is not |
| 714 // Never share connection with other jobs for FTP requests. | 808 // yet supported. |
| 715 DVLOG(1) << "Selected alternative service (host: " | 809 int supported_proxies = ProxyServer::SCHEME_DIRECT | |
| 716 << alternative_service.host_port_pair().host() | 810 ProxyServer::SCHEME_HTTP | ProxyServer::SCHEME_HTTPS | |
| 717 << " port: " << alternative_service.host_port_pair().port() << ")"; | 811 ProxyServer::SCHEME_SOCKS4 | |
| 812 ProxyServer::SCHEME_SOCKS5; | |
| 718 | 813 |
| 719 DCHECK(!request_info.url.SchemeIs(url::kFtpScheme)); | 814 if (session_->IsQuicEnabled()) |
| 720 HostPortPair alternative_destination(alternative_service.host_port_pair()); | 815 supported_proxies |= ProxyServer::SCHEME_QUIC; |
| 721 ignore_result( | 816 proxy_info_.RemoveProxiesWithoutScheme(supported_proxies); |
| 722 ApplyHostMappingRules(request_info.url, &alternative_destination)); | |
| 723 | 817 |
| 724 alternative_job_.reset(job_factory_->CreateJob( | 818 if (is_preconnect_) { |
| 725 this, ALTERNATIVE, session_, request_info, priority, server_ssl_config, | 819 // Due to how the socket pools handle priorities and idle sockets, only IDLE |
| 726 proxy_ssl_config, alternative_destination, origin_url, | 820 // priority currently makes sense for preconnects. The priority for |
| 727 alternative_service, enable_ip_based_pooling_, net_log_.net_log())); | 821 // preconnects is currently ignored (see RequestSocketsForPool()), but could |
| 822 // be used at some point for proxy resolution or something. | |
| 823 main_job_.reset(job_factory_->CreateJob( | |
| 824 this, PRECONNECT, session_, request_info_, IDLE, proxy_info_, | |
| 825 server_ssl_config_, proxy_ssl_config_, destination, origin_url, | |
| 826 alternative_service, enable_ip_based_pooling_, session_->net_log())); | |
| 827 main_job_->Preconnect(num_streams_); | |
| 828 } else { | |
| 829 main_job_.reset(job_factory_->CreateJob( | |
| 830 this, MAIN, session_, request_info_, priority_, proxy_info_, | |
| 831 server_ssl_config_, proxy_ssl_config_, destination, origin_url, | |
| 832 enable_ip_based_pooling_, net_log_.net_log())); | |
| 833 if (alternative_service.protocol != kProtoUnknown) { | |
| 834 // Never share connection with other jobs for FTP requests. | |
| 835 DVLOG(1) << "Selected alternative service (host: " | |
| 836 << alternative_service.host_port_pair().host() | |
| 837 << " port: " << alternative_service.host_port_pair().port() | |
| 838 << ")"; | |
| 728 | 839 |
| 729 main_job_is_blocked_ = true; | 840 DCHECK(!request_info_.url.SchemeIs(url::kFtpScheme)); |
| 730 alternative_job_->Start(request_->stream_type()); | 841 HostPortPair alternative_destination( |
| 731 } else { | 842 alternative_service.host_port_pair()); |
| 732 can_start_alternative_proxy_job_ = true; | 843 ignore_result( |
| 844 ApplyHostMappingRules(request_info_.url, &alternative_destination)); | |
| 845 | |
| 846 alternative_job_.reset(job_factory_->CreateJob( | |
| 847 this, ALTERNATIVE, session_, request_info_, priority_, proxy_info_, | |
| 848 server_ssl_config_, proxy_ssl_config_, alternative_destination, | |
| 849 origin_url, alternative_service, enable_ip_based_pooling_, | |
| 850 net_log_.net_log())); | |
| 851 | |
| 852 main_job_is_blocked_ = true; | |
| 853 alternative_job_->Start(request_->stream_type()); | |
| 854 } | |
| 855 if (!alternative_job_) { | |
| 856 ProxyServer alternative_proxy_server; | |
| 857 if (ShouldCreateAlternativeProxyServerJob(proxy_info_, request_info_.url, | |
| 858 &alternative_proxy_server)) { | |
| 859 DCHECK(main_job_); | |
| 860 DCHECK(!main_job_is_blocked_); | |
| 861 ProxyInfo alternative_proxy_info; | |
| 862 alternative_proxy_info.UseProxyServer(alternative_proxy_server); | |
| 863 | |
| 864 alternative_job_.reset(job_factory_->CreateJob( | |
| 865 this, ALTERNATIVE, session_, request_info_, priority_, | |
| 866 alternative_proxy_info, server_ssl_config_, proxy_ssl_config_, | |
| 867 destination, origin_url, alternative_proxy_server, | |
| 868 enable_ip_based_pooling_, net_log_.net_log())); | |
| 869 | |
| 870 can_start_alternative_proxy_job_ = false; | |
| 871 main_job_is_blocked_ = true; | |
| 872 | |
| 873 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 874 FROM_HERE, base::Bind(&HttpStreamFactoryImpl::JobController:: | |
| 875 StartAlternativeProxyServerJob, | |
| 876 ptr_factory_.GetWeakPtr())); | |
| 877 } | |
| 878 } | |
| 879 // Even if |alternative_job| has already finished, it will not have notified | |
| 880 // the request yet, since we defer that to the next iteration of the | |
| 881 // MessageLoop, so starting |main_job_| is always safe. | |
| 882 main_job_->Start(request_->stream_type()); | |
| 733 } | 883 } |
| 734 // Even if |alternative_job| has already finished, it will not have notified | 884 return; |
| 735 // the request yet, since we defer that to the next iteration of the | |
| 736 // MessageLoop, so starting |main_job_| is always safe. | |
| 737 main_job_->Start(request_->stream_type()); | |
| 738 } | 885 } |
| 739 | 886 |
| 740 void HttpStreamFactoryImpl::JobController::BindJob(Job* job) { | 887 void HttpStreamFactoryImpl::JobController::BindJob(Job* job) { |
| 741 DCHECK(request_); | 888 DCHECK(request_); |
| 742 DCHECK(job); | 889 DCHECK(job); |
| 743 DCHECK(job == alternative_job_.get() || job == main_job_.get()); | 890 DCHECK(job == alternative_job_.get() || job == main_job_.get()); |
| 744 DCHECK(!job_bound_); | 891 DCHECK(!job_bound_); |
| 745 DCHECK(!bound_job_); | 892 DCHECK(!bound_job_); |
| 746 | 893 |
| 747 job_bound_ = true; | 894 job_bound_ = true; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 828 bool using_spdy) { | 975 bool using_spdy) { |
| 829 if (request_) | 976 if (request_) |
| 830 request_->Complete(was_alpn_negotiated, negotiated_protocol, using_spdy); | 977 request_->Complete(was_alpn_negotiated, negotiated_protocol, using_spdy); |
| 831 } | 978 } |
| 832 | 979 |
| 833 void HttpStreamFactoryImpl::JobController::OnAlternativeJobFailed( | 980 void HttpStreamFactoryImpl::JobController::OnAlternativeJobFailed( |
| 834 int net_error) { | 981 int net_error) { |
| 835 DCHECK_EQ(alternative_job_->job_type(), ALTERNATIVE); | 982 DCHECK_EQ(alternative_job_->job_type(), ALTERNATIVE); |
| 836 DCHECK_NE(OK, net_error); | 983 DCHECK_NE(OK, net_error); |
| 837 | 984 |
| 985 DCHECK(alternative_job_->alternative_service().protocol != kProtoUnknown || | |
| 986 alternative_job_->alternative_proxy_server().is_valid()); | |
| 987 if (alternative_job_->alternative_proxy_server().is_valid()) | |
| 988 return; | |
| 989 | |
| 838 alternative_job_net_error_ = net_error; | 990 alternative_job_net_error_ = net_error; |
| 839 | 991 |
| 840 if (alternative_job_->alternative_proxy_server().is_valid()) { | 992 failed_alternative_service_ = alternative_job_->alternative_service(); |
| 841 failed_alternative_proxy_server_ = | |
| 842 alternative_job_->alternative_proxy_server(); | |
| 843 } else { | |
| 844 DCHECK(!failed_alternative_proxy_server_.is_valid()); | |
| 845 failed_alternative_service_ = alternative_job_->alternative_service(); | |
| 846 } | |
| 847 | 993 |
| 848 if (IsJobOrphaned(alternative_job_.get())) { | 994 if (IsJobOrphaned(alternative_job_.get())) { |
| 849 // If |request_| is gone then it must have been successfully served by | 995 // If |request_| is gone then it must have been successfully served by |
| 850 // |main_job_|. | 996 // |main_job_|. |
| 851 // If |request_| is bound to a different job, then it is being | 997 // If |request_| is bound to a different job, then it is being |
| 852 // successfully serverd by the main job. | 998 // successfully serverd by the main job. |
| 853 ReportBrokenAlternativeService(); | 999 ReportBrokenAlternativeService(); |
| 854 } | 1000 } |
| 855 } | 1001 } |
| 856 | 1002 |
| 1003 void HttpStreamFactoryImpl::JobController::OnAlternativeProxyJobFailed( | |
| 1004 int net_error) { | |
| 1005 DCHECK_EQ(alternative_job_->job_type(), ALTERNATIVE); | |
| 1006 DCHECK_NE(OK, net_error); | |
| 1007 | |
| 1008 if (!alternative_job_->alternative_proxy_server().is_valid()) | |
| 1009 return; | |
| 1010 // Need to mark alt proxy as broken regardless whether the job is bound. | |
| 1011 ProxyDelegate* proxy_delegate = session_->params().proxy_delegate; | |
| 1012 if (proxy_delegate) { | |
| 1013 proxy_delegate->OnAlternativeProxyBroken( | |
| 1014 alternative_job_->alternative_proxy_server()); | |
| 1015 } | |
| 1016 } | |
| 1017 | |
| 857 void HttpStreamFactoryImpl::JobController::ReportBrokenAlternativeService() { | 1018 void HttpStreamFactoryImpl::JobController::ReportBrokenAlternativeService() { |
| 858 DCHECK(failed_alternative_service_.protocol != kProtoUnknown || | 1019 DCHECK(failed_alternative_service_.protocol != kProtoUnknown); |
| 859 failed_alternative_proxy_server_.is_valid()); | |
| 860 DCHECK_NE(OK, alternative_job_net_error_); | 1020 DCHECK_NE(OK, alternative_job_net_error_); |
| 861 | 1021 |
| 862 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.AlternateServiceFailed", | 1022 int error_to_report = alternative_job_net_error_; |
| 863 -alternative_job_net_error_); | 1023 alternative_job_net_error_ = OK; |
| 1024 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.AlternateServiceFailed", -error_to_report); | |
| 864 | 1025 |
| 865 if (session_->params().quic_do_not_mark_as_broken_on_network_change && | 1026 if (session_->params().quic_do_not_mark_as_broken_on_network_change && |
| 866 (alternative_job_net_error_ == ERR_NETWORK_CHANGED || | 1027 (error_to_report == ERR_NETWORK_CHANGED || |
| 867 alternative_job_net_error_ == ERR_INTERNET_DISCONNECTED)) { | 1028 error_to_report == ERR_INTERNET_DISCONNECTED)) { |
| 868 // No need to mark alternative service or proxy as broken. | 1029 // No need to mark alternative service or proxy as broken. |
| 869 return; | 1030 return; |
| 870 } | 1031 } |
| 871 | 1032 |
| 872 if (failed_alternative_proxy_server_.is_valid()) { | 1033 HistogramBrokenAlternateProtocolLocation( |
| 873 ProxyDelegate* proxy_delegate = session_->params().proxy_delegate; | 1034 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); |
| 874 if (proxy_delegate) { | 1035 session_->http_server_properties()->MarkAlternativeServiceBroken( |
| 875 proxy_delegate->OnAlternativeProxyBroken( | 1036 failed_alternative_service_); |
| 876 failed_alternative_proxy_server_); | |
| 877 } | |
| 878 } else { | |
| 879 HistogramBrokenAlternateProtocolLocation( | |
| 880 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); | |
| 881 session_->http_server_properties()->MarkAlternativeServiceBroken( | |
| 882 failed_alternative_service_); | |
| 883 } | |
| 884 } | 1037 } |
| 885 | 1038 |
| 886 void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() { | 1039 void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() { |
| 887 if (!request_ && !main_job_ && !alternative_job_) { | 1040 if (!request_ && !main_job_ && !alternative_job_) { |
| 888 DCHECK(!bound_job_); | 1041 DCHECK(!bound_job_); |
| 889 factory_->OnJobControllerComplete(this); | 1042 factory_->OnJobControllerComplete(this); |
| 890 } | 1043 } |
| 891 } | 1044 } |
| 892 | 1045 |
| 893 GURL HttpStreamFactoryImpl::JobController::ApplyHostMappingRules( | 1046 GURL HttpStreamFactoryImpl::JobController::ApplyHostMappingRules( |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1026 | 1179 |
| 1027 // Ask delegate to mark QUIC as broken for the origin. | 1180 // Ask delegate to mark QUIC as broken for the origin. |
| 1028 if (quic_advertised && quic_all_broken && delegate != nullptr) | 1181 if (quic_advertised && quic_all_broken && delegate != nullptr) |
| 1029 delegate->OnQuicBroken(); | 1182 delegate->OnQuicBroken(); |
| 1030 | 1183 |
| 1031 return first_alternative_service; | 1184 return first_alternative_service; |
| 1032 } | 1185 } |
| 1033 | 1186 |
| 1034 bool HttpStreamFactoryImpl::JobController:: | 1187 bool HttpStreamFactoryImpl::JobController:: |
| 1035 ShouldCreateAlternativeProxyServerJob( | 1188 ShouldCreateAlternativeProxyServerJob( |
| 1036 Job* job, | |
| 1037 const ProxyInfo& proxy_info, | 1189 const ProxyInfo& proxy_info, |
| 1038 const GURL& url, | 1190 const GURL& url, |
| 1039 ProxyServer* alternative_proxy_server) const { | 1191 ProxyServer* alternative_proxy_server) const { |
| 1040 DCHECK(!alternative_proxy_server->is_valid()); | 1192 DCHECK(!alternative_proxy_server->is_valid()); |
| 1041 | 1193 |
| 1042 if (!enable_alternative_services_) | 1194 if (!enable_alternative_services_) |
| 1043 return false; | 1195 return false; |
| 1044 | 1196 |
| 1045 if (!can_start_alternative_proxy_job_) { | 1197 if (!can_start_alternative_proxy_job_) { |
| 1046 // Either an alternative service job or an alternative proxy server job has | 1198 // Either an alternative service job or an alternative proxy server job has |
| 1047 // already been started. | 1199 // already been started. |
| 1048 return false; | 1200 return false; |
| 1049 } | 1201 } |
| 1050 | 1202 |
| 1051 if (job->job_type() == ALTERNATIVE) { | |
| 1052 // If |job| is using alternative service, then alternative proxy server | |
| 1053 // should not be used. | |
| 1054 return false; | |
| 1055 } | |
| 1056 | |
| 1057 if (is_preconnect_ || job->job_type() == PRECONNECT) { | |
| 1058 // Preconnects should be fetched using only the main job to keep the | |
| 1059 // resource utilization down. | |
| 1060 return false; | |
| 1061 } | |
| 1062 | |
| 1063 if (proxy_info.is_empty() || proxy_info.is_direct() || proxy_info.is_quic()) { | 1203 if (proxy_info.is_empty() || proxy_info.is_direct() || proxy_info.is_quic()) { |
| 1064 // Alternative proxy server job can be created only if |job| fetches the | 1204 // Alternative proxy server job can be created only if |job| fetches the |
| 1065 // |request_| through a non-QUIC proxy. | 1205 // |request_| through a non-QUIC proxy. |
| 1066 return false; | 1206 return false; |
| 1067 } | 1207 } |
| 1068 | 1208 |
| 1069 if (!url.SchemeIs(url::kHttpScheme)) { | 1209 if (!url.SchemeIs(url::kHttpScheme)) { |
| 1070 // Only HTTP URLs can be fetched through alternative proxy server, since the | 1210 // Only HTTP URLs can be fetched through alternative proxy server, since the |
| 1071 // alternative proxy server may not support fetching of URLs with other | 1211 // alternative proxy server may not support fetching of URLs with other |
| 1072 // schemes. | 1212 // schemes. |
| 1073 return false; | 1213 return false; |
| 1074 } | 1214 } |
| 1075 | 1215 |
| 1076 ProxyDelegate* proxy_delegate = session_->params().proxy_delegate; | 1216 ProxyDelegate* proxy_delegate = session_->params().proxy_delegate; |
| 1077 if (!proxy_delegate) | 1217 if (!proxy_delegate) |
| 1078 return false; | 1218 return false; |
| 1079 | |
| 1080 proxy_delegate->GetAlternativeProxy(url, proxy_info.proxy_server(), | 1219 proxy_delegate->GetAlternativeProxy(url, proxy_info.proxy_server(), |
| 1081 alternative_proxy_server); | 1220 alternative_proxy_server); |
| 1082 | 1221 |
| 1083 if (!alternative_proxy_server->is_valid()) | 1222 if (!alternative_proxy_server->is_valid()) |
| 1084 return false; | 1223 return false; |
| 1085 | 1224 |
| 1086 DCHECK(!(*alternative_proxy_server == proxy_info.proxy_server())); | 1225 DCHECK(!(*alternative_proxy_server == proxy_info.proxy_server())); |
| 1087 | 1226 |
| 1088 if (!alternative_proxy_server->is_https() && | 1227 if (!alternative_proxy_server->is_https() && |
| 1089 !alternative_proxy_server->is_quic()) { | 1228 !alternative_proxy_server->is_quic()) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1129 return; | 1268 return; |
| 1130 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); | 1269 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); |
| 1131 alternative_job_->Start(request_->stream_type()); | 1270 alternative_job_->Start(request_->stream_type()); |
| 1132 } | 1271 } |
| 1133 | 1272 |
| 1134 bool HttpStreamFactoryImpl::JobController::IsJobOrphaned(Job* job) const { | 1273 bool HttpStreamFactoryImpl::JobController::IsJobOrphaned(Job* job) const { |
| 1135 return !request_ || (job_bound_ && bound_job_ != job); | 1274 return !request_ || (job_bound_ && bound_job_ != job); |
| 1136 } | 1275 } |
| 1137 | 1276 |
| 1138 } // namespace net | 1277 } // namespace net |
| OLD | NEW |