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