Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: net/proxy/proxy_service.cc

Issue 332313003: Add Finch experiment for selectively bypassing proxies. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: callback design (not yet done) Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/proxy/proxy_service.h" 5 #include "net/proxy/proxy_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 base::Bind(&PacRequest::QueryComplete, base::Unretained(this)), 764 base::Bind(&PacRequest::QueryComplete, base::Unretained(this)),
765 &resolve_job_, net_log_); 765 &resolve_job_, net_log_);
766 } 766 }
767 767
768 bool is_started() const { 768 bool is_started() const {
769 // Note that !! casts to bool. (VS gives a warning otherwise). 769 // Note that !! casts to bool. (VS gives a warning otherwise).
770 return !!resolve_job_; 770 return !!resolve_job_;
771 } 771 }
772 772
773 void StartAndCompleteCheckingForSynchronous() { 773 void StartAndCompleteCheckingForSynchronous() {
774 int rv = service_->TryToCompleteSynchronously(url_, results_); 774 int rv = service_->TryToCompleteSynchronously(url_, 0, results_);
775 if (rv == ERR_IO_PENDING) 775 if (rv == ERR_IO_PENDING)
776 rv = Start(); 776 rv = Start();
777 if (rv != ERR_IO_PENDING) 777 if (rv != ERR_IO_PENDING)
778 QueryComplete(rv); 778 QueryComplete(rv);
779 } 779 }
780 780
781 void CancelResolveJob() { 781 void CancelResolveJob() {
782 DCHECK(is_started()); 782 DCHECK(is_started());
783 // The request may already be running in the resolver. 783 // The request may already be running in the resolver.
784 resolver()->CancelRequest(resolve_job_); 784 resolver()->CancelRequest(resolve_job_);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 BoundNetLog net_log_; 870 BoundNetLog net_log_;
871 // Time when the PAC is started. Cached here since resetting ProxyInfo also 871 // Time when the PAC is started. Cached here since resetting ProxyInfo also
872 // clears the proxy times. 872 // clears the proxy times.
873 TimeTicks proxy_resolve_start_time_; 873 TimeTicks proxy_resolve_start_time_;
874 }; 874 };
875 875
876 // ProxyService --------------------------------------------------------------- 876 // ProxyService ---------------------------------------------------------------
877 877
878 ProxyService::ProxyService(ProxyConfigService* config_service, 878 ProxyService::ProxyService(ProxyConfigService* config_service,
879 ProxyResolver* resolver, 879 ProxyResolver* resolver,
880 NetworkDelegate* network_delegate,
880 NetLog* net_log) 881 NetLog* net_log)
881 : resolver_(resolver), 882 : resolver_(resolver),
882 next_config_id_(1), 883 next_config_id_(1),
883 current_state_(STATE_NONE) , 884 current_state_(STATE_NONE),
885 network_delegate_(network_delegate),
884 net_log_(net_log), 886 net_log_(net_log),
885 stall_proxy_auto_config_delay_(TimeDelta::FromMilliseconds( 887 stall_proxy_auto_config_delay_(TimeDelta::FromMilliseconds(
886 kDelayAfterNetworkChangesMs)), 888 kDelayAfterNetworkChangesMs)),
887 quick_check_enabled_(true) { 889 quick_check_enabled_(true) {
888 NetworkChangeNotifier::AddIPAddressObserver(this); 890 NetworkChangeNotifier::AddIPAddressObserver(this);
889 NetworkChangeNotifier::AddDNSObserver(this); 891 NetworkChangeNotifier::AddDNSObserver(this);
890 ResetConfigService(config_service); 892 ResetConfigService(config_service);
891 } 893 }
892 894
893 // static 895 // static
894 ProxyService* ProxyService::CreateUsingSystemProxyResolver( 896 ProxyService* ProxyService::CreateUsingSystemProxyResolver(
895 ProxyConfigService* proxy_config_service, 897 ProxyConfigService* proxy_config_service,
896 size_t num_pac_threads, 898 size_t num_pac_threads,
897 NetLog* net_log) { 899 NetLog* net_log) {
898 DCHECK(proxy_config_service); 900 DCHECK(proxy_config_service);
899 901
900 if (!ProxyResolverFactoryForSystem::IsSupported()) { 902 if (!ProxyResolverFactoryForSystem::IsSupported()) {
901 LOG(WARNING) << "PAC support disabled because there is no " 903 LOG(WARNING) << "PAC support disabled because there is no "
902 "system implementation"; 904 "system implementation";
903 return CreateWithoutProxyResolver(proxy_config_service, net_log); 905 return CreateWithoutProxyResolver(proxy_config_service, net_log);
904 } 906 }
905 907
906 if (num_pac_threads == 0) 908 if (num_pac_threads == 0)
907 num_pac_threads = kDefaultNumPacThreads; 909 num_pac_threads = kDefaultNumPacThreads;
908 910
909 ProxyResolver* proxy_resolver = new MultiThreadedProxyResolver( 911 ProxyResolver* proxy_resolver = new MultiThreadedProxyResolver(
910 new ProxyResolverFactoryForSystem(), num_pac_threads); 912 new ProxyResolverFactoryForSystem(), num_pac_threads);
911 913
912 return new ProxyService(proxy_config_service, proxy_resolver, net_log); 914 return new ProxyService(proxy_config_service, proxy_resolver, NULL, net_log);
913 } 915 }
914 916
915 // static 917 // static
916 ProxyService* ProxyService::CreateWithoutProxyResolver( 918 ProxyService* ProxyService::CreateWithoutProxyResolver(
917 ProxyConfigService* proxy_config_service, 919 ProxyConfigService* proxy_config_service,
918 NetLog* net_log) { 920 NetLog* net_log) {
919 return new ProxyService(proxy_config_service, 921 return new ProxyService(proxy_config_service,
920 new ProxyResolverNull(), 922 new ProxyResolverNull(),
923 NULL,
921 net_log); 924 net_log);
922 } 925 }
923 926
924 // static 927 // static
925 ProxyService* ProxyService::CreateFixed(const ProxyConfig& pc) { 928 ProxyService* ProxyService::CreateFixed(const ProxyConfig& pc) {
926 // TODO(eroman): This isn't quite right, won't work if |pc| specifies 929 // TODO(eroman): This isn't quite right, won't work if |pc| specifies
927 // a PAC script. 930 // a PAC script.
928 return CreateUsingSystemProxyResolver(new ProxyConfigServiceFixed(pc), 931 return CreateUsingSystemProxyResolver(new ProxyConfigServiceFixed(pc),
929 0, NULL); 932 0, NULL);
930 } 933 }
931 934
932 // static 935 // static
933 ProxyService* ProxyService::CreateFixed(const std::string& proxy) { 936 ProxyService* ProxyService::CreateFixed(const std::string& proxy) {
934 net::ProxyConfig proxy_config; 937 net::ProxyConfig proxy_config;
935 proxy_config.proxy_rules().ParseFromString(proxy); 938 proxy_config.proxy_rules().ParseFromString(proxy);
936 return ProxyService::CreateFixed(proxy_config); 939 return ProxyService::CreateFixed(proxy_config);
937 } 940 }
938 941
939 // static 942 // static
940 ProxyService* ProxyService::CreateDirect() { 943 ProxyService* ProxyService::CreateDirect() {
941 return CreateDirectWithNetLog(NULL); 944 return CreateDirectWithNetLog(NULL);
942 } 945 }
943 946
944 ProxyService* ProxyService::CreateDirectWithNetLog(NetLog* net_log) { 947 ProxyService* ProxyService::CreateDirectWithNetLog(NetLog* net_log) {
945 // Use direct connections. 948 // Use direct connections.
946 return new ProxyService(new ProxyConfigServiceDirect, new ProxyResolverNull, 949 return new ProxyService(new ProxyConfigServiceDirect, new ProxyResolverNull,
947 net_log); 950 NULL, net_log);
948 } 951 }
949 952
950 // static 953 // static
951 ProxyService* ProxyService::CreateFixedFromPacResult( 954 ProxyService* ProxyService::CreateFixedFromPacResult(
952 const std::string& pac_string) { 955 const std::string& pac_string) {
953 956
954 // We need the settings to contain an "automatic" setting, otherwise the 957 // We need the settings to contain an "automatic" setting, otherwise the
955 // ProxyResolver dependency we give it will never be used. 958 // ProxyResolver dependency we give it will never be used.
956 scoped_ptr<ProxyConfigService> proxy_config_service( 959 scoped_ptr<ProxyConfigService> proxy_config_service(
957 new ProxyConfigServiceFixed(ProxyConfig::CreateAutoDetect())); 960 new ProxyConfigServiceFixed(ProxyConfig::CreateAutoDetect()));
958 961
959 scoped_ptr<ProxyResolver> proxy_resolver( 962 scoped_ptr<ProxyResolver> proxy_resolver(
960 new ProxyResolverFromPacString(pac_string)); 963 new ProxyResolverFromPacString(pac_string));
961 964
962 return new ProxyService(proxy_config_service.release(), 965 return new ProxyService(proxy_config_service.release(),
963 proxy_resolver.release(), 966 proxy_resolver.release(),
964 NULL); 967 NULL, NULL);
965 } 968 }
966 969
967 int ProxyService::ResolveProxy(const GURL& raw_url, 970 int ProxyService::ResolveProxy(const GURL& raw_url,
971 int load_flags,
968 ProxyInfo* result, 972 ProxyInfo* result,
969 const net::CompletionCallback& callback, 973 const net::CompletionCallback& callback,
970 PacRequest** pac_request, 974 PacRequest** pac_request,
971 const BoundNetLog& net_log) { 975 const BoundNetLog& net_log) {
972 DCHECK(CalledOnValidThread()); 976 DCHECK(CalledOnValidThread());
973 DCHECK(!callback.is_null()); 977 DCHECK(!callback.is_null());
974 978
975 net_log.BeginEvent(NetLog::TYPE_PROXY_SERVICE); 979 net_log.BeginEvent(NetLog::TYPE_PROXY_SERVICE);
976 980
977 // Notify our polling-based dependencies that a resolve is taking place. 981 // Notify our polling-based dependencies that a resolve is taking place.
978 // This way they can schedule their polls in response to network activity. 982 // This way they can schedule their polls in response to network activity.
979 config_service_->OnLazyPoll(); 983 config_service_->OnLazyPoll();
980 if (script_poller_.get()) 984 if (script_poller_.get())
981 script_poller_->OnLazyPoll(); 985 script_poller_->OnLazyPoll();
982 986
983 if (current_state_ == STATE_NONE) 987 if (current_state_ == STATE_NONE)
984 ApplyProxyConfigIfAvailable(); 988 ApplyProxyConfigIfAvailable();
985 989
986 // Strip away any reference fragments and the username/password, as they 990 // Strip away any reference fragments and the username/password, as they
987 // are not relevant to proxy resolution. 991 // are not relevant to proxy resolution.
988 GURL url = SimplifyUrlForRequest(raw_url); 992 GURL url = SimplifyUrlForRequest(raw_url);
989 993
990 // Check if the request can be completed right away. (This is the case when 994 // Check if the request can be completed right away. (This is the case when
991 // using a direct connection for example). 995 // using a direct connection for example).
992 int rv = TryToCompleteSynchronously(url, result); 996 int rv = TryToCompleteSynchronously(url, load_flags, result);
993 if (rv != ERR_IO_PENDING) 997 if (rv != ERR_IO_PENDING)
994 return DidFinishResolvingProxy(result, rv, net_log); 998 return DidFinishResolvingProxy(result, rv, net_log);
995 999
1000 // TODO(rcs): add load_flags to PacRequest.
mmenke 2014/06/27 18:59:35 Flywheel requests always go through a PAC currentl
rcs 2014/06/28 03:53:38 I ran this (a few days) without adding load_flags
rcs 2014/06/28 04:01:04 *a few days ago
rcs 2014/06/30 19:46:31 I verified that data compression proxy requests do
996 scoped_refptr<PacRequest> req( 1001 scoped_refptr<PacRequest> req(
997 new PacRequest(this, url, result, callback, net_log)); 1002 new PacRequest(this, url, result, callback, net_log));
998 1003
999 if (current_state_ == STATE_READY) { 1004 if (current_state_ == STATE_READY) {
1000 // Start the resolve request. 1005 // Start the resolve request.
1001 rv = req->Start(); 1006 rv = req->Start();
1002 if (rv != ERR_IO_PENDING) 1007 if (rv != ERR_IO_PENDING)
1003 return req->QueryDidComplete(rv); 1008 return req->QueryDidComplete(rv);
1004 } else { 1009 } else {
1005 req->net_log()->BeginEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC); 1010 req->net_log()->BeginEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC);
1006 } 1011 }
1007 1012
1008 DCHECK_EQ(ERR_IO_PENDING, rv); 1013 DCHECK_EQ(ERR_IO_PENDING, rv);
1009 DCHECK(!ContainsPendingRequest(req.get())); 1014 DCHECK(!ContainsPendingRequest(req.get()));
1010 pending_requests_.push_back(req); 1015 pending_requests_.push_back(req);
1011 1016
1012 // Completion will be notified through |callback|, unless the caller cancels 1017 // Completion will be notified through |callback|, unless the caller cancels
1013 // the request using |pac_request|. 1018 // the request using |pac_request|.
1014 if (pac_request) 1019 if (pac_request)
1015 *pac_request = req.get(); 1020 *pac_request = req.get();
1016 return rv; // ERR_IO_PENDING 1021 return rv; // ERR_IO_PENDING
1017 } 1022 }
1018 1023
1019 int ProxyService::TryToCompleteSynchronously(const GURL& url, 1024 int ProxyService::TryToCompleteSynchronously(const GURL& url,
1025 int load_flags,
1020 ProxyInfo* result) { 1026 ProxyInfo* result) {
1021 DCHECK_NE(STATE_NONE, current_state_); 1027 DCHECK_NE(STATE_NONE, current_state_);
1022 1028
1023 if (current_state_ != STATE_READY) 1029 if (current_state_ != STATE_READY)
1024 return ERR_IO_PENDING; // Still initializing. 1030 return ERR_IO_PENDING; // Still initializing.
1025 1031
1026 DCHECK_NE(config_.id(), ProxyConfig::kInvalidConfigID); 1032 DCHECK_NE(config_.id(), ProxyConfig::kInvalidConfigID);
1027 1033
1028 // If it was impossible to fetch or parse the PAC script, we cannot complete 1034 // If it was impossible to fetch or parse the PAC script, we cannot complete
1029 // the request here and bail out. 1035 // the request here and bail out.
1030 if (permanent_error_ != OK) 1036 if (permanent_error_ != OK)
1031 return permanent_error_; 1037 return permanent_error_;
1032 1038
1033 if (config_.HasAutomaticSettings()) 1039 if (config_.HasAutomaticSettings())
1034 return ERR_IO_PENDING; // Must submit the request to the proxy resolver. 1040 return ERR_IO_PENDING; // Must submit the request to the proxy resolver.
1035 1041
1036 // Use the manual proxy settings. 1042 // Use the manual proxy settings.
1037 config_.proxy_rules().Apply(url, result); 1043 config_.proxy_rules().Apply(url, result);
1038 result->config_source_ = config_.source(); 1044 result->config_source_ = config_.source();
1039 result->config_id_ = config_.id(); 1045 result->config_id_ = config_.id();
1046
1047 // Allow the network delegate to interpose on the resolution decision,
1048 // possibly modifying the ProxyInfo.
1049 if (network_delegate_) {
1050 network_delegate_->NotifyResolveProxy(url, load_flags, result);
1051 }
1052
1040 return OK; 1053 return OK;
1041 } 1054 }
1042 1055
1043 ProxyService::~ProxyService() { 1056 ProxyService::~ProxyService() {
1044 NetworkChangeNotifier::RemoveIPAddressObserver(this); 1057 NetworkChangeNotifier::RemoveIPAddressObserver(this);
1045 NetworkChangeNotifier::RemoveDNSObserver(this); 1058 NetworkChangeNotifier::RemoveDNSObserver(this);
1046 config_service_->RemoveObserver(this); 1059 config_service_->RemoveObserver(this);
1047 1060
1048 // Cancel any inprogress requests. 1061 // Cancel any inprogress requests.
1049 for (PendingRequests::iterator it = pending_requests_.begin(); 1062 for (PendingRequests::iterator it = pending_requests_.begin();
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 // Check to see if we have a new config since ResolveProxy was called. We 1189 // Check to see if we have a new config since ResolveProxy was called. We
1177 // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a 1190 // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a
1178 // direct connection failed and we never tried the current config. 1191 // direct connection failed and we never tried the current config.
1179 1192
1180 bool re_resolve = result->config_id_ != config_.id(); 1193 bool re_resolve = result->config_id_ != config_.id();
1181 1194
1182 if (re_resolve) { 1195 if (re_resolve) {
1183 // If we have a new config or the config was never tried, we delete the 1196 // If we have a new config or the config was never tried, we delete the
1184 // list of bad proxies and we try again. 1197 // list of bad proxies and we try again.
1185 proxy_retry_info_.clear(); 1198 proxy_retry_info_.clear();
1186 return ResolveProxy(url, result, callback, pac_request, net_log); 1199 return ResolveProxy(url, 0, result, callback, pac_request, net_log);
1187 } 1200 }
1188 1201
1189 #if defined(SPDY_PROXY_AUTH_ORIGIN) 1202 #if defined(SPDY_PROXY_AUTH_ORIGIN)
1190 if (result->proxy_server().isDataReductionProxy()) { 1203 if (result->proxy_server().isDataReductionProxy()) {
1191 RecordDataReductionProxyBypassInfo( 1204 RecordDataReductionProxyBypassInfo(
1192 true, result->proxy_server(), ERROR_BYPASS); 1205 true, result->proxy_server(), ERROR_BYPASS);
1193 RecordDataReductionProxyBypassOnNetworkError( 1206 RecordDataReductionProxyBypassOnNetworkError(
1194 true, result->proxy_server(), net_error); 1207 true, result->proxy_server(), net_error);
1195 } else if (result->proxy_server().isDataReductionProxyFallback()) { 1208 } else if (result->proxy_server().isDataReductionProxyFallback()) {
1196 RecordDataReductionProxyBypassInfo( 1209 RecordDataReductionProxyBypassInfo(
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 *proxy_info = proxy_info_; 1629 *proxy_info = proxy_info_;
1617 } 1630 }
1618 return result_; 1631 return result_;
1619 } 1632 }
1620 1633
1621 SyncProxyServiceHelper::~SyncProxyServiceHelper() {} 1634 SyncProxyServiceHelper::~SyncProxyServiceHelper() {}
1622 1635
1623 void SyncProxyServiceHelper::StartAsyncResolve(const GURL& url, 1636 void SyncProxyServiceHelper::StartAsyncResolve(const GURL& url,
1624 const BoundNetLog& net_log) { 1637 const BoundNetLog& net_log) {
1625 result_ = proxy_service_->ResolveProxy( 1638 result_ = proxy_service_->ResolveProxy(
1626 url, &proxy_info_, callback_, NULL, net_log); 1639 url, 0, &proxy_info_, callback_, NULL, net_log);
1627 if (result_ != net::ERR_IO_PENDING) { 1640 if (result_ != net::ERR_IO_PENDING) {
1628 OnCompletion(result_); 1641 OnCompletion(result_);
1629 } 1642 }
1630 } 1643 }
1631 1644
1632 void SyncProxyServiceHelper::StartAsyncReconsider(const GURL& url, 1645 void SyncProxyServiceHelper::StartAsyncReconsider(const GURL& url,
1633 int net_error, 1646 int net_error,
1634 const BoundNetLog& net_log) { 1647 const BoundNetLog& net_log) {
1635 result_ = proxy_service_->ReconsiderProxyAfterError( 1648 result_ = proxy_service_->ReconsiderProxyAfterError(
1636 url, net_error, &proxy_info_, callback_, NULL, net_log); 1649 url, net_error, &proxy_info_, callback_, NULL, net_log);
1637 if (result_ != net::ERR_IO_PENDING) { 1650 if (result_ != net::ERR_IO_PENDING) {
1638 OnCompletion(result_); 1651 OnCompletion(result_);
1639 } 1652 }
1640 } 1653 }
1641 1654
1642 void SyncProxyServiceHelper::OnCompletion(int rv) { 1655 void SyncProxyServiceHelper::OnCompletion(int rv) {
1643 result_ = rv; 1656 result_ = rv;
1644 event_.Signal(); 1657 event_.Signal();
1645 } 1658 }
1646 1659
1647 } // namespace net 1660 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698