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 |
| 34 // Returns parameters associated with the proxy resolution. |
| 35 std::unique_ptr<base::Value> NetLogHttpStreamJobProxyServerResolved( |
| 36 const ProxyServer& proxy_server, |
| 37 NetLogCaptureMode /* capture_mode */) { |
| 38 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 39 |
| 40 dict->SetString("proxy_server", proxy_server.is_valid() |
| 41 ? proxy_server.ToPacString() |
| 42 : std::string()); |
| 43 return std::move(dict); |
| 44 } |
| 45 |
| 46 } // namespace |
| 47 |
32 // The maximum time to wait for the alternate job to complete before resuming | 48 // The maximum time to wait for the alternate job to complete before resuming |
33 // the main job. | 49 // the main job. |
34 const int kMaxDelayTimeForMainJobSecs = 3; | 50 const int kMaxDelayTimeForMainJobSecs = 3; |
35 | 51 |
36 std::unique_ptr<base::Value> NetLogJobControllerCallback( | 52 std::unique_ptr<base::Value> NetLogJobControllerCallback( |
37 const GURL* url, | 53 const GURL* url, |
38 bool is_preconnect, | 54 bool is_preconnect, |
39 NetLogCaptureMode /* capture_mode */) { | 55 NetLogCaptureMode /* capture_mode */) { |
40 auto dict = base::MakeUnique<base::DictionaryValue>(); | 56 auto dict = base::MakeUnique<base::DictionaryValue>(); |
41 dict->SetString("url", url->possibly_invalid_spec()); | 57 dict->SetString("url", url->possibly_invalid_spec()); |
42 dict->SetBoolean("is_preconnect", is_preconnect); | 58 dict->SetBoolean("is_preconnect", is_preconnect); |
43 return std::move(dict); | 59 return std::move(dict); |
44 } | 60 } |
45 | 61 |
46 HttpStreamFactoryImpl::JobController::JobController( | 62 HttpStreamFactoryImpl::JobController::JobController( |
47 HttpStreamFactoryImpl* factory, | 63 HttpStreamFactoryImpl* factory, |
48 HttpStreamRequest::Delegate* delegate, | 64 HttpStreamRequest::Delegate* delegate, |
49 HttpNetworkSession* session, | 65 HttpNetworkSession* session, |
50 JobFactory* job_factory, | 66 JobFactory* job_factory, |
51 const HttpRequestInfo& request_info, | 67 const HttpRequestInfo& request_info, |
52 bool is_preconnect, | 68 bool is_preconnect, |
53 bool enable_ip_based_pooling, | 69 bool enable_ip_based_pooling, |
54 bool enable_alternative_services) | 70 bool enable_alternative_services, |
| 71 const SSLConfig& server_ssl_config, |
| 72 const SSLConfig& proxy_ssl_config) |
55 : factory_(factory), | 73 : factory_(factory), |
56 session_(session), | 74 session_(session), |
57 job_factory_(job_factory), | 75 job_factory_(job_factory), |
58 request_(nullptr), | 76 request_(nullptr), |
59 delegate_(delegate), | 77 delegate_(delegate), |
60 is_preconnect_(is_preconnect), | 78 is_preconnect_(is_preconnect), |
61 enable_ip_based_pooling_(enable_ip_based_pooling), | 79 enable_ip_based_pooling_(enable_ip_based_pooling), |
62 enable_alternative_services_(enable_alternative_services), | 80 enable_alternative_services_(enable_alternative_services), |
63 alternative_job_net_error_(OK), | 81 alternative_job_net_error_(OK), |
64 job_bound_(false), | 82 job_bound_(false), |
65 main_job_is_blocked_(false), | 83 main_job_is_blocked_(false), |
66 main_job_is_resumed_(false), | 84 main_job_is_resumed_(false), |
67 bound_job_(nullptr), | 85 bound_job_(nullptr), |
68 can_start_alternative_proxy_job_(false), | 86 can_start_alternative_proxy_job_(true), |
69 privacy_mode_(PRIVACY_MODE_DISABLED), | 87 next_state_(STATE_RESOLVE_PROXY), |
| 88 pac_request_(nullptr), |
| 89 io_callback_( |
| 90 base::Bind(&JobController::OnIOComplete, base::Unretained(this))), |
| 91 request_info_(request_info), |
| 92 server_ssl_config_(server_ssl_config), |
| 93 proxy_ssl_config_(proxy_ssl_config), |
| 94 num_streams_(0), |
| 95 priority_(IDLE), |
70 net_log_( | 96 net_log_( |
71 NetLogWithSource::Make(session->net_log(), | 97 NetLogWithSource::Make(session->net_log(), |
72 NetLogSourceType::HTTP_STREAM_JOB_CONTROLLER)), | 98 NetLogSourceType::HTTP_STREAM_JOB_CONTROLLER)), |
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 stream_type_ = stream_type; |
| 130 priority_ = priority; |
105 | 131 |
106 request_ = new Request(request_info.url, this, delegate, | 132 request_ = new Request(request_info_.url, this, delegate, |
107 websocket_handshake_stream_create_helper, | 133 websocket_handshake_stream_create_helper, |
108 source_net_log, stream_type); | 134 source_net_log, stream_type); |
109 // Associates |net_log_| with |source_net_log|. | 135 // Associates |net_log_| with |source_net_log|. |
110 source_net_log.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, | 136 source_net_log.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, |
111 net_log_.source().ToEventParametersCallback()); | 137 net_log_.source().ToEventParametersCallback()); |
112 net_log_.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, | 138 net_log_.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, |
113 source_net_log.source().ToEventParametersCallback()); | 139 source_net_log.source().ToEventParametersCallback()); |
114 | 140 |
115 CreateJobs(request_info, priority, server_ssl_config, proxy_ssl_config, | 141 RunLoop(OK); |
116 delegate, stream_type); | |
117 | |
118 return request_; | 142 return request_; |
119 } | 143 } |
120 | 144 |
121 void HttpStreamFactoryImpl::JobController::Preconnect( | 145 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_); | 146 DCHECK(!main_job_); |
127 DCHECK(!alternative_job_); | 147 DCHECK(!alternative_job_); |
128 DCHECK(is_preconnect_); | 148 DCHECK(is_preconnect_); |
129 | 149 |
130 privacy_mode_ = request_info.privacy_mode; | 150 stream_type_ = HttpStreamRequest::HTTP_STREAM; |
| 151 num_streams_ = num_streams; |
131 | 152 |
132 HostPortPair destination(HostPortPair::FromURL(request_info.url)); | 153 RunLoop(OK); |
133 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); | |
134 | |
135 const AlternativeService alternative_service = GetAlternativeServiceFor( | |
136 request_info, nullptr, HttpStreamRequest::HTTP_STREAM); | |
137 | |
138 if (alternative_service.protocol != kProtoUnknown) { | |
139 destination = alternative_service.host_port_pair(); | |
140 ignore_result(ApplyHostMappingRules(request_info.url, &destination)); | |
141 } | |
142 | |
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 } | 154 } |
153 | 155 |
154 LoadState HttpStreamFactoryImpl::JobController::GetLoadState() const { | 156 LoadState HttpStreamFactoryImpl::JobController::GetLoadState() const { |
155 DCHECK(request_); | 157 DCHECK(request_); |
| 158 if (next_state_ == STATE_RESOLVE_PROXY_COMPLETE) |
| 159 return session_->proxy_service()->GetLoadState(pac_request_); |
156 DCHECK(main_job_ || alternative_job_); | 160 DCHECK(main_job_ || alternative_job_); |
157 if (bound_job_) | 161 if (bound_job_) |
158 return bound_job_->GetLoadState(); | 162 return bound_job_->GetLoadState(); |
159 | 163 |
160 // Just pick the first one. | 164 // Just pick the first one. |
161 return main_job_ ? main_job_->GetLoadState() | 165 return main_job_ ? main_job_->GetLoadState() |
162 : alternative_job_->GetLoadState(); | 166 : alternative_job_->GetLoadState(); |
163 } | 167 } |
164 | 168 |
165 void HttpStreamFactoryImpl::JobController::OnRequestComplete() { | 169 void HttpStreamFactoryImpl::JobController::OnRequestComplete() { |
(...skipping 29 matching lines...) Expand all Loading... |
195 if (alternative_job_) { | 199 if (alternative_job_) { |
196 alternative_job_->SetPriority(priority); | 200 alternative_job_->SetPriority(priority); |
197 } | 201 } |
198 } | 202 } |
199 | 203 |
200 void HttpStreamFactoryImpl::JobController::OnStreamReady( | 204 void HttpStreamFactoryImpl::JobController::OnStreamReady( |
201 Job* job, | 205 Job* job, |
202 const SSLConfig& used_ssl_config) { | 206 const SSLConfig& used_ssl_config) { |
203 DCHECK(job); | 207 DCHECK(job); |
204 | 208 |
205 factory_->OnStreamReady(job->proxy_info(), privacy_mode_); | 209 factory_->OnStreamReady(job->proxy_info(), request_info_.privacy_mode); |
206 | 210 |
207 if (IsJobOrphaned(job)) { | 211 if (IsJobOrphaned(job)) { |
208 // We have bound a job to the associated Request, |job| has been orphaned. | 212 // We have bound a job to the associated Request, |job| has been orphaned. |
209 OnOrphanedJobComplete(job); | 213 OnOrphanedJobComplete(job); |
210 return; | 214 return; |
211 } | 215 } |
212 std::unique_ptr<HttpStream> stream = job->ReleaseStream(); | 216 std::unique_ptr<HttpStream> stream = job->ReleaseStream(); |
213 DCHECK(stream); | 217 DCHECK(stream); |
214 | 218 |
215 MarkRequestComplete(job->was_alpn_negotiated(), job->negotiated_protocol(), | 219 MarkRequestComplete(job->was_alpn_negotiated(), job->negotiated_protocol(), |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 request_->OnWebSocketHandshakeStreamReady(used_ssl_config, used_proxy_info, | 274 request_->OnWebSocketHandshakeStreamReady(used_ssl_config, used_proxy_info, |
271 stream); | 275 stream); |
272 } | 276 } |
273 | 277 |
274 void HttpStreamFactoryImpl::JobController::OnStreamFailed( | 278 void HttpStreamFactoryImpl::JobController::OnStreamFailed( |
275 Job* job, | 279 Job* job, |
276 int status, | 280 int status, |
277 const SSLConfig& used_ssl_config) { | 281 const SSLConfig& used_ssl_config) { |
278 if (job->job_type() == ALTERNATIVE) { | 282 if (job->job_type() == ALTERNATIVE) { |
279 DCHECK_EQ(alternative_job_.get(), job); | 283 DCHECK_EQ(alternative_job_.get(), job); |
280 OnAlternativeJobFailed(status); | 284 if (alternative_job_->alternative_proxy_server().is_valid()) { |
| 285 OnAlternativeProxyJobFailed(status); |
| 286 } else { |
| 287 OnAlternativeServiceJobFailed(status); |
| 288 } |
281 } | 289 } |
282 | 290 |
283 MaybeResumeMainJob(job, base::TimeDelta()); | 291 MaybeResumeMainJob(job, base::TimeDelta()); |
284 | 292 |
285 if (IsJobOrphaned(job)) { | 293 if (IsJobOrphaned(job)) { |
286 // We have bound a job to the associated Request, |job| has been orphaned. | 294 // We have bound a job to the associated Request, |job| has been orphaned. |
287 OnOrphanedJobComplete(job); | 295 OnOrphanedJobComplete(job); |
288 return; | 296 return; |
289 } | 297 } |
290 | 298 |
(...skipping 11 matching lines...) Expand all Loading... |
302 } else { | 310 } else { |
303 DCHECK(job->job_type() == ALTERNATIVE); | 311 DCHECK(job->job_type() == ALTERNATIVE); |
304 alternative_job_.reset(); | 312 alternative_job_.reset(); |
305 } | 313 } |
306 return; | 314 return; |
307 } else { | 315 } else { |
308 BindJob(job); | 316 BindJob(job); |
309 } | 317 } |
310 } | 318 } |
311 | 319 |
| 320 status = ReconsiderProxyAfterError(job, status); |
| 321 if (next_state_ == STATE_RESOLVE_PROXY_COMPLETE) { |
| 322 RunLoop(OK); |
| 323 return; |
| 324 } |
312 request_->OnStreamFailed(status, used_ssl_config); | 325 request_->OnStreamFailed(status, used_ssl_config); |
313 } | 326 } |
314 | 327 |
315 void HttpStreamFactoryImpl::JobController::OnCertificateError( | 328 void HttpStreamFactoryImpl::JobController::OnCertificateError( |
316 Job* job, | 329 Job* job, |
317 int status, | 330 int status, |
318 const SSLConfig& used_ssl_config, | 331 const SSLConfig& used_ssl_config, |
319 const SSLInfo& ssl_info) { | 332 const SSLInfo& ssl_info) { |
320 MaybeResumeMainJob(job, base::TimeDelta()); | 333 MaybeResumeMainJob(job, base::TimeDelta()); |
321 | 334 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 if (!request_) | 405 if (!request_) |
393 return; | 406 return; |
394 if (!bound_job_) | 407 if (!bound_job_) |
395 BindJob(job); | 408 BindJob(job); |
396 request_->OnNeedsProxyAuth(proxy_response, used_ssl_config, used_proxy_info, | 409 request_->OnNeedsProxyAuth(proxy_response, used_ssl_config, used_proxy_info, |
397 auth_controller); | 410 auth_controller); |
398 } | 411 } |
399 | 412 |
400 bool HttpStreamFactoryImpl::JobController::OnInitConnection( | 413 bool HttpStreamFactoryImpl::JobController::OnInitConnection( |
401 const ProxyInfo& proxy_info) { | 414 const ProxyInfo& proxy_info) { |
402 return factory_->OnInitConnection(*this, proxy_info, privacy_mode_); | 415 return factory_->OnInitConnection(*this, proxy_info, |
403 } | 416 request_info_.privacy_mode); |
404 | |
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 } | 417 } |
443 | 418 |
444 void HttpStreamFactoryImpl::JobController::OnNewSpdySessionReady( | 419 void HttpStreamFactoryImpl::JobController::OnNewSpdySessionReady( |
445 Job* job, | 420 Job* job, |
446 const base::WeakPtr<SpdySession>& spdy_session, | 421 const base::WeakPtr<SpdySession>& spdy_session, |
447 bool direct) { | 422 bool direct) { |
448 DCHECK(job); | 423 DCHECK(job); |
449 DCHECK(job->using_spdy()); | 424 DCHECK(job->using_spdy()); |
450 DCHECK(!is_preconnect_); | 425 DCHECK(!is_preconnect_); |
451 | 426 |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 return base::trace_event::EstimateMemoryUsage(main_job_) + | 657 return base::trace_event::EstimateMemoryUsage(main_job_) + |
683 base::trace_event::EstimateMemoryUsage(alternative_job_); | 658 base::trace_event::EstimateMemoryUsage(alternative_job_); |
684 } | 659 } |
685 | 660 |
686 WebSocketHandshakeStreamBase::CreateHelper* HttpStreamFactoryImpl:: | 661 WebSocketHandshakeStreamBase::CreateHelper* HttpStreamFactoryImpl:: |
687 JobController::websocket_handshake_stream_create_helper() { | 662 JobController::websocket_handshake_stream_create_helper() { |
688 DCHECK(request_); | 663 DCHECK(request_); |
689 return request_->websocket_handshake_stream_create_helper(); | 664 return request_->websocket_handshake_stream_create_helper(); |
690 } | 665 } |
691 | 666 |
692 void HttpStreamFactoryImpl::JobController::CreateJobs( | 667 void HttpStreamFactoryImpl::JobController::OnIOComplete(int result) { |
693 const HttpRequestInfo& request_info, | 668 RunLoop(result); |
694 RequestPriority priority, | 669 } |
695 const SSLConfig& server_ssl_config, | 670 |
696 const SSLConfig& proxy_ssl_config, | 671 void HttpStreamFactoryImpl::JobController::RunLoop(int result) { |
697 HttpStreamRequest::Delegate* delegate, | 672 int rv = DoLoop(result); |
698 HttpStreamRequest::StreamType stream_type) { | 673 if (rv == ERR_IO_PENDING) |
| 674 return; |
| 675 if (rv != OK) { |
| 676 // DoLoop can only fail during proxy resolution step which happens before |
| 677 // any jobs are created. Notify |request_| of the failure one message loop |
| 678 // iteration later to avoid re-entrancy. |
| 679 DCHECK(!main_job_); |
| 680 DCHECK(!alternative_job_); |
| 681 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 682 FROM_HERE, |
| 683 base::Bind(&HttpStreamFactoryImpl::JobController::NotifyRequestFailed, |
| 684 ptr_factory_.GetWeakPtr(), rv)); |
| 685 } |
| 686 } |
| 687 |
| 688 int HttpStreamFactoryImpl::JobController::DoLoop(int rv) { |
| 689 DCHECK_NE(next_state_, STATE_NONE); |
| 690 do { |
| 691 State state = next_state_; |
| 692 next_state_ = STATE_NONE; |
| 693 switch (state) { |
| 694 case STATE_RESOLVE_PROXY: |
| 695 DCHECK_EQ(OK, rv); |
| 696 rv = DoResolveProxy(); |
| 697 break; |
| 698 case STATE_RESOLVE_PROXY_COMPLETE: |
| 699 rv = DoResolveProxyComplete(rv); |
| 700 break; |
| 701 case STATE_CREATE_JOBS: |
| 702 DCHECK_EQ(OK, rv); |
| 703 rv = DoCreateJobs(); |
| 704 break; |
| 705 default: |
| 706 NOTREACHED() << "bad state"; |
| 707 break; |
| 708 } |
| 709 } while (next_state_ != STATE_NONE && rv != ERR_IO_PENDING); |
| 710 return rv; |
| 711 } |
| 712 |
| 713 int HttpStreamFactoryImpl::JobController::DoResolveProxy() { |
| 714 DCHECK(!pac_request_); |
| 715 DCHECK(session_); |
| 716 |
| 717 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; |
| 718 |
| 719 if (request_info_.load_flags & LOAD_BYPASS_PROXY) { |
| 720 proxy_info_.UseDirect(); |
| 721 return OK; |
| 722 } |
| 723 |
| 724 HostPortPair destination(HostPortPair::FromURL(request_info_.url)); |
| 725 GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination); |
| 726 |
| 727 return session_->proxy_service()->ResolveProxy( |
| 728 origin_url, request_info_.method, &proxy_info_, io_callback_, |
| 729 &pac_request_, session_->params().proxy_delegate, net_log_); |
| 730 } |
| 731 |
| 732 int HttpStreamFactoryImpl::JobController::DoResolveProxyComplete(int rv) { |
| 733 DCHECK_NE(ERR_IO_PENDING, rv); |
| 734 |
| 735 pac_request_ = nullptr; |
| 736 net_log_.AddEvent( |
| 737 NetLogEventType::HTTP_STREAM_JOB_PROXY_SERVER_RESOLVED, |
| 738 base::Bind( |
| 739 &NetLogHttpStreamJobProxyServerResolved, |
| 740 proxy_info_.is_empty() ? ProxyServer() : proxy_info_.proxy_server())); |
| 741 |
| 742 if (rv != OK) |
| 743 return rv; |
| 744 // Remove unsupported proxies from the list. |
| 745 int supported_proxies = ProxyServer::SCHEME_DIRECT | |
| 746 ProxyServer::SCHEME_HTTP | ProxyServer::SCHEME_HTTPS | |
| 747 ProxyServer::SCHEME_SOCKS4 | |
| 748 ProxyServer::SCHEME_SOCKS5; |
| 749 if (session_->IsQuicEnabled()) |
| 750 supported_proxies |= ProxyServer::SCHEME_QUIC; |
| 751 proxy_info_.RemoveProxiesWithoutScheme(supported_proxies); |
| 752 |
| 753 if (proxy_info_.is_empty()) { |
| 754 // No proxies/direct to choose from. |
| 755 return ERR_NO_SUPPORTED_PROXIES; |
| 756 } |
| 757 |
| 758 next_state_ = STATE_CREATE_JOBS; |
| 759 return rv; |
| 760 } |
| 761 |
| 762 int HttpStreamFactoryImpl::JobController::DoCreateJobs() { |
699 DCHECK(!main_job_); | 763 DCHECK(!main_job_); |
700 DCHECK(!alternative_job_); | 764 DCHECK(!alternative_job_); |
701 HostPortPair destination(HostPortPair::FromURL(request_info.url)); | |
702 GURL origin_url = ApplyHostMappingRules(request_info.url, &destination); | |
703 | 765 |
704 main_job_.reset(job_factory_->CreateJob( | 766 HostPortPair destination(HostPortPair::FromURL(request_info_.url)); |
705 this, MAIN, session_, request_info, priority, server_ssl_config, | 767 GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination); |
706 proxy_ssl_config, destination, origin_url, enable_ip_based_pooling_, | |
707 net_log_.net_log())); | |
708 | 768 |
709 // Create an alternative job if alternative service is set up for this domain. | 769 // Create an alternative job if alternative service is set up for this domain. |
710 const AlternativeService alternative_service = | 770 const AlternativeService alternative_service = |
711 GetAlternativeServiceFor(request_info, delegate, stream_type); | 771 GetAlternativeServiceFor(request_info_, delegate_, stream_type_); |
712 | 772 |
| 773 if (is_preconnect_) { |
| 774 // Due to how the socket pools handle priorities and idle sockets, only IDLE |
| 775 // priority currently makes sense for preconnects. The priority for |
| 776 // preconnects is currently ignored (see RequestSocketsForPool()), but could |
| 777 // be used at some point for proxy resolution or something. |
| 778 main_job_.reset(job_factory_->CreateAltSvcJob( |
| 779 this, PRECONNECT, session_, request_info_, IDLE, proxy_info_, |
| 780 server_ssl_config_, proxy_ssl_config_, destination, origin_url, |
| 781 alternative_service, enable_ip_based_pooling_, session_->net_log())); |
| 782 main_job_->Preconnect(num_streams_); |
| 783 return OK; |
| 784 } |
| 785 main_job_.reset(job_factory_->CreateMainJob( |
| 786 this, MAIN, session_, request_info_, priority_, proxy_info_, |
| 787 server_ssl_config_, proxy_ssl_config_, destination, origin_url, |
| 788 enable_ip_based_pooling_, net_log_.net_log())); |
| 789 // Alternative Service can only be set for HTTPS requests while Alternative |
| 790 // Proxy is set for HTTP requests. |
713 if (alternative_service.protocol != kProtoUnknown) { | 791 if (alternative_service.protocol != kProtoUnknown) { |
714 // Never share connection with other jobs for FTP requests. | 792 // Never share connection with other jobs for FTP requests. |
715 DVLOG(1) << "Selected alternative service (host: " | 793 DVLOG(1) << "Selected alternative service (host: " |
716 << alternative_service.host_port_pair().host() | 794 << alternative_service.host_port_pair().host() |
717 << " port: " << alternative_service.host_port_pair().port() << ")"; | 795 << " port: " << alternative_service.host_port_pair().port() << ")"; |
718 | 796 |
719 DCHECK(!request_info.url.SchemeIs(url::kFtpScheme)); | 797 DCHECK(!request_info_.url.SchemeIs(url::kFtpScheme)); |
720 HostPortPair alternative_destination(alternative_service.host_port_pair()); | 798 HostPortPair alternative_destination(alternative_service.host_port_pair()); |
721 ignore_result( | 799 ignore_result( |
722 ApplyHostMappingRules(request_info.url, &alternative_destination)); | 800 ApplyHostMappingRules(request_info_.url, &alternative_destination)); |
723 | 801 |
724 alternative_job_.reset(job_factory_->CreateJob( | 802 alternative_job_.reset(job_factory_->CreateAltSvcJob( |
725 this, ALTERNATIVE, session_, request_info, priority, server_ssl_config, | 803 this, ALTERNATIVE, session_, request_info_, priority_, proxy_info_, |
726 proxy_ssl_config, alternative_destination, origin_url, | 804 server_ssl_config_, proxy_ssl_config_, alternative_destination, |
727 alternative_service, enable_ip_based_pooling_, net_log_.net_log())); | 805 origin_url, alternative_service, enable_ip_based_pooling_, |
| 806 net_log_.net_log())); |
728 | 807 |
729 main_job_is_blocked_ = true; | 808 main_job_is_blocked_ = true; |
730 alternative_job_->Start(request_->stream_type()); | 809 alternative_job_->Start(request_->stream_type()); |
731 } else { | 810 } else { |
732 can_start_alternative_proxy_job_ = true; | 811 ProxyServer alternative_proxy_server; |
| 812 if (ShouldCreateAlternativeProxyServerJob(proxy_info_, request_info_.url, |
| 813 &alternative_proxy_server)) { |
| 814 DCHECK(!main_job_is_blocked_); |
| 815 ProxyInfo alternative_proxy_info; |
| 816 alternative_proxy_info.UseProxyServer(alternative_proxy_server); |
| 817 |
| 818 alternative_job_.reset(job_factory_->CreateAltProxyJob( |
| 819 this, ALTERNATIVE, session_, request_info_, priority_, |
| 820 alternative_proxy_info, server_ssl_config_, proxy_ssl_config_, |
| 821 destination, origin_url, alternative_proxy_server, |
| 822 enable_ip_based_pooling_, net_log_.net_log())); |
| 823 |
| 824 can_start_alternative_proxy_job_ = false; |
| 825 main_job_is_blocked_ = true; |
| 826 alternative_job_->Start(request_->stream_type()); |
| 827 } |
733 } | 828 } |
734 // Even if |alternative_job| has already finished, it will not have notified | 829 // Even if |alternative_job| has already finished, it will not have notified |
735 // the request yet, since we defer that to the next iteration of the | 830 // the request yet, since we defer that to the next iteration of the |
736 // MessageLoop, so starting |main_job_| is always safe. | 831 // MessageLoop, so starting |main_job_| is always safe. |
737 main_job_->Start(request_->stream_type()); | 832 main_job_->Start(request_->stream_type()); |
| 833 return OK; |
738 } | 834 } |
739 | 835 |
740 void HttpStreamFactoryImpl::JobController::BindJob(Job* job) { | 836 void HttpStreamFactoryImpl::JobController::BindJob(Job* job) { |
741 DCHECK(request_); | 837 DCHECK(request_); |
742 DCHECK(job); | 838 DCHECK(job); |
743 DCHECK(job == alternative_job_.get() || job == main_job_.get()); | 839 DCHECK(job == alternative_job_.get() || job == main_job_.get()); |
744 DCHECK(!job_bound_); | 840 DCHECK(!job_bound_); |
745 DCHECK(!bound_job_); | 841 DCHECK(!bound_job_); |
746 | 842 |
747 job_bound_ = true; | 843 job_bound_ = true; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 } | 919 } |
824 | 920 |
825 void HttpStreamFactoryImpl::JobController::MarkRequestComplete( | 921 void HttpStreamFactoryImpl::JobController::MarkRequestComplete( |
826 bool was_alpn_negotiated, | 922 bool was_alpn_negotiated, |
827 NextProto negotiated_protocol, | 923 NextProto negotiated_protocol, |
828 bool using_spdy) { | 924 bool using_spdy) { |
829 if (request_) | 925 if (request_) |
830 request_->Complete(was_alpn_negotiated, negotiated_protocol, using_spdy); | 926 request_->Complete(was_alpn_negotiated, negotiated_protocol, using_spdy); |
831 } | 927 } |
832 | 928 |
833 void HttpStreamFactoryImpl::JobController::OnAlternativeJobFailed( | 929 void HttpStreamFactoryImpl::JobController::OnAlternativeServiceJobFailed( |
834 int net_error) { | 930 int net_error) { |
835 DCHECK_EQ(alternative_job_->job_type(), ALTERNATIVE); | 931 DCHECK_EQ(alternative_job_->job_type(), ALTERNATIVE); |
836 DCHECK_NE(OK, net_error); | 932 DCHECK_NE(OK, net_error); |
| 933 DCHECK_NE(kProtoUnknown, alternative_job_->alternative_service().protocol); |
837 | 934 |
838 alternative_job_net_error_ = net_error; | 935 alternative_job_net_error_ = net_error; |
839 | 936 failed_alternative_service_ = alternative_job_->alternative_service(); |
840 if (alternative_job_->alternative_proxy_server().is_valid()) { | |
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 | 937 |
848 if (IsJobOrphaned(alternative_job_.get())) { | 938 if (IsJobOrphaned(alternative_job_.get())) { |
849 // If |request_| is gone then it must have been successfully served by | 939 // If |request_| is gone then it must have been successfully served by |
850 // |main_job_|. | 940 // |main_job_|. |
851 // If |request_| is bound to a different job, then it is being | 941 // If |request_| is bound to a different job, then it is being |
852 // successfully serverd by the main job. | 942 // successfully serverd by the main job. |
853 ReportBrokenAlternativeService(); | 943 ReportBrokenAlternativeService(); |
854 } | 944 } |
855 } | 945 } |
856 | 946 |
| 947 void HttpStreamFactoryImpl::JobController::OnAlternativeProxyJobFailed( |
| 948 int net_error) { |
| 949 DCHECK_EQ(alternative_job_->job_type(), ALTERNATIVE); |
| 950 DCHECK_NE(OK, net_error); |
| 951 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); |
| 952 |
| 953 // Need to mark alt proxy as broken regardless whether the job is bound. |
| 954 ProxyDelegate* proxy_delegate = session_->params().proxy_delegate; |
| 955 if (proxy_delegate) { |
| 956 proxy_delegate->OnAlternativeProxyBroken( |
| 957 alternative_job_->alternative_proxy_server()); |
| 958 } |
| 959 } |
| 960 |
857 void HttpStreamFactoryImpl::JobController::ReportBrokenAlternativeService() { | 961 void HttpStreamFactoryImpl::JobController::ReportBrokenAlternativeService() { |
858 DCHECK(failed_alternative_service_.protocol != kProtoUnknown || | 962 DCHECK(failed_alternative_service_.protocol != kProtoUnknown); |
859 failed_alternative_proxy_server_.is_valid()); | |
860 DCHECK_NE(OK, alternative_job_net_error_); | 963 DCHECK_NE(OK, alternative_job_net_error_); |
861 | 964 |
862 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.AlternateServiceFailed", | 965 int error_to_report = alternative_job_net_error_; |
863 -alternative_job_net_error_); | 966 alternative_job_net_error_ = OK; |
| 967 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.AlternateServiceFailed", -error_to_report); |
864 | 968 |
865 if (alternative_job_net_error_ == ERR_NETWORK_CHANGED || | 969 if (error_to_report == ERR_NETWORK_CHANGED || |
866 alternative_job_net_error_ == ERR_INTERNET_DISCONNECTED) { | 970 error_to_report == ERR_INTERNET_DISCONNECTED) { |
867 // No need to mark alternative service or proxy as broken. | 971 // No need to mark alternative service or proxy as broken. |
868 return; | 972 return; |
869 } | 973 } |
870 | 974 |
871 if (failed_alternative_proxy_server_.is_valid()) { | 975 HistogramBrokenAlternateProtocolLocation( |
872 ProxyDelegate* proxy_delegate = session_->params().proxy_delegate; | 976 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); |
873 if (proxy_delegate) { | 977 session_->http_server_properties()->MarkAlternativeServiceBroken( |
874 proxy_delegate->OnAlternativeProxyBroken( | 978 failed_alternative_service_); |
875 failed_alternative_proxy_server_); | |
876 } | |
877 } else { | |
878 HistogramBrokenAlternateProtocolLocation( | |
879 BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_ALT); | |
880 session_->http_server_properties()->MarkAlternativeServiceBroken( | |
881 failed_alternative_service_); | |
882 } | |
883 } | 979 } |
884 | 980 |
885 void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() { | 981 void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() { |
886 if (!request_ && !main_job_ && !alternative_job_) { | 982 if (!request_ && !main_job_ && !alternative_job_) { |
887 DCHECK(!bound_job_); | 983 DCHECK(!bound_job_); |
888 factory_->OnJobControllerComplete(this); | 984 factory_->OnJobControllerComplete(this); |
889 } | 985 } |
890 } | 986 } |
891 | 987 |
| 988 void HttpStreamFactoryImpl::JobController::NotifyRequestFailed(int rv) { |
| 989 if (!request_) |
| 990 return; |
| 991 request_->OnStreamFailed(rv, server_ssl_config_); |
| 992 } |
| 993 |
892 GURL HttpStreamFactoryImpl::JobController::ApplyHostMappingRules( | 994 GURL HttpStreamFactoryImpl::JobController::ApplyHostMappingRules( |
893 const GURL& url, | 995 const GURL& url, |
894 HostPortPair* endpoint) { | 996 HostPortPair* endpoint) { |
895 const HostMappingRules* mapping_rules = session_->params().host_mapping_rules; | 997 const HostMappingRules* mapping_rules = session_->params().host_mapping_rules; |
896 if (mapping_rules && mapping_rules->RewriteHost(endpoint)) { | 998 if (mapping_rules && mapping_rules->RewriteHost(endpoint)) { |
897 url::Replacements<char> replacements; | 999 url::Replacements<char> replacements; |
898 const std::string port_str = base::UintToString(endpoint->port()); | 1000 const std::string port_str = base::UintToString(endpoint->port()); |
899 replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size())); | 1001 replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size())); |
900 replacements.SetHost(endpoint->host().c_str(), | 1002 replacements.SetHost(endpoint->host().c_str(), |
901 url::Component(0, endpoint->host().size())); | 1003 url::Component(0, endpoint->host().size())); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 | 1127 |
1026 // Ask delegate to mark QUIC as broken for the origin. | 1128 // Ask delegate to mark QUIC as broken for the origin. |
1027 if (quic_advertised && quic_all_broken && delegate != nullptr) | 1129 if (quic_advertised && quic_all_broken && delegate != nullptr) |
1028 delegate->OnQuicBroken(); | 1130 delegate->OnQuicBroken(); |
1029 | 1131 |
1030 return first_alternative_service; | 1132 return first_alternative_service; |
1031 } | 1133 } |
1032 | 1134 |
1033 bool HttpStreamFactoryImpl::JobController:: | 1135 bool HttpStreamFactoryImpl::JobController:: |
1034 ShouldCreateAlternativeProxyServerJob( | 1136 ShouldCreateAlternativeProxyServerJob( |
1035 Job* job, | |
1036 const ProxyInfo& proxy_info, | 1137 const ProxyInfo& proxy_info, |
1037 const GURL& url, | 1138 const GURL& url, |
1038 ProxyServer* alternative_proxy_server) const { | 1139 ProxyServer* alternative_proxy_server) const { |
1039 DCHECK(!alternative_proxy_server->is_valid()); | 1140 DCHECK(!alternative_proxy_server->is_valid()); |
1040 | 1141 |
1041 if (!enable_alternative_services_) | 1142 if (!enable_alternative_services_) |
1042 return false; | 1143 return false; |
1043 | 1144 |
1044 if (!can_start_alternative_proxy_job_) { | 1145 if (!can_start_alternative_proxy_job_) { |
1045 // Either an alternative service job or an alternative proxy server job has | 1146 // Either an alternative service job or an alternative proxy server job has |
1046 // already been started. | 1147 // already been started. |
1047 return false; | 1148 return false; |
1048 } | 1149 } |
1049 | 1150 |
1050 if (job->job_type() == ALTERNATIVE) { | |
1051 // If |job| is using alternative service, then alternative proxy server | |
1052 // should not be used. | |
1053 return false; | |
1054 } | |
1055 | |
1056 if (is_preconnect_ || job->job_type() == PRECONNECT) { | |
1057 // Preconnects should be fetched using only the main job to keep the | |
1058 // resource utilization down. | |
1059 return false; | |
1060 } | |
1061 | |
1062 if (proxy_info.is_empty() || proxy_info.is_direct() || proxy_info.is_quic()) { | 1151 if (proxy_info.is_empty() || proxy_info.is_direct() || proxy_info.is_quic()) { |
1063 // Alternative proxy server job can be created only if |job| fetches the | 1152 // Alternative proxy server job can be created only if |job| fetches the |
1064 // |request_| through a non-QUIC proxy. | 1153 // |request_| through a non-QUIC proxy. |
1065 return false; | 1154 return false; |
1066 } | 1155 } |
1067 | 1156 |
1068 if (!url.SchemeIs(url::kHttpScheme)) { | 1157 if (!url.SchemeIs(url::kHttpScheme)) { |
1069 // Only HTTP URLs can be fetched through alternative proxy server, since the | 1158 // Only HTTP URLs can be fetched through alternative proxy server, since the |
1070 // alternative proxy server may not support fetching of URLs with other | 1159 // alternative proxy server may not support fetching of URLs with other |
1071 // schemes. | 1160 // schemes. |
1072 return false; | 1161 return false; |
1073 } | 1162 } |
1074 | 1163 |
1075 ProxyDelegate* proxy_delegate = session_->params().proxy_delegate; | 1164 ProxyDelegate* proxy_delegate = session_->params().proxy_delegate; |
1076 if (!proxy_delegate) | 1165 if (!proxy_delegate) |
1077 return false; | 1166 return false; |
1078 | |
1079 proxy_delegate->GetAlternativeProxy(url, proxy_info.proxy_server(), | 1167 proxy_delegate->GetAlternativeProxy(url, proxy_info.proxy_server(), |
1080 alternative_proxy_server); | 1168 alternative_proxy_server); |
1081 | 1169 |
1082 if (!alternative_proxy_server->is_valid()) | 1170 if (!alternative_proxy_server->is_valid()) |
1083 return false; | 1171 return false; |
1084 | 1172 |
1085 DCHECK(!(*alternative_proxy_server == proxy_info.proxy_server())); | 1173 DCHECK(!(*alternative_proxy_server == proxy_info.proxy_server())); |
1086 | 1174 |
1087 if (!alternative_proxy_server->is_https() && | 1175 if (!alternative_proxy_server->is_https() && |
1088 !alternative_proxy_server->is_quic()) { | 1176 !alternative_proxy_server->is_quic()) { |
(...skipping 27 matching lines...) Expand all Loading... |
1116 if (job->using_existing_quic_session()) { | 1204 if (job->using_existing_quic_session()) { |
1117 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE, | 1205 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE, |
1118 proxy_server_used); | 1206 proxy_server_used); |
1119 return; | 1207 return; |
1120 } | 1208 } |
1121 | 1209 |
1122 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE, | 1210 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE, |
1123 proxy_server_used); | 1211 proxy_server_used); |
1124 } | 1212 } |
1125 | 1213 |
1126 void HttpStreamFactoryImpl::JobController::StartAlternativeProxyServerJob() { | |
1127 if (!alternative_job_ || !request_) | |
1128 return; | |
1129 DCHECK(alternative_job_->alternative_proxy_server().is_valid()); | |
1130 alternative_job_->Start(request_->stream_type()); | |
1131 } | |
1132 | |
1133 bool HttpStreamFactoryImpl::JobController::IsJobOrphaned(Job* job) const { | 1214 bool HttpStreamFactoryImpl::JobController::IsJobOrphaned(Job* job) const { |
1134 return !request_ || (job_bound_ && bound_job_ != job); | 1215 return !request_ || (job_bound_ && bound_job_ != job); |
1135 } | 1216 } |
1136 | 1217 |
| 1218 int HttpStreamFactoryImpl::JobController::ReconsiderProxyAfterError(Job* job, |
| 1219 int error) { |
| 1220 // ReconsiderProxyAfterError() should only be called when the last job fails. |
| 1221 DCHECK(!(alternative_job_ && main_job_)); |
| 1222 DCHECK(!pac_request_); |
| 1223 DCHECK(session_); |
| 1224 |
| 1225 if (!job->should_reconsider_proxy()) |
| 1226 return error; |
| 1227 |
| 1228 DCHECK(!job->alternative_proxy_server().is_valid()); |
| 1229 |
| 1230 // Do not bypass non-QUIC proxy on ERR_MSG_TOO_BIG. |
| 1231 if (!proxy_info_.is_quic() && error == ERR_MSG_TOO_BIG) |
| 1232 return error; |
| 1233 |
| 1234 if (request_info_.load_flags & LOAD_BYPASS_PROXY) |
| 1235 return error; |
| 1236 |
| 1237 if (proxy_info_.is_https() && proxy_ssl_config_.send_client_cert) { |
| 1238 session_->ssl_client_auth_cache()->Remove( |
| 1239 proxy_info_.proxy_server().host_port_pair()); |
| 1240 } |
| 1241 |
| 1242 HostPortPair destination(HostPortPair::FromURL(request_info_.url)); |
| 1243 GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination); |
| 1244 |
| 1245 int rv = session_->proxy_service()->ReconsiderProxyAfterError( |
| 1246 origin_url, request_info_.method, error, &proxy_info_, io_callback_, |
| 1247 &pac_request_, session_->params().proxy_delegate, net_log_); |
| 1248 if (rv == OK || rv == ERR_IO_PENDING) { |
| 1249 RemoveRequestFromSpdySessionRequestMap(); |
| 1250 // Abandon all Jobs and start over. |
| 1251 job_bound_ = false; |
| 1252 bound_job_ = nullptr; |
| 1253 alternative_job_.reset(); |
| 1254 main_job_.reset(); |
| 1255 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; |
| 1256 } else { |
| 1257 // If ReconsiderProxyAfterError() failed synchronously, it means |
| 1258 // there was nothing left to fall-back to, so fail the transaction |
| 1259 // with the last connection error we got. |
| 1260 // TODO(eroman): This is a confusing contract, make it more obvious. |
| 1261 rv = error; |
| 1262 } |
| 1263 return rv; |
| 1264 } |
| 1265 |
1137 } // namespace net | 1266 } // namespace net |
OLD | NEW |