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.
5 #ifndef NET_PROXY_PROXY_SCRIPT_DECIDER_H_
6 #define NET_PROXY_PROXY_SCRIPT_DECIDER_H_
11 #include "base/memory/ref_counted.h"
12 #include "base/string16.h"
13 #include "base/time.h"
14 #include "base/timer.h"
15 #include "googleurl/src/gurl.h"
16 #include "net/base/completion_callback.h"
17 #include "net/base/net_export.h"
18 #include "net/base/net_log.h"
19 #include "net/proxy/proxy_config.h"
20 #include "net/proxy/proxy_resolver.h"
24 class DhcpProxyScriptFetcher
;
25 class NetLogParameter
;
27 class ProxyScriptFetcher
;
29 // ProxyScriptDecider is a helper class used by ProxyService to determine which
30 // PAC script to use given our proxy configuration.
32 // This involves trying to use PAC scripts in this order:
34 // (1) WPAD (DHCP) if auto-detect is on.
35 // (2) WPAD (DNS) if auto-detect is on.
36 // (3) Custom PAC script if a URL was given.
38 // If no PAC script was successfully selected, then it fails with either a
39 // network error, or PAC_SCRIPT_FAILED (indicating it did not pass our
42 // On successful completion, the fetched PAC script data can be accessed using
45 // Deleting ProxyScriptDecider while Init() is in progress, will
46 // cancel the request.
48 class NET_EXPORT_PRIVATE ProxyScriptDecider
{
50 // |proxy_script_fetcher|, |dhcp_proxy_script_fetcher| and
51 // |net_log| must remain valid for the lifespan of ProxyScriptDecider.
52 ProxyScriptDecider(ProxyScriptFetcher
* proxy_script_fetcher
,
53 DhcpProxyScriptFetcher
* dhcp_proxy_script_fetcher
,
56 // Aborts any in-progress request.
57 ~ProxyScriptDecider();
59 // Evaluates the effective proxy settings for |config|, and downloads the
60 // associated PAC script.
61 // If |wait_delay| is positive, the initialization will pause for this
62 // amount of time before getting started.
63 // On successful completion, the "effective" proxy settings we ended up
64 // deciding on will be available vial the effective_settings() accessor.
65 // Note that this may differ from |config| since we will have stripped any
66 // manual settings, and decided whether to use auto-detect or the custom PAC
67 // URL. Finally, if auto-detect was used we may now have resolved that to a
68 // specific script URL.
69 int Start(const ProxyConfig
& config
,
70 const base::TimeDelta wait_delay
,
72 const net::CompletionCallback
& callback
);
74 const ProxyConfig
& effective_config() const;
76 // TODO(eroman): Return a const-pointer.
77 ProxyResolverScriptData
* script_data() const;
80 // Represents the sources from which we can get PAC files; two types of
81 // auto-detect or a custom URL.
89 PacSource(Type type
, const GURL
& url
)
90 : type(type
), url(url
) {}
92 // Returns a Value representing the PacSource. |effective_pac_url| must
93 // be non-NULL and point to the URL derived from information contained in
94 // |this|, if Type is not WPAD_DHCP.
95 base::Value
* NetLogCallback(const GURL
* effective_pac_url
,
96 NetLog::LogLevel log_level
) const;
99 GURL url
; // Empty unless |type == PAC_SOURCE_CUSTOM|.
102 typedef std::vector
<PacSource
> PacSourceList
;
108 STATE_FETCH_PAC_SCRIPT
,
109 STATE_FETCH_PAC_SCRIPT_COMPLETE
,
110 STATE_VERIFY_PAC_SCRIPT
,
111 STATE_VERIFY_PAC_SCRIPT_COMPLETE
,
114 // Returns ordered list of PAC urls to try for |config|.
115 PacSourceList
BuildPacSourcesFallbackList(const ProxyConfig
& config
) const;
117 void OnIOCompletion(int result
);
118 int DoLoop(int result
);
119 void DoCallback(int result
);
122 int DoWaitComplete(int result
);
124 int DoFetchPacScript();
125 int DoFetchPacScriptComplete(int result
);
127 int DoVerifyPacScript();
128 int DoVerifyPacScriptComplete(int result
);
130 // Tries restarting using the next fallback PAC URL:
131 // |pac_sources_[++current_pac_source_index]|.
132 // Returns OK and rewinds the state machine when there
133 // is something to try, otherwise returns |error|.
134 int TryToFallbackPacSource(int error
);
136 // Gets the initial state (we skip fetching when the
137 // ProxyResolver doesn't |expect_pac_bytes()|.
138 State
GetStartState() const;
140 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;
145 void OnWaitTimerFired();
149 ProxyResolver
* resolver_
;
150 ProxyScriptFetcher
* proxy_script_fetcher_
;
151 DhcpProxyScriptFetcher
* dhcp_proxy_script_fetcher_
;
153 net::CompletionCallback callback_
;
155 size_t current_pac_source_index_
;
157 // Filled when the PAC script fetch completes.
158 string16 pac_script_
;
160 // Flag indicating whether the caller requested a mandatory pac script
161 // (i.e. fallback to direct connections are prohibited).
164 PacSourceList pac_sources_
;
167 BoundNetLog net_log_
;
169 bool fetch_pac_bytes_
;
171 base::TimeDelta wait_delay_
;
172 base::OneShotTimer
<ProxyScriptDecider
> wait_timer_
;
175 ProxyConfig effective_config_
;
176 scoped_refptr
<ProxyResolverScriptData
> script_data_
;
179 DISALLOW_COPY_AND_ASSIGN(ProxyScriptDecider
);
184 #endif // NET_PROXY_PROXY_SCRIPT_DECIDER_H_