OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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.h" | 5 #include "net/http/http_stream_factory_impl_job.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
12 #include "base/feature_list.h" | 12 #include "base/feature_list.h" |
13 #include "base/location.h" | 13 #include "base/location.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/memory/ptr_util.h" | |
16 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
17 #include "base/metrics/sparse_histogram.h" | 16 #include "base/metrics/sparse_histogram.h" |
18 #include "base/profiler/scoped_tracker.h" | 17 #include "base/profiler/scoped_tracker.h" |
19 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
20 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
21 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
22 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
23 #include "base/threading/thread_task_runner_handle.h" | 22 #include "base/threading/thread_task_runner_handle.h" |
24 #include "base/trace_event/trace_event.h" | 23 #include "base/trace_event/trace_event.h" |
25 #include "base/values.h" | 24 #include "base/values.h" |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 // stream. | 141 // stream. |
143 std::unique_ptr<base::Value> NetLogHttpStreamProtoCallback( | 142 std::unique_ptr<base::Value> NetLogHttpStreamProtoCallback( |
144 NextProto negotiated_protocol, | 143 NextProto negotiated_protocol, |
145 NetLogCaptureMode /* capture_mode */) { | 144 NetLogCaptureMode /* capture_mode */) { |
146 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 145 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
147 | 146 |
148 dict->SetString("proto", NextProtoToString(negotiated_protocol)); | 147 dict->SetString("proto", NextProtoToString(negotiated_protocol)); |
149 return std::move(dict); | 148 return std::move(dict); |
150 } | 149 } |
151 | 150 |
| 151 // Returns parameters associated with the proxy resolution. |
| 152 std::unique_ptr<base::Value> NetLogHttpStreamJobProxyServerResolved( |
| 153 const ProxyServer& proxy_server, |
| 154 NetLogCaptureMode /* capture_mode */) { |
| 155 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 156 |
| 157 dict->SetString("proxy_server", proxy_server.is_valid() |
| 158 ? proxy_server.ToPacString() |
| 159 : std::string()); |
| 160 return std::move(dict); |
| 161 } |
| 162 |
152 HttpStreamFactoryImpl::Job::Job(Delegate* delegate, | 163 HttpStreamFactoryImpl::Job::Job(Delegate* delegate, |
153 JobType job_type, | 164 JobType job_type, |
154 HttpNetworkSession* session, | 165 HttpNetworkSession* session, |
155 const HttpRequestInfo& request_info, | 166 const HttpRequestInfo& request_info, |
156 RequestPriority priority, | 167 RequestPriority priority, |
157 const ProxyInfo& proxy_info, | |
158 const SSLConfig& server_ssl_config, | 168 const SSLConfig& server_ssl_config, |
159 const SSLConfig& proxy_ssl_config, | 169 const SSLConfig& proxy_ssl_config, |
160 HostPortPair destination, | 170 HostPortPair destination, |
161 GURL origin_url, | 171 GURL origin_url, |
162 bool enable_ip_based_pooling, | 172 bool enable_ip_based_pooling, |
163 NetLog* net_log) | 173 NetLog* net_log) |
164 : Job(delegate, | 174 : Job(delegate, |
165 job_type, | 175 job_type, |
166 session, | 176 session, |
167 request_info, | 177 request_info, |
168 priority, | 178 priority, |
169 proxy_info, | |
170 server_ssl_config, | 179 server_ssl_config, |
171 proxy_ssl_config, | 180 proxy_ssl_config, |
172 destination, | 181 destination, |
173 origin_url, | 182 origin_url, |
174 AlternativeService(), | 183 AlternativeService(), |
175 ProxyServer(), | 184 ProxyServer(), |
176 enable_ip_based_pooling, | 185 enable_ip_based_pooling, |
177 net_log) {} | 186 net_log) {} |
178 | 187 |
179 HttpStreamFactoryImpl::Job::Job(Delegate* delegate, | 188 HttpStreamFactoryImpl::Job::Job(Delegate* delegate, |
180 JobType job_type, | 189 JobType job_type, |
181 HttpNetworkSession* session, | 190 HttpNetworkSession* session, |
182 const HttpRequestInfo& request_info, | 191 const HttpRequestInfo& request_info, |
183 RequestPriority priority, | 192 RequestPriority priority, |
184 const ProxyInfo& proxy_info, | |
185 const SSLConfig& server_ssl_config, | 193 const SSLConfig& server_ssl_config, |
186 const SSLConfig& proxy_ssl_config, | 194 const SSLConfig& proxy_ssl_config, |
187 HostPortPair destination, | 195 HostPortPair destination, |
188 GURL origin_url, | 196 GURL origin_url, |
189 AlternativeService alternative_service, | 197 AlternativeService alternative_service, |
190 const ProxyServer& alternative_proxy_server, | 198 const ProxyServer& alternative_proxy_server, |
191 bool enable_ip_based_pooling, | 199 bool enable_ip_based_pooling, |
192 NetLog* net_log) | 200 NetLog* net_log) |
193 : request_info_(request_info), | 201 : request_info_(request_info), |
194 priority_(priority), | 202 priority_(priority), |
195 proxy_info_(proxy_info), | |
196 server_ssl_config_(server_ssl_config), | 203 server_ssl_config_(server_ssl_config), |
197 proxy_ssl_config_(proxy_ssl_config), | 204 proxy_ssl_config_(proxy_ssl_config), |
198 net_log_( | 205 net_log_( |
199 NetLogWithSource::Make(net_log, NetLogSourceType::HTTP_STREAM_JOB)), | 206 NetLogWithSource::Make(net_log, NetLogSourceType::HTTP_STREAM_JOB)), |
200 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), | 207 io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))), |
201 connection_(new ClientSocketHandle), | 208 connection_(new ClientSocketHandle), |
202 session_(session), | 209 session_(session), |
203 state_(STATE_NONE), | 210 state_(STATE_NONE), |
204 next_state_(STATE_NONE), | 211 next_state_(STATE_NONE), |
| 212 pac_request_(NULL), |
205 destination_(destination), | 213 destination_(destination), |
206 origin_url_(origin_url), | 214 origin_url_(origin_url), |
207 alternative_service_(alternative_service), | 215 alternative_service_(alternative_service), |
208 alternative_proxy_server_(alternative_proxy_server), | 216 alternative_proxy_server_(alternative_proxy_server), |
209 enable_ip_based_pooling_(enable_ip_based_pooling), | 217 enable_ip_based_pooling_(enable_ip_based_pooling), |
210 delegate_(delegate), | 218 delegate_(delegate), |
211 job_type_(job_type), | 219 job_type_(job_type), |
212 using_ssl_(origin_url_.SchemeIs(url::kHttpsScheme) || | 220 using_ssl_(origin_url_.SchemeIs(url::kHttpsScheme) || |
213 origin_url_.SchemeIs(url::kWssScheme)), | 221 origin_url_.SchemeIs(url::kWssScheme)), |
214 using_spdy_(false), | 222 using_spdy_(false), |
215 using_quic_(false), | 223 using_quic_(false), |
216 should_reconsider_proxy_(false), | |
217 quic_request_(session_->quic_stream_factory()), | 224 quic_request_(session_->quic_stream_factory()), |
218 using_existing_quic_session_(false), | 225 using_existing_quic_session_(false), |
219 establishing_tunnel_(false), | 226 establishing_tunnel_(false), |
220 was_alpn_negotiated_(false), | 227 was_alpn_negotiated_(false), |
221 negotiated_protocol_(kProtoUnknown), | 228 negotiated_protocol_(kProtoUnknown), |
222 num_streams_(0), | 229 num_streams_(0), |
223 spdy_session_direct_(false), | 230 spdy_session_direct_(false), |
224 stream_type_(HttpStreamRequest::BIDIRECTIONAL_STREAM), | 231 stream_type_(HttpStreamRequest::BIDIRECTIONAL_STREAM), |
225 ptr_factory_(this) { | 232 ptr_factory_(this) { |
226 DCHECK(session); | 233 DCHECK(session); |
(...skipping 28 matching lines...) Expand all Loading... |
255 net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB); | 262 net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB); |
256 | 263 |
257 // When we're in a partially constructed state, waiting for the user to | 264 // When we're in a partially constructed state, waiting for the user to |
258 // provide certificate handling information or authentication, we can't reuse | 265 // provide certificate handling information or authentication, we can't reuse |
259 // this stream at all. | 266 // this stream at all. |
260 if (next_state_ == STATE_WAITING_USER_ACTION) { | 267 if (next_state_ == STATE_WAITING_USER_ACTION) { |
261 connection_->socket()->Disconnect(); | 268 connection_->socket()->Disconnect(); |
262 connection_.reset(); | 269 connection_.reset(); |
263 } | 270 } |
264 | 271 |
| 272 if (pac_request_) |
| 273 session_->proxy_service()->CancelPacRequest(pac_request_); |
| 274 |
265 // The stream could be in a partial state. It is not reusable. | 275 // The stream could be in a partial state. It is not reusable. |
266 if (stream_.get() && next_state_ != STATE_DONE) | 276 if (stream_.get() && next_state_ != STATE_DONE) |
267 stream_->Close(true /* not reusable */); | 277 stream_->Close(true /* not reusable */); |
268 } | 278 } |
269 | 279 |
270 void HttpStreamFactoryImpl::Job::Start( | 280 void HttpStreamFactoryImpl::Job::Start( |
271 HttpStreamRequest::StreamType stream_type) { | 281 HttpStreamRequest::StreamType stream_type) { |
272 stream_type_ = stream_type; | 282 stream_type_ = stream_type; |
273 StartInternal(); | 283 StartInternal(); |
274 } | 284 } |
(...skipping 24 matching lines...) Expand all Loading... |
299 int HttpStreamFactoryImpl::Job::RestartTunnelWithProxyAuth() { | 309 int HttpStreamFactoryImpl::Job::RestartTunnelWithProxyAuth() { |
300 DCHECK(establishing_tunnel_); | 310 DCHECK(establishing_tunnel_); |
301 next_state_ = STATE_RESTART_TUNNEL_AUTH; | 311 next_state_ = STATE_RESTART_TUNNEL_AUTH; |
302 stream_.reset(); | 312 stream_.reset(); |
303 RunLoop(OK); | 313 RunLoop(OK); |
304 return ERR_IO_PENDING; | 314 return ERR_IO_PENDING; |
305 } | 315 } |
306 | 316 |
307 LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { | 317 LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { |
308 switch (next_state_) { | 318 switch (next_state_) { |
| 319 case STATE_RESOLVE_PROXY_COMPLETE: |
| 320 return session_->proxy_service()->GetLoadState(pac_request_); |
309 case STATE_INIT_CONNECTION_COMPLETE: | 321 case STATE_INIT_CONNECTION_COMPLETE: |
310 case STATE_CREATE_STREAM_COMPLETE: | 322 case STATE_CREATE_STREAM_COMPLETE: |
311 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); | 323 return using_quic_ ? LOAD_STATE_CONNECTING : connection_->GetLoadState(); |
312 default: | 324 default: |
313 return LOAD_STATE_IDLE; | 325 return LOAD_STATE_IDLE; |
314 } | 326 } |
315 } | 327 } |
316 | 328 |
317 void HttpStreamFactoryImpl::Job::Resume() { | 329 void HttpStreamFactoryImpl::Job::Resume() { |
318 DCHECK_EQ(job_type_, MAIN); | 330 DCHECK_EQ(job_type_, MAIN); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 } | 407 } |
396 | 408 |
397 SpdySessionKey HttpStreamFactoryImpl::Job::GetSpdySessionKey() const { | 409 SpdySessionKey HttpStreamFactoryImpl::Job::GetSpdySessionKey() const { |
398 // In the case that we're using an HTTPS proxy for an HTTP url, | 410 // In the case that we're using an HTTPS proxy for an HTTP url, |
399 // we look for a SPDY session *to* the proxy, instead of to the | 411 // we look for a SPDY session *to* the proxy, instead of to the |
400 // origin server. | 412 // origin server. |
401 if (IsHttpsProxyAndHttpUrl()) { | 413 if (IsHttpsProxyAndHttpUrl()) { |
402 return SpdySessionKey(proxy_info_.proxy_server().host_port_pair(), | 414 return SpdySessionKey(proxy_info_.proxy_server().host_port_pair(), |
403 ProxyServer::Direct(), PRIVACY_MODE_DISABLED); | 415 ProxyServer::Direct(), PRIVACY_MODE_DISABLED); |
404 } | 416 } |
405 return SpdySessionKey(HostPortPair::FromURL(origin_url_), | 417 return SpdySessionKey(destination_, proxy_info_.proxy_server(), |
406 proxy_info_.proxy_server(), request_info_.privacy_mode); | 418 request_info_.privacy_mode); |
407 } | 419 } |
408 | 420 |
409 bool HttpStreamFactoryImpl::Job::CanUseExistingSpdySession() const { | 421 bool HttpStreamFactoryImpl::Job::CanUseExistingSpdySession() const { |
410 // We need to make sure that if a spdy session was created for | 422 // We need to make sure that if a spdy session was created for |
411 // https://somehost/ that we don't use that session for http://somehost:443/. | 423 // https://somehost/ that we don't use that session for http://somehost:443/. |
412 // The only time we can use an existing session is if the request URL is | 424 // The only time we can use an existing session is if the request URL is |
413 // https (the normal case) or if we're connection to a SPDY proxy. | 425 // https (the normal case) or if we're connection to a SPDY proxy. |
414 // https://crbug.com/133176 | 426 // https://crbug.com/133176 |
415 // TODO(ricea): Add "wss" back to this list when SPDY WebSocket support is | 427 // TODO(ricea): Add "wss" back to this list when SPDY WebSocket support is |
416 // working. | 428 // working. |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 do { | 681 do { |
670 State state = next_state_; | 682 State state = next_state_; |
671 // Added to investigate crbug.com/711721. | 683 // Added to investigate crbug.com/711721. |
672 state_ = state; | 684 state_ = state; |
673 next_state_ = STATE_NONE; | 685 next_state_ = STATE_NONE; |
674 switch (state) { | 686 switch (state) { |
675 case STATE_START: | 687 case STATE_START: |
676 DCHECK_EQ(OK, rv); | 688 DCHECK_EQ(OK, rv); |
677 rv = DoStart(); | 689 rv = DoStart(); |
678 break; | 690 break; |
| 691 case STATE_RESOLVE_PROXY: |
| 692 DCHECK_EQ(OK, rv); |
| 693 rv = DoResolveProxy(); |
| 694 break; |
| 695 case STATE_RESOLVE_PROXY_COMPLETE: |
| 696 rv = DoResolveProxyComplete(rv); |
| 697 break; |
679 case STATE_WAIT: | 698 case STATE_WAIT: |
680 DCHECK_EQ(OK, rv); | 699 DCHECK_EQ(OK, rv); |
681 rv = DoWait(); | 700 rv = DoWait(); |
682 break; | 701 break; |
683 case STATE_WAIT_COMPLETE: | 702 case STATE_WAIT_COMPLETE: |
684 rv = DoWaitComplete(rv); | 703 rv = DoWaitComplete(rv); |
685 break; | 704 break; |
686 case STATE_INIT_CONNECTION: | 705 case STATE_INIT_CONNECTION: |
687 DCHECK_EQ(OK, rv); | 706 DCHECK_EQ(OK, rv); |
688 rv = DoInitConnection(); | 707 rv = DoInitConnection(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 net_log->AddEvent(NetLogEventType::HTTP_STREAM_REQUEST_STARTED_JOB, | 754 net_log->AddEvent(NetLogEventType::HTTP_STREAM_REQUEST_STARTED_JOB, |
736 net_log_.source().ToEventParametersCallback()); | 755 net_log_.source().ToEventParametersCallback()); |
737 } | 756 } |
738 | 757 |
739 // Don't connect to restricted ports. | 758 // Don't connect to restricted ports. |
740 if (!IsPortAllowedForScheme(destination_.port(), | 759 if (!IsPortAllowedForScheme(destination_.port(), |
741 request_info_.url.scheme())) { | 760 request_info_.url.scheme())) { |
742 return ERR_UNSAFE_PORT; | 761 return ERR_UNSAFE_PORT; |
743 } | 762 } |
744 | 763 |
745 next_state_ = STATE_WAIT; | 764 next_state_ = STATE_RESOLVE_PROXY; |
746 return OK; | 765 return OK; |
747 } | 766 } |
748 | 767 |
| 768 int HttpStreamFactoryImpl::Job::DoResolveProxy() { |
| 769 DCHECK(!pac_request_); |
| 770 DCHECK(session_); |
| 771 |
| 772 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; |
| 773 |
| 774 if (request_info_.load_flags & LOAD_BYPASS_PROXY) { |
| 775 proxy_info_.UseDirect(); |
| 776 return OK; |
| 777 } |
| 778 |
| 779 // If an alternative proxy server was provided, use that. |
| 780 if (alternative_proxy_server_.is_valid()) { |
| 781 proxy_info_.UseProxyServer(alternative_proxy_server_); |
| 782 return OK; |
| 783 } |
| 784 |
| 785 return session_->proxy_service()->ResolveProxy( |
| 786 origin_url_, request_info_.method, &proxy_info_, io_callback_, |
| 787 &pac_request_, session_->params().proxy_delegate, net_log_); |
| 788 } |
| 789 |
| 790 int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) { |
| 791 pac_request_ = NULL; |
| 792 |
| 793 net_log_.AddEvent( |
| 794 NetLogEventType::HTTP_STREAM_JOB_PROXY_SERVER_RESOLVED, |
| 795 base::Bind( |
| 796 &NetLogHttpStreamJobProxyServerResolved, |
| 797 proxy_info_.is_empty() ? ProxyServer() : proxy_info_.proxy_server())); |
| 798 |
| 799 if (result == OK) { |
| 800 // Remove unsupported proxies from the list. |
| 801 int supported_proxies = |
| 802 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP | |
| 803 ProxyServer::SCHEME_HTTPS | ProxyServer::SCHEME_SOCKS4 | |
| 804 ProxyServer::SCHEME_SOCKS5; |
| 805 |
| 806 if (session_->IsQuicEnabled()) |
| 807 supported_proxies |= ProxyServer::SCHEME_QUIC; |
| 808 |
| 809 proxy_info_.RemoveProxiesWithoutScheme(supported_proxies); |
| 810 |
| 811 if (proxy_info_.is_empty()) { |
| 812 // No proxies/direct to choose from. This happens when we don't support |
| 813 // any of the proxies in the returned list. |
| 814 result = ERR_NO_SUPPORTED_PROXIES; |
| 815 } else if (using_quic_ && |
| 816 (!proxy_info_.is_quic() && !proxy_info_.is_direct())) { |
| 817 // QUIC can not be spoken to non-QUIC proxies. This error should not be |
| 818 // user visible, because the non-alternative Job should be resumed. |
| 819 result = ERR_NO_SUPPORTED_PROXIES; |
| 820 } |
| 821 } |
| 822 |
| 823 if (result != OK) { |
| 824 return result; |
| 825 } |
| 826 |
| 827 next_state_ = STATE_WAIT; |
| 828 |
| 829 delegate_->OnResolveProxyComplete(this, request_info_, priority_, |
| 830 server_ssl_config_, proxy_ssl_config_, |
| 831 stream_type_); |
| 832 |
| 833 return OK; |
| 834 } |
| 835 |
749 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { | 836 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { |
750 return session_->IsQuicEnabled() && | 837 return session_->IsQuicEnabled() && |
751 (base::ContainsKey(session_->params().origins_to_force_quic_on, | 838 (base::ContainsKey(session_->params().origins_to_force_quic_on, |
752 HostPortPair()) || | 839 HostPortPair()) || |
753 base::ContainsKey(session_->params().origins_to_force_quic_on, | 840 base::ContainsKey(session_->params().origins_to_force_quic_on, |
754 destination_)) && | 841 destination_)) && |
755 proxy_info_.is_direct() && origin_url_.SchemeIs(url::kHttpsScheme); | 842 proxy_info_.is_direct() && origin_url_.SchemeIs(url::kHttpsScheme); |
756 } | 843 } |
757 | 844 |
758 int HttpStreamFactoryImpl::Job::DoWait() { | 845 int HttpStreamFactoryImpl::Job::DoWait() { |
(...skipping 22 matching lines...) Expand all Loading... |
781 | 868 |
782 return result; | 869 return result; |
783 } | 870 } |
784 | 871 |
785 int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() { | 872 int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() { |
786 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. | 873 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462812 is fixed. |
787 tracked_objects::ScopedTracker tracking_profile( | 874 tracked_objects::ScopedTracker tracking_profile( |
788 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 875 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
789 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); | 876 "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); |
790 DCHECK(!connection_->is_initialized()); | 877 DCHECK(!connection_->is_initialized()); |
791 | |
792 if (using_quic_ && !proxy_info_.is_quic() && !proxy_info_.is_direct()) { | |
793 // QUIC can not be spoken to non-QUIC proxies. This error should not be | |
794 // user visible, because the non-alternative Job should be resumed. | |
795 return ERR_NO_SUPPORTED_PROXIES; | |
796 } | |
797 | |
798 DCHECK(proxy_info_.proxy_server().is_valid()); | 878 DCHECK(proxy_info_.proxy_server().is_valid()); |
799 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 879 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
800 | 880 |
801 if (delegate_->OnInitConnection(proxy_info_)) { | 881 if (delegate_->OnInitConnection(proxy_info_)) { |
802 // Return since the connection initialization can be skipped. | 882 // Return since the connection initialization can be skipped. |
803 return OK; | 883 return OK; |
804 } | 884 } |
805 | 885 |
806 using_spdy_ = false; | 886 using_spdy_ = false; |
807 | 887 |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1059 // Quic session is closed before stream can be created. | 1139 // Quic session is closed before stream can be created. |
1060 return ERR_CONNECTION_CLOSED; | 1140 return ERR_CONNECTION_CLOSED; |
1061 } | 1141 } |
1062 } | 1142 } |
1063 next_state_ = STATE_NONE; | 1143 next_state_ = STATE_NONE; |
1064 return OK; | 1144 return OK; |
1065 } | 1145 } |
1066 | 1146 |
1067 if (result < 0 && !ssl_started) | 1147 if (result < 0 && !ssl_started) |
1068 return ReconsiderProxyAfterError(result); | 1148 return ReconsiderProxyAfterError(result); |
1069 | |
1070 establishing_tunnel_ = false; | 1149 establishing_tunnel_ = false; |
1071 | 1150 |
1072 // Handle SSL errors below. | 1151 // Handle SSL errors below. |
1073 if (using_ssl_) { | 1152 if (using_ssl_) { |
1074 DCHECK(ssl_started); | 1153 DCHECK(ssl_started); |
1075 if (IsCertificateError(result)) { | 1154 if (IsCertificateError(result)) { |
1076 result = HandleCertificateError(result); | 1155 result = HandleCertificateError(result); |
1077 if (result == OK && !connection_->socket()->IsConnectedAndIdle()) { | 1156 if (result == OK && !connection_->socket()->IsConnectedAndIdle()) { |
1078 ReturnToStateInitConnection(true /* close connection */); | 1157 ReturnToStateInitConnection(true /* close connection */); |
1079 return result; | 1158 return result; |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 | 1406 |
1328 if (request_info_.load_flags & LOAD_VERIFY_EV_CERT) | 1407 if (request_info_.load_flags & LOAD_VERIFY_EV_CERT) |
1329 ssl_config->verify_ev_cert = true; | 1408 ssl_config->verify_ev_cert = true; |
1330 | 1409 |
1331 // Disable Channel ID if privacy mode is enabled. | 1410 // Disable Channel ID if privacy mode is enabled. |
1332 if (request_info_.privacy_mode == PRIVACY_MODE_ENABLED) | 1411 if (request_info_.privacy_mode == PRIVACY_MODE_ENABLED) |
1333 ssl_config->channel_id_enabled = false; | 1412 ssl_config->channel_id_enabled = false; |
1334 } | 1413 } |
1335 | 1414 |
1336 int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) { | 1415 int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) { |
| 1416 DCHECK(!pac_request_); |
| 1417 DCHECK(session_); |
| 1418 |
| 1419 // A failure to resolve the hostname or any error related to establishing a |
| 1420 // TCP connection could be grounds for trying a new proxy configuration. |
| 1421 // |
| 1422 // Why do this when a hostname cannot be resolved? Some URLs only make sense |
| 1423 // to proxy servers. The hostname in those URLs might fail to resolve if we |
| 1424 // are still using a non-proxy config. We need to check if a proxy config |
| 1425 // now exists that corresponds to a proxy server that could load the URL. |
| 1426 // |
1337 switch (error) { | 1427 switch (error) { |
1338 case ERR_PROXY_CONNECTION_FAILED: | 1428 case ERR_PROXY_CONNECTION_FAILED: |
1339 case ERR_NAME_NOT_RESOLVED: | 1429 case ERR_NAME_NOT_RESOLVED: |
1340 case ERR_INTERNET_DISCONNECTED: | 1430 case ERR_INTERNET_DISCONNECTED: |
1341 case ERR_ADDRESS_UNREACHABLE: | 1431 case ERR_ADDRESS_UNREACHABLE: |
1342 case ERR_CONNECTION_CLOSED: | 1432 case ERR_CONNECTION_CLOSED: |
1343 case ERR_CONNECTION_TIMED_OUT: | 1433 case ERR_CONNECTION_TIMED_OUT: |
1344 case ERR_CONNECTION_RESET: | 1434 case ERR_CONNECTION_RESET: |
1345 case ERR_CONNECTION_REFUSED: | 1435 case ERR_CONNECTION_REFUSED: |
1346 case ERR_CONNECTION_ABORTED: | 1436 case ERR_CONNECTION_ABORTED: |
(...skipping 18 matching lines...) Expand all Loading... |
1365 // | 1455 // |
1366 // Note that if the host resolving was done by the SOCKS5 proxy, we can't | 1456 // Note that if the host resolving was done by the SOCKS5 proxy, we can't |
1367 // differentiate between a proxy-side "host not found" versus a proxy-side | 1457 // differentiate between a proxy-side "host not found" versus a proxy-side |
1368 // "address unreachable" error, and will report both of these failures as | 1458 // "address unreachable" error, and will report both of these failures as |
1369 // ERR_ADDRESS_UNREACHABLE. | 1459 // ERR_ADDRESS_UNREACHABLE. |
1370 return ERR_ADDRESS_UNREACHABLE; | 1460 return ERR_ADDRESS_UNREACHABLE; |
1371 default: | 1461 default: |
1372 return error; | 1462 return error; |
1373 } | 1463 } |
1374 | 1464 |
| 1465 // Do not bypass non-QUIC proxy on ERR_MSG_TOO_BIG. |
| 1466 if (!proxy_info_.is_quic() && error == ERR_MSG_TOO_BIG) |
| 1467 return error; |
| 1468 |
| 1469 if (request_info_.load_flags & LOAD_BYPASS_PROXY) |
| 1470 return error; |
| 1471 |
1375 // Alternative proxy server job should not use fallback proxies, and instead | 1472 // Alternative proxy server job should not use fallback proxies, and instead |
1376 // return. This would resume the main job (if possible) which may try the | 1473 // return. This would resume the main job (if possible) which may try the |
1377 // fallback proxies. | 1474 // fallback proxies. |
1378 if (alternative_proxy_server().is_valid()) { | 1475 if (alternative_proxy_server_.is_valid()) { |
1379 DCHECK_EQ(STATE_NONE, next_state_); | 1476 DCHECK_EQ(STATE_NONE, next_state_); |
1380 return error; | 1477 return error; |
1381 } | 1478 } |
1382 | 1479 |
1383 should_reconsider_proxy_ = true; | 1480 if (proxy_info_.is_https() && proxy_ssl_config_.send_client_cert) { |
1384 return error; | 1481 session_->ssl_client_auth_cache()->Remove( |
| 1482 proxy_info_.proxy_server().host_port_pair()); |
| 1483 } |
| 1484 |
| 1485 int rv = session_->proxy_service()->ReconsiderProxyAfterError( |
| 1486 request_info_.url, request_info_.method, error, &proxy_info_, |
| 1487 io_callback_, &pac_request_, session_->params().proxy_delegate, net_log_); |
| 1488 if (rv == OK || rv == ERR_IO_PENDING) { |
| 1489 // If the error was during connection setup, there is no socket to |
| 1490 // disconnect. |
| 1491 if (connection_->socket()) |
| 1492 connection_->socket()->Disconnect(); |
| 1493 connection_->Reset(); |
| 1494 delegate_->RemoveRequestFromSpdySessionRequestMapForJob(this); |
| 1495 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; |
| 1496 } else { |
| 1497 // If ReconsiderProxyAfterError() failed synchronously, it means |
| 1498 // there was nothing left to fall-back to, so fail the transaction |
| 1499 // with the last connection error we got. |
| 1500 // TODO(eroman): This is a confusing contract, make it more obvious. |
| 1501 rv = error; |
| 1502 } |
| 1503 |
| 1504 return rv; |
1385 } | 1505 } |
1386 | 1506 |
1387 int HttpStreamFactoryImpl::Job::HandleCertificateError(int error) { | 1507 int HttpStreamFactoryImpl::Job::HandleCertificateError(int error) { |
1388 DCHECK(using_ssl_); | 1508 DCHECK(using_ssl_); |
1389 DCHECK(IsCertificateError(error)); | 1509 DCHECK(IsCertificateError(error)); |
1390 | 1510 |
1391 SSLClientSocket* ssl_socket = | 1511 SSLClientSocket* ssl_socket = |
1392 static_cast<SSLClientSocket*>(connection_->socket()); | 1512 static_cast<SSLClientSocket*>(connection_->socket()); |
1393 ssl_socket->GetSSLInfo(&ssl_info_); | 1513 ssl_socket->GetSSLInfo(&ssl_info_); |
1394 | 1514 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1436 return; | 1556 return; |
1437 | 1557 |
1438 ConnectionAttempts socket_attempts = connection_->connection_attempts(); | 1558 ConnectionAttempts socket_attempts = connection_->connection_attempts(); |
1439 if (connection_->socket()) { | 1559 if (connection_->socket()) { |
1440 connection_->socket()->GetConnectionAttempts(&socket_attempts); | 1560 connection_->socket()->GetConnectionAttempts(&socket_attempts); |
1441 } | 1561 } |
1442 | 1562 |
1443 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); | 1563 delegate_->AddConnectionAttemptsToRequest(this, socket_attempts); |
1444 } | 1564 } |
1445 | 1565 |
1446 HttpStreamFactoryImpl::JobFactory::JobFactory() {} | |
1447 | |
1448 HttpStreamFactoryImpl::JobFactory::~JobFactory() {} | |
1449 | |
1450 std::unique_ptr<HttpStreamFactoryImpl::Job> | |
1451 HttpStreamFactoryImpl::JobFactory::CreateMainJob( | |
1452 HttpStreamFactoryImpl::Job::Delegate* delegate, | |
1453 HttpStreamFactoryImpl::JobType job_type, | |
1454 HttpNetworkSession* session, | |
1455 const HttpRequestInfo& request_info, | |
1456 RequestPriority priority, | |
1457 const ProxyInfo& proxy_info, | |
1458 const SSLConfig& server_ssl_config, | |
1459 const SSLConfig& proxy_ssl_config, | |
1460 HostPortPair destination, | |
1461 GURL origin_url, | |
1462 bool enable_ip_based_pooling, | |
1463 NetLog* net_log) { | |
1464 return base::MakeUnique<HttpStreamFactoryImpl::Job>( | |
1465 delegate, job_type, session, request_info, priority, proxy_info, | |
1466 server_ssl_config, proxy_ssl_config, destination, origin_url, | |
1467 enable_ip_based_pooling, net_log); | |
1468 } | |
1469 | |
1470 std::unique_ptr<HttpStreamFactoryImpl::Job> | |
1471 HttpStreamFactoryImpl::JobFactory::CreateAltSvcJob( | |
1472 HttpStreamFactoryImpl::Job::Delegate* delegate, | |
1473 HttpStreamFactoryImpl::JobType job_type, | |
1474 HttpNetworkSession* session, | |
1475 const HttpRequestInfo& request_info, | |
1476 RequestPriority priority, | |
1477 const ProxyInfo& proxy_info, | |
1478 const SSLConfig& server_ssl_config, | |
1479 const SSLConfig& proxy_ssl_config, | |
1480 HostPortPair destination, | |
1481 GURL origin_url, | |
1482 AlternativeService alternative_service, | |
1483 bool enable_ip_based_pooling, | |
1484 NetLog* net_log) { | |
1485 return base::MakeUnique<HttpStreamFactoryImpl::Job>( | |
1486 delegate, job_type, session, request_info, priority, proxy_info, | |
1487 server_ssl_config, proxy_ssl_config, destination, origin_url, | |
1488 alternative_service, ProxyServer(), enable_ip_based_pooling, net_log); | |
1489 } | |
1490 | |
1491 std::unique_ptr<HttpStreamFactoryImpl::Job> | |
1492 HttpStreamFactoryImpl::JobFactory::CreateAltProxyJob( | |
1493 HttpStreamFactoryImpl::Job::Delegate* delegate, | |
1494 HttpStreamFactoryImpl::JobType job_type, | |
1495 HttpNetworkSession* session, | |
1496 const HttpRequestInfo& request_info, | |
1497 RequestPriority priority, | |
1498 const ProxyInfo& proxy_info, | |
1499 const SSLConfig& server_ssl_config, | |
1500 const SSLConfig& proxy_ssl_config, | |
1501 HostPortPair destination, | |
1502 GURL origin_url, | |
1503 const ProxyServer& alternative_proxy_server, | |
1504 bool enable_ip_based_pooling, | |
1505 NetLog* net_log) { | |
1506 return base::MakeUnique<HttpStreamFactoryImpl::Job>( | |
1507 delegate, job_type, session, request_info, priority, proxy_info, | |
1508 server_ssl_config, proxy_ssl_config, destination, origin_url, | |
1509 AlternativeService(), alternative_proxy_server, enable_ip_based_pooling, | |
1510 net_log); | |
1511 } | |
1512 | |
1513 } // namespace net | 1566 } // namespace net |
OLD | NEW |