OLD | NEW |
| (Empty) |
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 | |
5 #ifndef NET_PROXY_PROXY_SCRIPT_DECIDER_H_ | |
6 #define NET_PROXY_PROXY_SCRIPT_DECIDER_H_ | |
7 | |
8 #include <string> | |
9 #include <vector> | |
10 | |
11 #include "base/memory/ref_counted.h" | |
12 #include "base/strings/string16.h" | |
13 #include "base/time/time.h" | |
14 #include "base/timer/timer.h" | |
15 #include "net/base/address_list.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/dns/host_resolver.h" | |
20 #include "net/dns/single_request_host_resolver.h" | |
21 #include "net/proxy/proxy_config.h" | |
22 #include "net/proxy/proxy_resolver.h" | |
23 #include "url/gurl.h" | |
24 | |
25 namespace net { | |
26 | |
27 class DhcpProxyScriptFetcher; | |
28 class NetLogParameter; | |
29 class ProxyResolver; | |
30 class ProxyScriptFetcher; | |
31 | |
32 // ProxyScriptDecider is a helper class used by ProxyService to determine which | |
33 // PAC script to use given our proxy configuration. | |
34 // | |
35 // This involves trying to use PAC scripts in this order: | |
36 // | |
37 // (1) WPAD (DHCP) if auto-detect is on. | |
38 // (2) WPAD (DNS) if auto-detect is on. | |
39 // (3) Custom PAC script if a URL was given. | |
40 // | |
41 // If no PAC script was successfully selected, then it fails with either a | |
42 // network error, or PAC_SCRIPT_FAILED (indicating it did not pass our | |
43 // validation). | |
44 // | |
45 // On successful completion, the fetched PAC script data can be accessed using | |
46 // script_data(). | |
47 // | |
48 // Deleting ProxyScriptDecider while Init() is in progress, will | |
49 // cancel the request. | |
50 // | |
51 class NET_EXPORT_PRIVATE ProxyScriptDecider { | |
52 public: | |
53 // |proxy_script_fetcher|, |dhcp_proxy_script_fetcher| and | |
54 // |net_log| must remain valid for the lifespan of ProxyScriptDecider. | |
55 ProxyScriptDecider(ProxyScriptFetcher* proxy_script_fetcher, | |
56 DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher, | |
57 NetLog* net_log); | |
58 | |
59 // Aborts any in-progress request. | |
60 ~ProxyScriptDecider(); | |
61 | |
62 // Evaluates the effective proxy settings for |config|, and downloads the | |
63 // associated PAC script. | |
64 // If |wait_delay| is positive, the initialization will pause for this | |
65 // amount of time before getting started. | |
66 // On successful completion, the "effective" proxy settings we ended up | |
67 // deciding on will be available vial the effective_settings() accessor. | |
68 // Note that this may differ from |config| since we will have stripped any | |
69 // manual settings, and decided whether to use auto-detect or the custom PAC | |
70 // URL. Finally, if auto-detect was used we may now have resolved that to a | |
71 // specific script URL. | |
72 int Start(const ProxyConfig& config, | |
73 const base::TimeDelta wait_delay, | |
74 bool fetch_pac_bytes, | |
75 const net::CompletionCallback& callback); | |
76 | |
77 const ProxyConfig& effective_config() const; | |
78 | |
79 // TODO(eroman): Return a const-pointer. | |
80 ProxyResolverScriptData* script_data() const; | |
81 | |
82 void set_quick_check_enabled(bool enabled) { | |
83 quick_check_enabled_ = enabled; | |
84 } | |
85 | |
86 bool quick_check_enabled() const { return quick_check_enabled_; } | |
87 | |
88 private: | |
89 // Represents the sources from which we can get PAC files; two types of | |
90 // auto-detect or a custom URL. | |
91 struct PacSource { | |
92 enum Type { | |
93 WPAD_DHCP, | |
94 WPAD_DNS, | |
95 CUSTOM | |
96 }; | |
97 | |
98 PacSource(Type type, const GURL& url) | |
99 : type(type), url(url) {} | |
100 | |
101 // Returns a Value representing the PacSource. |effective_pac_url| must | |
102 // be non-NULL and point to the URL derived from information contained in | |
103 // |this|, if Type is not WPAD_DHCP. | |
104 base::Value* NetLogCallback(const GURL* effective_pac_url, | |
105 NetLog::LogLevel log_level) const; | |
106 | |
107 Type type; | |
108 GURL url; // Empty unless |type == PAC_SOURCE_CUSTOM|. | |
109 }; | |
110 | |
111 typedef std::vector<PacSource> PacSourceList; | |
112 | |
113 enum State { | |
114 STATE_NONE, | |
115 STATE_WAIT, | |
116 STATE_WAIT_COMPLETE, | |
117 STATE_QUICK_CHECK, | |
118 STATE_QUICK_CHECK_COMPLETE, | |
119 STATE_FETCH_PAC_SCRIPT, | |
120 STATE_FETCH_PAC_SCRIPT_COMPLETE, | |
121 STATE_VERIFY_PAC_SCRIPT, | |
122 STATE_VERIFY_PAC_SCRIPT_COMPLETE, | |
123 }; | |
124 | |
125 // Returns ordered list of PAC urls to try for |config|. | |
126 PacSourceList BuildPacSourcesFallbackList(const ProxyConfig& config) const; | |
127 | |
128 void OnIOCompletion(int result); | |
129 int DoLoop(int result); | |
130 void DoCallback(int result); | |
131 | |
132 int DoWait(); | |
133 int DoWaitComplete(int result); | |
134 | |
135 int DoQuickCheck(); | |
136 int DoQuickCheckComplete(int result); | |
137 | |
138 int DoFetchPacScript(); | |
139 int DoFetchPacScriptComplete(int result); | |
140 | |
141 int DoVerifyPacScript(); | |
142 int DoVerifyPacScriptComplete(int result); | |
143 | |
144 // Tries restarting using the next fallback PAC URL: | |
145 // |pac_sources_[++current_pac_source_index]|. | |
146 // Returns OK and rewinds the state machine when there | |
147 // is something to try, otherwise returns |error|. | |
148 int TryToFallbackPacSource(int error); | |
149 | |
150 // Gets the initial state (we skip fetching when the | |
151 // ProxyResolver doesn't |expect_pac_bytes()|. | |
152 State GetStartState() const; | |
153 | |
154 void DetermineURL(const PacSource& pac_source, GURL* effective_pac_url); | |
155 | |
156 // Returns the current PAC URL we are fetching/testing. | |
157 const PacSource& current_pac_source() const; | |
158 | |
159 void OnWaitTimerFired(); | |
160 void DidComplete(); | |
161 void Cancel(); | |
162 | |
163 ProxyScriptFetcher* proxy_script_fetcher_; | |
164 DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher_; | |
165 | |
166 net::CompletionCallback callback_; | |
167 | |
168 size_t current_pac_source_index_; | |
169 | |
170 // Filled when the PAC script fetch completes. | |
171 base::string16 pac_script_; | |
172 | |
173 // Flag indicating whether the caller requested a mandatory pac script | |
174 // (i.e. fallback to direct connections are prohibited). | |
175 bool pac_mandatory_; | |
176 | |
177 // Whether we have an existing custom PAC URL. | |
178 bool have_custom_pac_url_; | |
179 | |
180 PacSourceList pac_sources_; | |
181 State next_state_; | |
182 | |
183 BoundNetLog net_log_; | |
184 | |
185 bool fetch_pac_bytes_; | |
186 | |
187 base::TimeDelta wait_delay_; | |
188 base::OneShotTimer<ProxyScriptDecider> wait_timer_; | |
189 | |
190 // Whether to do DNS quick check | |
191 bool quick_check_enabled_; | |
192 | |
193 // Results. | |
194 ProxyConfig effective_config_; | |
195 scoped_refptr<ProxyResolverScriptData> script_data_; | |
196 | |
197 AddressList wpad_addresses_; | |
198 base::OneShotTimer<ProxyScriptDecider> quick_check_timer_; | |
199 scoped_ptr<SingleRequestHostResolver> host_resolver_; | |
200 base::Time quick_check_start_time_; | |
201 | |
202 DISALLOW_COPY_AND_ASSIGN(ProxyScriptDecider); | |
203 }; | |
204 | |
205 } // namespace net | |
206 | |
207 #endif // NET_PROXY_PROXY_SCRIPT_DECIDER_H_ | |
OLD | NEW |