| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_PROXY_PAC_FILE_DECIDER_H_ |
| #define NET_PROXY_PAC_FILE_DECIDER_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/macros.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/strings/string16.h" |
| #include "base/time/time.h" |
| #include "base/timer/timer.h" |
| #include "net/base/address_list.h" |
| #include "net/base/completion_once_callback.h" |
| #include "net/base/net_export.h" |
| #include "net/dns/host_resolver.h" |
| #include "net/log/net_log_with_source.h" |
| #include "net/proxy_resolution/proxy_config_with_annotation.h" |
| #include "net/proxy_resolution/proxy_resolver.h" |
| #include "starboard/types.h" |
| #include "url/gurl.h" |
| |
| namespace base { |
| class Value; |
| } |
| |
| namespace net { |
| |
| class DhcpPacFileFetcher; |
| class NetLog; |
| class NetLogCaptureMode; |
| class ProxyResolver; |
| class PacFileFetcher; |
| |
| // PacFileDecider is a helper class used by ProxyResolutionService to |
| // determine which PAC script to use given our proxy configuration. |
| // |
| // This involves trying to use PAC scripts in this order: |
| // |
| // (1) WPAD (DHCP) if auto-detect is on. |
| // (2) WPAD (DNS) if auto-detect is on. |
| // (3) Custom PAC script if a URL was given. |
| // |
| // If no PAC script was successfully selected, then it fails with either a |
| // network error, or PAC_SCRIPT_FAILED (indicating it did not pass our |
| // validation). |
| // |
| // On successful completion, the fetched PAC script data can be accessed using |
| // script_data(). |
| // |
| // Deleting PacFileDecider while Init() is in progress, will |
| // cancel the request. |
| // |
| class NET_EXPORT_PRIVATE PacFileDecider { |
| public: |
| // |pac_file_fetcher|, |dhcp_pac_file_fetcher| and |
| // |net_log| must remain valid for the lifespan of PacFileDecider. |
| PacFileDecider(PacFileFetcher* pac_file_fetcher, |
| DhcpPacFileFetcher* dhcp_pac_file_fetcher, |
| NetLog* net_log); |
| |
| // Aborts any in-progress request. |
| ~PacFileDecider(); |
| |
| // Evaluates the effective proxy settings for |config|, and downloads the |
| // associated PAC script. |
| // If |wait_delay| is positive, the initialization will pause for this |
| // amount of time before getting started. |
| // On successful completion, the "effective" proxy settings we ended up |
| // deciding on will be available vial the effective_settings() accessor. |
| // Note that this may differ from |config| since we will have stripped any |
| // manual settings, and decided whether to use auto-detect or the custom PAC |
| // URL. Finally, if auto-detect was used we may now have resolved that to a |
| // specific script URL. |
| int Start(const ProxyConfigWithAnnotation& config, |
| const base::TimeDelta wait_delay, |
| bool fetch_pac_bytes, |
| CompletionOnceCallback callback); |
| |
| // Shuts down any in-progress DNS requests, and cancels any ScriptFetcher |
| // requests. Does not call OnShutdown on the [Dhcp]PacFileFetcher. |
| void OnShutdown(); |
| |
| const ProxyConfigWithAnnotation& effective_config() const; |
| |
| const scoped_refptr<PacFileData>& script_data() const; |
| |
| void set_quick_check_enabled(bool enabled) { quick_check_enabled_ = enabled; } |
| |
| bool quick_check_enabled() const { return quick_check_enabled_; } |
| |
| private: |
| // Represents the sources from which we can get PAC files; two types of |
| // auto-detect or a custom URL. |
| struct PacSource { |
| enum Type { WPAD_DHCP, WPAD_DNS, CUSTOM }; |
| |
| PacSource(Type type, const GURL& url) : type(type), url(url) {} |
| |
| // Returns a Value representing the PacSource. |effective_pac_url| must |
| // be non-NULL and point to the URL derived from information contained in |
| // |this|, if Type is not WPAD_DHCP. |
| std::unique_ptr<base::Value> NetLogCallback( |
| const GURL* effective_pac_url, |
| NetLogCaptureMode capture_mode) const; |
| |
| Type type; |
| GURL url; // Empty unless |type == PAC_SOURCE_CUSTOM|. |
| }; |
| |
| typedef std::vector<PacSource> PacSourceList; |
| |
| enum State { |
| STATE_NONE, |
| STATE_WAIT, |
| STATE_WAIT_COMPLETE, |
| STATE_QUICK_CHECK, |
| STATE_QUICK_CHECK_COMPLETE, |
| STATE_FETCH_PAC_SCRIPT, |
| STATE_FETCH_PAC_SCRIPT_COMPLETE, |
| STATE_VERIFY_PAC_SCRIPT, |
| STATE_VERIFY_PAC_SCRIPT_COMPLETE, |
| }; |
| |
| // Returns ordered list of PAC urls to try for |config|. |
| PacSourceList BuildPacSourcesFallbackList(const ProxyConfig& config) const; |
| |
| void OnIOCompletion(int result); |
| int DoLoop(int result); |
| |
| int DoWait(); |
| int DoWaitComplete(int result); |
| |
| int DoQuickCheck(); |
| int DoQuickCheckComplete(int result); |
| |
| int DoFetchPacScript(); |
| int DoFetchPacScriptComplete(int result); |
| |
| int DoVerifyPacScript(); |
| int DoVerifyPacScriptComplete(int result); |
| |
| // Tries restarting using the next fallback PAC URL: |
| // |pac_sources_[++current_pac_source_index]|. |
| // Returns OK and rewinds the state machine when there |
| // is something to try, otherwise returns |error|. |
| int TryToFallbackPacSource(int error); |
| |
| // Gets the initial state (we skip fetching when the |
| // ProxyResolver doesn't |expect_pac_bytes()|. |
| State GetStartState() const; |
| |
| void DetermineURL(const PacSource& pac_source, GURL* effective_pac_url); |
| |
| // Returns the current PAC URL we are fetching/testing. |
| const PacSource& current_pac_source() const; |
| |
| void OnWaitTimerFired(); |
| void DidComplete(); |
| void Cancel(); |
| |
| PacFileFetcher* pac_file_fetcher_; |
| DhcpPacFileFetcher* dhcp_pac_file_fetcher_; |
| |
| CompletionOnceCallback callback_; |
| |
| size_t current_pac_source_index_; |
| |
| // Filled when the PAC script fetch completes. |
| base::string16 pac_script_; |
| |
| // Flag indicating whether the caller requested a mandatory PAC script |
| // (i.e. fallback to direct connections are prohibited). |
| bool pac_mandatory_; |
| |
| // Whether we have an existing custom PAC URL. |
| bool have_custom_pac_url_; |
| |
| PacSourceList pac_sources_; |
| State next_state_; |
| |
| NetLogWithSource net_log_; |
| |
| bool fetch_pac_bytes_; |
| |
| base::TimeDelta wait_delay_; |
| base::OneShotTimer wait_timer_; |
| |
| net::MutableNetworkTrafficAnnotationTag traffic_annotation_; |
| |
| // Whether to do DNS quick check |
| bool quick_check_enabled_; |
| |
| // Results. |
| ProxyConfigWithAnnotation effective_config_; |
| scoped_refptr<PacFileData> script_data_; |
| |
| AddressList wpad_addresses_; |
| base::OneShotTimer quick_check_timer_; |
| std::unique_ptr<HostResolver::Request> request_; |
| base::Time quick_check_start_time_; |
| |
| DISALLOW_COPY_AND_ASSIGN(PacFileDecider); |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_PROXY_PAC_FILE_DECIDER_H_ |