configured_proxy_resolution_service.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  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
  3. // found in the LICENSE file.
  4. #ifndef NET_PROXY_RESOLUTION_CONFIGURED_PROXY_RESOLUTION_SERVICE_H_
  5. #define NET_PROXY_RESOLUTION_CONFIGURED_PROXY_RESOLUTION_SERVICE_H_
  6. #include <stddef.h>
  7. #include <memory>
  8. #include <set>
  9. #include <string>
  10. #include <vector>
  11. #include "base/gtest_prod_util.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/memory/ref_counted.h"
  14. #include "base/synchronization/waitable_event.h"
  15. #include "base/threading/thread_checker.h"
  16. #include "net/base/completion_once_callback.h"
  17. #include "net/base/load_states.h"
  18. #include "net/base/net_errors.h"
  19. #include "net/base/net_export.h"
  20. #include "net/base/network_change_notifier.h"
  21. #include "net/log/net_log_with_source.h"
  22. #include "net/proxy_resolution/proxy_config_service.h"
  23. #include "net/proxy_resolution/proxy_config_with_annotation.h"
  24. #include "net/proxy_resolution/proxy_info.h"
  25. #include "net/proxy_resolution/proxy_resolution_request.h"
  26. #include "net/proxy_resolution/proxy_resolution_service.h"
  27. #include "net/proxy_resolution/proxy_resolver.h"
  28. #include "net/traffic_annotation/network_traffic_annotation.h"
  29. #include "third_party/abseil-cpp/absl/types/optional.h"
  30. #include "url/gurl.h"
  31. namespace base {
  32. class TimeDelta;
  33. } // namespace base
  34. namespace net {
  35. class ConfiguredProxyResolutionRequest;
  36. class DhcpPacFileFetcher;
  37. class NetLog;
  38. class PacFileFetcher;
  39. class ProxyDelegate;
  40. class ProxyResolverFactory;
  41. struct PacFileDataWithSource;
  42. // This class decides which proxy server(s) to use for a particular URL request.
  43. // It uses the given ProxyResolver to evaluate a PAC file, which the
  44. // ConfiguredProxyResolutionService then uses to resolve a proxy. All proxy
  45. // resolution in this class is based on first getting proxy configurations (ex:
  46. // a PAC URL) from some source and then using these configurations to attempt to
  47. // resolve that proxy.
  48. class NET_EXPORT ConfiguredProxyResolutionService
  49. : public ProxyResolutionService,
  50. public NetworkChangeNotifier::IPAddressObserver,
  51. public NetworkChangeNotifier::DNSObserver,
  52. public ProxyConfigService::Observer {
  53. public:
  54. // This interface defines the set of policies for when to poll the PAC
  55. // script for changes.
  56. //
  57. // The polling policy decides what the next poll delay should be in
  58. // milliseconds. It also decides how to wait for this delay -- either
  59. // by starting a timer to do the poll at exactly |next_delay_ms|
  60. // (MODE_USE_TIMER) or by waiting for the first network request issued after
  61. // |next_delay_ms| (MODE_START_AFTER_ACTIVITY).
  62. //
  63. // The timer method is more precise and guarantees that polling happens when
  64. // it was requested. However it has the disadvantage of causing spurious CPU
  65. // and network activity. It is a reasonable choice to use for short poll
  66. // intervals which only happen a couple times.
  67. //
  68. // However for repeated timers this will prevent the browser from going
  69. // idle. MODE_START_AFTER_ACTIVITY solves this problem by only polling in
  70. // direct response to network activity. The drawback to
  71. // MODE_START_AFTER_ACTIVITY is since the poll is initiated only after the
  72. // request is received, the first couple requests initiated after a long
  73. // period of inactivity will likely see a stale version of the PAC script
  74. // until the background polling gets a chance to update things.
  75. class NET_EXPORT_PRIVATE PacPollPolicy {
  76. public:
  77. enum Mode {
  78. MODE_USE_TIMER,
  79. MODE_START_AFTER_ACTIVITY,
  80. };
  81. virtual ~PacPollPolicy() = default;
  82. // Decides the next poll delay. |current_delay| is the delay used
  83. // by the preceding poll, or a negative TimeDelta value if determining
  84. // the delay for the initial poll. |initial_error| is the network error
  85. // code that the last PAC fetch (or WPAD initialization) failed with,
  86. // or OK if it completed successfully. Implementations must set
  87. // |next_delay| to a non-negative value.
  88. virtual Mode GetNextDelay(int initial_error,
  89. base::TimeDelta current_delay,
  90. base::TimeDelta* next_delay) const = 0;
  91. };
  92. // |net_log| is a possibly nullptr destination to send log events to. It must
  93. // remain alive for the lifetime of this ConfiguredProxyResolutionService.
  94. ConfiguredProxyResolutionService(
  95. std::unique_ptr<ProxyConfigService> config_service,
  96. std::unique_ptr<ProxyResolverFactory> resolver_factory,
  97. NetLog* net_log,
  98. bool quick_check_enabled);
  99. ConfiguredProxyResolutionService(const ConfiguredProxyResolutionService&) =
  100. delete;
  101. ConfiguredProxyResolutionService& operator=(
  102. const ConfiguredProxyResolutionService&) = delete;
  103. ~ConfiguredProxyResolutionService() override;
  104. // ProxyResolutionService
  105. //
  106. // We use the three possible proxy access types in the following order,
  107. // doing fallback if one doesn't work. See "pac_script_decider.h"
  108. // for the specifics.
  109. // 1. WPAD auto-detection
  110. // 2. PAC URL
  111. // 3. named proxy
  112. int ResolveProxy(const GURL& url,
  113. const std::string& method,
  114. const NetworkIsolationKey& network_isolation_key,
  115. ProxyInfo* results,
  116. CompletionOnceCallback callback,
  117. std::unique_ptr<ProxyResolutionRequest>* request,
  118. const NetLogWithSource& net_log) override;
  119. // ProxyResolutionService
  120. bool MarkProxiesAsBadUntil(
  121. const ProxyInfo& results,
  122. base::TimeDelta retry_delay,
  123. const std::vector<ProxyServer>& additional_bad_proxies,
  124. const NetLogWithSource& net_log) override;
  125. // ProxyResolutionService
  126. void ReportSuccess(const ProxyInfo& proxy_info) override;
  127. // Sets the PacFileFetcher and DhcpPacFileFetcher dependencies. This
  128. // is needed if the ProxyResolver is of type ProxyResolverWithoutFetch.
  129. void SetPacFileFetchers(
  130. std::unique_ptr<PacFileFetcher> pac_file_fetcher,
  131. std::unique_ptr<DhcpPacFileFetcher> dhcp_pac_file_fetcher);
  132. PacFileFetcher* GetPacFileFetcher() const;
  133. // ProxyResolutionService
  134. void SetProxyDelegate(ProxyDelegate* delegate) override;
  135. // ProxyResolutionService
  136. void OnShutdown() override;
  137. // Returns the last configuration fetched from ProxyConfigService.
  138. const absl::optional<ProxyConfigWithAnnotation>& fetched_config() const {
  139. return fetched_config_;
  140. }
  141. // Returns the current configuration being used by ProxyConfigService.
  142. const absl::optional<ProxyConfigWithAnnotation>& config() const {
  143. return config_;
  144. }
  145. // ProxyResolutionService
  146. const ProxyRetryInfoMap& proxy_retry_info() const override;
  147. // ProxyResolutionService
  148. void ClearBadProxiesCache() override;
  149. // Forces refetching the proxy configuration, and applying it.
  150. // This re-does everything from fetching the system configuration,
  151. // to downloading and testing the PAC files.
  152. void ForceReloadProxyConfig();
  153. // ProxyResolutionService
  154. base::Value::Dict GetProxyNetLogValues() override;
  155. // ProxyResolutionService
  156. [[nodiscard]] bool CastToConfiguredProxyResolutionService(
  157. ConfiguredProxyResolutionService** configured_proxy_resolution_service)
  158. override;
  159. // Same as CreateProxyResolutionServiceUsingV8ProxyResolver, except it uses
  160. // system libraries for evaluating the PAC script if available, otherwise
  161. // skips proxy autoconfig.
  162. static std::unique_ptr<ConfiguredProxyResolutionService>
  163. CreateUsingSystemProxyResolver(
  164. std::unique_ptr<ProxyConfigService> proxy_config_service,
  165. NetLog* net_log,
  166. bool quick_check_enabled);
  167. // Creates a ConfiguredProxyResolutionService without support for proxy
  168. // autoconfig.
  169. static std::unique_ptr<ConfiguredProxyResolutionService>
  170. CreateWithoutProxyResolver(
  171. std::unique_ptr<ProxyConfigService> proxy_config_service,
  172. NetLog* net_log);
  173. // Convenience methods that creates a proxy service using the
  174. // specified fixed settings.
  175. static std::unique_ptr<ConfiguredProxyResolutionService> CreateFixedForTest(
  176. const ProxyConfigWithAnnotation& pc);
  177. static std::unique_ptr<ConfiguredProxyResolutionService> CreateFixedForTest(
  178. const std::string& proxy,
  179. const NetworkTrafficAnnotationTag& traffic_annotation);
  180. // Creates a proxy service that uses a DIRECT connection for all requests.
  181. static std::unique_ptr<ConfiguredProxyResolutionService> CreateDirect();
  182. // This method is used by tests to create a ConfiguredProxyResolutionService
  183. // that returns a hardcoded proxy fallback list (|pac_string|) for every URL.
  184. //
  185. // |pac_string| is a list of proxy servers, in the format that a PAC script
  186. // would return it. For example, "PROXY foobar:99; SOCKS fml:2; DIRECT"
  187. static std::unique_ptr<ConfiguredProxyResolutionService>
  188. CreateFixedFromPacResultForTest(
  189. const std::string& pac_string,
  190. const NetworkTrafficAnnotationTag& traffic_annotation);
  191. // Same as CreateFixedFromPacResultForTest(), except the resulting ProxyInfo
  192. // from resolutions will be tagged as having been auto-detected.
  193. static std::unique_ptr<ConfiguredProxyResolutionService>
  194. CreateFixedFromAutoDetectedPacResultForTest(
  195. const std::string& pac_string,
  196. const NetworkTrafficAnnotationTag& traffic_annotation);
  197. // This method should only be used by unit tests.
  198. void set_stall_proxy_auto_config_delay(base::TimeDelta delay) {
  199. stall_proxy_auto_config_delay_ = delay;
  200. }
  201. // This method should only be used by unit tests. Returns the previously
  202. // active policy.
  203. static const PacPollPolicy* set_pac_script_poll_policy(
  204. const PacPollPolicy* policy);
  205. // This method should only be used by unit tests. Creates an instance
  206. // of the default internal PacPollPolicy used by
  207. // ConfiguredProxyResolutionService.
  208. static std::unique_ptr<PacPollPolicy> CreateDefaultPacPollPolicy();
  209. bool quick_check_enabled_for_testing() const { return quick_check_enabled_; }
  210. private:
  211. friend class ConfiguredProxyResolutionRequest;
  212. FRIEND_TEST_ALL_PREFIXES(ProxyResolutionServiceTest,
  213. UpdateConfigAfterFailedAutodetect);
  214. FRIEND_TEST_ALL_PREFIXES(ProxyResolutionServiceTest,
  215. UpdateConfigFromPACToDirect);
  216. class InitProxyResolver;
  217. class PacFileDeciderPoller;
  218. typedef std::set<ConfiguredProxyResolutionRequest*> PendingRequests;
  219. enum State {
  220. STATE_NONE,
  221. STATE_WAITING_FOR_PROXY_CONFIG,
  222. STATE_WAITING_FOR_INIT_PROXY_RESOLVER,
  223. STATE_READY,
  224. };
  225. // We won't always be able to return a good LoadState. For example, the
  226. // ConfiguredProxyResolutionService can only get this information from the
  227. // InitProxyResolver, which is not always available.
  228. bool GetLoadStateIfAvailable(LoadState* load_state) const;
  229. ProxyResolver* GetProxyResolver() const;
  230. // Resets all the variables associated with the current proxy configuration,
  231. // and rewinds the current state to |STATE_NONE|. Returns the previous value
  232. // of |current_state_|. If |reset_fetched_config| is true then
  233. // |fetched_config_| will also be reset, otherwise it will be left as-is.
  234. // Resetting it means that we will have to re-fetch the configuration from
  235. // the ProxyConfigService later.
  236. State ResetProxyConfig(bool reset_fetched_config);
  237. // Retrieves the current proxy configuration from the ProxyConfigService, and
  238. // starts initializing for it.
  239. void ApplyProxyConfigIfAvailable();
  240. // Callback for when the proxy resolver has been initialized with a
  241. // PAC script.
  242. void OnInitProxyResolverComplete(int result);
  243. // Returns ERR_IO_PENDING if the request cannot be completed synchronously.
  244. // Otherwise it fills |result| with the proxy information for |url|.
  245. // Completing synchronously means we don't need to query ProxyResolver.
  246. int TryToCompleteSynchronously(const GURL& url, ProxyInfo* result);
  247. // Cancels all of the requests sent to the ProxyResolver. These will be
  248. // restarted when calling SetReady().
  249. void SuspendAllPendingRequests();
  250. // Advances the current state to |STATE_READY|, and resumes any pending
  251. // requests which had been stalled waiting for initialization to complete.
  252. void SetReady();
  253. // Returns true if |pending_requests_| contains |req|.
  254. bool ContainsPendingRequest(ConfiguredProxyResolutionRequest* req);
  255. // Removes |req| from the list of pending requests.
  256. void RemovePendingRequest(ConfiguredProxyResolutionRequest* req);
  257. // Called when proxy resolution has completed (either synchronously or
  258. // asynchronously). Handles logging the result, and cleaning out
  259. // bad entries from the results list.
  260. int DidFinishResolvingProxy(const GURL& url,
  261. const std::string& method,
  262. ProxyInfo* result,
  263. int result_code,
  264. const NetLogWithSource& net_log);
  265. // Start initialization using |fetched_config_|.
  266. void InitializeUsingLastFetchedConfig();
  267. // Start the initialization skipping past the "decision" phase.
  268. void InitializeUsingDecidedConfig(
  269. int decider_result,
  270. const PacFileDataWithSource& script_data,
  271. const ProxyConfigWithAnnotation& effective_config);
  272. // NetworkChangeNotifier::IPAddressObserver
  273. // When this is called, we re-fetch PAC scripts and re-run WPAD.
  274. void OnIPAddressChanged() override;
  275. // NetworkChangeNotifier::DNSObserver
  276. // We respond as above.
  277. void OnDNSChanged() override;
  278. // ProxyConfigService::Observer
  279. void OnProxyConfigChanged(
  280. const ProxyConfigWithAnnotation& config,
  281. ProxyConfigService::ConfigAvailability availability) override;
  282. // When using a PAC script there isn't a user-configurable ProxyBypassRules to
  283. // check, as the one from manual settings doesn't apply. However we
  284. // still check for matches against the implicit bypass rules, to prevent PAC
  285. // scripts from being able to proxy localhost.
  286. bool ApplyPacBypassRules(const GURL& url, ProxyInfo* results);
  287. std::unique_ptr<ProxyConfigService> config_service_;
  288. std::unique_ptr<ProxyResolverFactory> resolver_factory_;
  289. // If non-null, the initialized ProxyResolver to use for requests.
  290. std::unique_ptr<ProxyResolver> resolver_;
  291. // We store the proxy configuration that was last fetched from the
  292. // ProxyConfigService, as well as the resulting "effective" configuration.
  293. // The effective configuration is what we condense the original fetched
  294. // settings to after testing the various automatic settings (auto-detect
  295. // and custom PAC url).
  296. //
  297. // These are "optional" as their value remains unset while being calculated.
  298. absl::optional<ProxyConfigWithAnnotation> fetched_config_;
  299. absl::optional<ProxyConfigWithAnnotation> config_;
  300. // Map of the known bad proxies and the information about the retry time.
  301. ProxyRetryInfoMap proxy_retry_info_;
  302. // Set of pending/inprogress requests.
  303. PendingRequests pending_requests_;
  304. // The fetcher to use when downloading PAC scripts for the ProxyResolver.
  305. // This dependency can be nullptr if our ProxyResolver has no need for
  306. // external PAC script fetching.
  307. std::unique_ptr<PacFileFetcher> pac_file_fetcher_;
  308. // The fetcher to use when attempting to download the most appropriate PAC
  309. // script configured in DHCP, if any. Can be nullptr if the ProxyResolver has
  310. // no need for DHCP PAC script fetching.
  311. std::unique_ptr<DhcpPacFileFetcher> dhcp_pac_file_fetcher_;
  312. // Helper to download the PAC script (wpad + custom) and apply fallback rules.
  313. //
  314. // Note that the declaration is important here: |pac_file_fetcher_| and
  315. // |proxy_resolver_| must outlive |init_proxy_resolver_|.
  316. std::unique_ptr<InitProxyResolver> init_proxy_resolver_;
  317. // Helper to poll the PAC script for changes.
  318. std::unique_ptr<PacFileDeciderPoller> script_poller_;
  319. State current_state_ = STATE_NONE;
  320. // Either OK or an ERR_* value indicating that a permanent error (e.g.
  321. // failed to fetch the PAC script) prevents proxy resolution.
  322. int permanent_error_ = OK;
  323. // This is the log where any events generated by |init_proxy_resolver_| are
  324. // sent to.
  325. raw_ptr<NetLog> net_log_;
  326. // The earliest time at which we should run any proxy auto-config. (Used to
  327. // stall re-configuration following an IP address change).
  328. base::TimeTicks stall_proxy_autoconfig_until_;
  329. // The amount of time to stall requests following IP address changes.
  330. base::TimeDelta stall_proxy_auto_config_delay_;
  331. // Whether child PacFileDeciders should use QuickCheck
  332. bool quick_check_enabled_;
  333. THREAD_CHECKER(thread_checker_);
  334. raw_ptr<ProxyDelegate> proxy_delegate_ = nullptr;
  335. // Flag used by |SetReady()| to check if |this| has been deleted by a
  336. // synchronous callback.
  337. base::WeakPtrFactory<ConfiguredProxyResolutionService> weak_ptr_factory_{
  338. this};
  339. };
  340. } // namespace net
  341. #endif // NET_PROXY_RESOLUTION_CONFIGURED_PROXY_RESOLUTION_SERVICE_H_