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/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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |