pac_file_decider.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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_PAC_FILE_DECIDER_H_
  5. #define NET_PROXY_RESOLUTION_PAC_FILE_DECIDER_H_
  6. #include <stddef.h>
  7. #include <memory>
  8. #include <string>
  9. #include <vector>
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/memory/ref_counted.h"
  12. #include "base/time/time.h"
  13. #include "base/timer/timer.h"
  14. #include "net/base/completion_once_callback.h"
  15. #include "net/base/net_export.h"
  16. #include "net/dns/host_resolver.h"
  17. #include "net/log/net_log_with_source.h"
  18. #include "net/proxy_resolution/proxy_config_with_annotation.h"
  19. #include "net/proxy_resolution/proxy_resolver.h"
  20. #include "url/gurl.h"
  21. namespace base {
  22. class Value;
  23. }
  24. namespace net {
  25. class DhcpPacFileFetcher;
  26. class NetLog;
  27. class ProxyResolver;
  28. class PacFileFetcher;
  29. // Structure that encapsulates the result a PacFileData along with an
  30. // indication of its origin: was it obtained implicitly from auto-detect,
  31. // or was it read from a more explicitly configured URL.
  32. //
  33. // Note that |!from_auto_detect| does NOT imply the script was securely
  34. // delivered. Most commonly PAC scripts are configured from http:// URLs,
  35. // both for auto-detect and not.
  36. struct NET_EXPORT_PRIVATE PacFileDataWithSource {
  37. PacFileDataWithSource();
  38. PacFileDataWithSource(const PacFileDataWithSource&);
  39. ~PacFileDataWithSource();
  40. PacFileDataWithSource& operator=(const PacFileDataWithSource&);
  41. scoped_refptr<PacFileData> data;
  42. bool from_auto_detect = false;
  43. };
  44. // PacFileDecider is a helper class used by ConfiguredProxyResolutionService to
  45. // determine which PAC script to use given our proxy configuration.
  46. //
  47. // This involves trying to use PAC scripts in this order:
  48. //
  49. // (1) WPAD (DHCP) if auto-detect is on.
  50. // (2) WPAD (DNS) if auto-detect is on.
  51. // (3) Custom PAC script if a URL was given.
  52. //
  53. // If no PAC script was successfully selected, then it fails with either a
  54. // network error, or PAC_SCRIPT_FAILED (indicating it did not pass our
  55. // validation).
  56. //
  57. // On successful completion, the fetched PAC script data can be accessed using
  58. // script_data().
  59. //
  60. // Deleting PacFileDecider while Init() is in progress, will
  61. // cancel the request.
  62. //
  63. class NET_EXPORT_PRIVATE PacFileDecider {
  64. public:
  65. // |pac_file_fetcher|, |dhcp_pac_file_fetcher| and
  66. // |net_log| must remain valid for the lifespan of PacFileDecider.
  67. PacFileDecider(PacFileFetcher* pac_file_fetcher,
  68. DhcpPacFileFetcher* dhcp_pac_file_fetcher,
  69. NetLog* net_log);
  70. PacFileDecider(const PacFileDecider&) = delete;
  71. PacFileDecider& operator=(const PacFileDecider&) = delete;
  72. // Aborts any in-progress request.
  73. ~PacFileDecider();
  74. // Evaluates the effective proxy settings for |config|, and downloads the
  75. // associated PAC script.
  76. // If |wait_delay| is positive, the initialization will pause for this
  77. // amount of time before getting started.
  78. // On successful completion, the "effective" proxy settings we ended up
  79. // deciding on will be available vial the effective_settings() accessor.
  80. // Note that this may differ from |config| since we will have stripped any
  81. // manual settings, and decided whether to use auto-detect or the custom PAC
  82. // URL. Finally, if auto-detect was used we may now have resolved that to a
  83. // specific script URL.
  84. int Start(const ProxyConfigWithAnnotation& config,
  85. const base::TimeDelta wait_delay,
  86. bool fetch_pac_bytes,
  87. CompletionOnceCallback callback);
  88. // Shuts down any in-progress DNS requests, and cancels any ScriptFetcher
  89. // requests. Does not call OnShutdown() on the [Dhcp]PacFileFetcher. Any
  90. // pending callback will not be invoked.
  91. void OnShutdown();
  92. const ProxyConfigWithAnnotation& effective_config() const;
  93. const PacFileDataWithSource& script_data() const;
  94. void set_quick_check_enabled(bool enabled) { quick_check_enabled_ = enabled; }
  95. bool quick_check_enabled() const { return quick_check_enabled_; }
  96. private:
  97. // Represents the sources from which we can get PAC files; two types of
  98. // auto-detect or a custom URL.
  99. struct PacSource {
  100. enum Type { WPAD_DHCP, WPAD_DNS, CUSTOM };
  101. PacSource(Type type, const GURL& url) : type(type), url(url) {}
  102. // Returns a Value representing the PacSource. |effective_pac_url| is the
  103. // URL derived from information contained in
  104. // |this|, if Type is not WPAD_DHCP.
  105. base::Value NetLogParams(const GURL& effective_pac_url) const;
  106. Type type;
  107. GURL url; // Empty unless |type == PAC_SOURCE_CUSTOM|.
  108. };
  109. typedef std::vector<PacSource> PacSourceList;
  110. enum State {
  111. STATE_NONE,
  112. STATE_WAIT,
  113. STATE_WAIT_COMPLETE,
  114. STATE_QUICK_CHECK,
  115. STATE_QUICK_CHECK_COMPLETE,
  116. STATE_FETCH_PAC_SCRIPT,
  117. STATE_FETCH_PAC_SCRIPT_COMPLETE,
  118. STATE_VERIFY_PAC_SCRIPT,
  119. STATE_VERIFY_PAC_SCRIPT_COMPLETE,
  120. };
  121. // Returns ordered list of PAC urls to try for |config|.
  122. PacSourceList BuildPacSourcesFallbackList(const ProxyConfig& config) const;
  123. void OnIOCompletion(int result);
  124. int DoLoop(int result);
  125. int DoWait();
  126. int DoWaitComplete(int result);
  127. int DoQuickCheck();
  128. int DoQuickCheckComplete(int result);
  129. int DoFetchPacScript();
  130. int DoFetchPacScriptComplete(int result);
  131. int DoVerifyPacScript();
  132. int DoVerifyPacScriptComplete(int result);
  133. // Tries restarting using the next fallback PAC URL:
  134. // |pac_sources_[++current_pac_source_index]|.
  135. // Returns OK and rewinds the state machine when there
  136. // is something to try, otherwise returns |error|.
  137. int TryToFallbackPacSource(int error);
  138. // Gets the initial state (we skip fetching when the
  139. // ProxyResolver doesn't |expect_pac_bytes()|.
  140. State GetStartState() const;
  141. void DetermineURL(const PacSource& pac_source, GURL* effective_pac_url);
  142. // Returns the current PAC URL we are fetching/testing.
  143. const PacSource& current_pac_source() const;
  144. void OnWaitTimerFired();
  145. void DidComplete();
  146. void Cancel();
  147. raw_ptr<PacFileFetcher> pac_file_fetcher_;
  148. raw_ptr<DhcpPacFileFetcher> dhcp_pac_file_fetcher_;
  149. CompletionOnceCallback callback_;
  150. size_t current_pac_source_index_ = 0u;
  151. // Filled when the PAC script fetch completes.
  152. std::u16string pac_script_;
  153. // Flag indicating whether the caller requested a mandatory PAC script
  154. // (i.e. fallback to direct connections are prohibited).
  155. bool pac_mandatory_ = false;
  156. // Whether we have an existing custom PAC URL.
  157. bool have_custom_pac_url_;
  158. PacSourceList pac_sources_;
  159. State next_state_ = STATE_NONE;
  160. NetLogWithSource net_log_;
  161. bool fetch_pac_bytes_ = false;
  162. base::TimeDelta wait_delay_;
  163. base::OneShotTimer wait_timer_;
  164. net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
  165. // Whether to do DNS quick check
  166. bool quick_check_enabled_ = true;
  167. // Results.
  168. ProxyConfigWithAnnotation effective_config_;
  169. PacFileDataWithSource script_data_;
  170. std::unique_ptr<HostResolver::ResolveHostRequest> resolve_request_;
  171. base::OneShotTimer quick_check_timer_;
  172. };
  173. } // namespace net
  174. #endif // NET_PROXY_RESOLUTION_PAC_FILE_DECIDER_H_