Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: net/proxy/single_threaded_proxy_resolver.h

Issue 149525: Remove the concept of threading from ProxyService, and move it into the Proxy... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Add missing header for mac Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/proxy/proxy_service_unittest.cc ('k') | net/proxy/single_threaded_proxy_resolver.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef NET_PROXY_PROXY_SERVICE_H_ 5 #ifndef NET_PROXY_SINGLE_THREADED_PROXY_RESOLVER_H_
6 #define NET_PROXY_PROXY_SERVICE_H_ 6 #define NET_PROXY_SINGLE_THREADED_PROXY_RESOLVER_H_
7 7
8 #include <deque> 8 #include <deque>
9 #include <string> 9 #include <string>
10 10
11 #include "base/ref_counted.h" 11 #include "base/ref_counted.h"
12 #include "base/scoped_ptr.h" 12 #include "base/scoped_ptr.h"
13 #include "base/thread.h" 13 #include "net/proxy/proxy_resolver.h"
14 #include "base/waitable_event.h"
15 #include "net/base/completion_callback.h"
16 #include "net/proxy/proxy_server.h"
17 #include "net/proxy/proxy_info.h"
18 14
19 class GURL; 15 namespace base {
20 class URLRequestContext; 16 class Thread;
17 } // namespace base
21 18
22 namespace net { 19 namespace net {
23 20
24 class ProxyScriptFetcher; 21 // ProxyResolver implementation that wraps a synchronous ProxyResolver, and
25 class ProxyConfigService; 22 // runs it on a single worker thread. If multiple requests accumulate, they
26 class ProxyResolver; 23 // are serviced in FIFO order.
24 class SingleThreadedProxyResolver : public ProxyResolver {
25 public:
27 26
28 // This class can be used to resolve the proxy server to use when loading a 27 // |resolver| is a synchronous ProxyResolver implementation. It doesn't
29 // HTTP(S) URL. It uses the given ProxyResolver to handle the actual proxy 28 // have to be thread-safe, since it is run on exactly one thread. The
30 // resolution. See ProxyResolverWinHttp for example. 29 // constructor takes ownership of |resolver|.
31 class ProxyService { 30 explicit SingleThreadedProxyResolver(ProxyResolver* resolver);
32 public:
33 // The instance takes ownership of |config_service| and |resolver|.
34 ProxyService(ProxyConfigService* config_service,
35 ProxyResolver* resolver);
36 31
37 ~ProxyService(); 32 virtual ~SingleThreadedProxyResolver();
38 33
39 // Used internally to handle PAC queries. 34 // ProxyResolver implementation:
40 class PacRequest; 35 virtual int GetProxyForURL(const GURL& url,
36 ProxyInfo* results,
37 CompletionCallback* callback,
38 RequestHandle* request);
39 virtual void CancelRequest(RequestHandle request);
41 40
42 // Returns ERR_IO_PENDING if the proxy information could not be provided 41 protected:
43 // synchronously, to indicate that the result will be available when the 42 // The wrapped (synchronous) ProxyResolver.
44 // callback is run. The callback is run on the thread that calls 43 ProxyResolver* resolver() { return resolver_.get(); }
45 // ResolveProxy.
46 //
47 // The caller is responsible for ensuring that |results| and |callback|
48 // remain valid until the callback is run or until |pac_request| is cancelled
49 // via CancelPacRequest. |pac_request| is only valid while the completion
50 // callback is still pending. NULL can be passed for |pac_request| if
51 // the caller will not need to cancel the request.
52 //
53 // We use the three possible proxy access types in the following order, and
54 // we only use one of them (no falling back to other access types if the
55 // chosen one doesn't work).
56 // 1. named proxy
57 // 2. PAC URL
58 // 3. WPAD auto-detection
59 //
60 int ResolveProxy(const GURL& url,
61 ProxyInfo* results,
62 CompletionCallback* callback,
63 PacRequest** pac_request);
64
65 // This method is called after a failure to connect or resolve a host name.
66 // It gives the proxy service an opportunity to reconsider the proxy to use.
67 // The |results| parameter contains the results returned by an earlier call
68 // to ResolveProxy. The semantics of this call are otherwise similar to
69 // ResolveProxy.
70 //
71 // NULL can be passed for |pac_request| if the caller will not need to
72 // cancel the request.
73 //
74 // Returns ERR_FAILED if there is not another proxy config to try.
75 //
76 int ReconsiderProxyAfterError(const GURL& url,
77 ProxyInfo* results,
78 CompletionCallback* callback,
79 PacRequest** pac_request);
80
81 // Call this method with a non-null |pac_request| to cancel the PAC request.
82 void CancelPacRequest(PacRequest* pac_request);
83
84 // Sets the ProxyScriptFetcher dependency. This is needed if the ProxyResolver
85 // is of type ProxyResolverWithoutFetch. ProxyService takes ownership of
86 // |proxy_script_fetcher|.
87 void SetProxyScriptFetcher(ProxyScriptFetcher* proxy_script_fetcher);
88
89 // Tells this ProxyService to start using a new ProxyConfigService to
90 // retrieve its ProxyConfig from. The new ProxyConfigService will immediately
91 // be queried for new config info which will be used for all subsequent
92 // ResolveProxy calls. ProxyService takes ownership of
93 // |new_proxy_config_service|.
94 void ResetConfigService(ProxyConfigService* new_proxy_config_service);
95
96 // Creates a proxy service using the specified settings. If |pc| is NULL then
97 // the system's default proxy settings will be used (on Windows this will
98 // use IE's settings).
99 // Iff |use_v8_resolver| is true, then the V8 implementation is
100 // used.
101 // |url_request_context| is only used when use_v8_resolver is true:
102 // it specifies the URL request context that will be used if a PAC
103 // script needs to be fetched.
104 // |io_loop| points to the IO thread's message loop. It is only used
105 // when pc is NULL. If both pc and io_loop are NULL, then monitoring
106 // of gconf setting changes will be disabled in
107 // ProxyConfigServiceLinux.
108 // ##########################################################################
109 // # See the warnings in net/proxy/proxy_resolver_v8.h describing the
110 // # multi-threading model. In order for this to be safe to use, *ALL* the
111 // # other V8's running in the process must use v8::Locker.
112 // ##########################################################################
113 static ProxyService* Create(
114 const ProxyConfig* pc,
115 bool use_v8_resolver,
116 URLRequestContext* url_request_context,
117 MessageLoop* io_loop);
118
119 // Convenience method that creates a proxy service using the
120 // specified fixed settings. |pc| must not be NULL.
121 static ProxyService* CreateFixed(const ProxyConfig& pc);
122
123 // Creates a proxy service that always fails to fetch the proxy configuration,
124 // so it falls back to direct connect.
125 static ProxyService* CreateNull();
126 44
127 private: 45 private:
128 friend class PacRequest; 46 // Refcounted helper class that bridges between origin thread and worker
47 // thread.
48 class Job;
49 friend class Job;
50 // FIFO queue that contains the in-progress job, and any pending jobs.
51 typedef std::deque<scoped_refptr<Job> > PendingJobsQueue;
129 52
130 // Creates a config service appropriate for this platform that fetches the 53 base::Thread* thread() { return thread_.get(); }
131 // system proxy settings.
132 static ProxyConfigService* CreateSystemProxyConfigService(
133 MessageLoop* io_loop);
134 54
135 // Creates a proxy resolver appropriate for this platform that doesn't rely 55 // ProxyResolver implementation:
136 // on V8. 56 virtual void SetPacScriptByUrlInternal(const GURL& pac_url);
137 static ProxyResolver* CreateNonV8ProxyResolver(); 57 virtual void SetPacScriptByDataInternal(const std::string& bytes);
138 58
139 ProxyResolver* resolver() { return resolver_.get(); } 59 // Helper for shared code between SetPacScriptByUrlInternal() and
140 base::Thread* pac_thread() { return pac_thread_.get(); } 60 // SetPacScriptByDataInternal() -- the unused parameter is set to empty.
61 void SetPacScriptHelper(const GURL& pac_url, const std::string& bytes);
141 62
142 // Identifies the proxy configuration. 63 // Starts the worker thread if it isn't already running.
143 ProxyConfig::ID config_id() const { return config_.id(); } 64 void EnsureThreadStarted();
144 65
145 // Returns true if we have called UpdateConfig() at least once. 66 // Starts the next job from |pending_jobs_| if possible.
146 bool config_has_been_initialized() const { 67 void ProcessPendingJobs();
147 return config_.id() != ProxyConfig::INVALID_ID;
148 }
149 68
150 // Checks to see if the proxy configuration changed, and then updates config_ 69 // Removes the front entry of the jobs queue. |expected_job| is our
151 // to reference the new configuration. 70 // expectation of what the front of the job queue is; it is only used by
152 void UpdateConfig(); 71 // DCHECK for verification purposes.
72 void RemoveFrontOfJobsQueueAndStartNext(Job* expected_job);
153 73
154 // Assign |config| as the current configuration. 74 // The synchronous resolver implementation.
155 void SetConfig(const ProxyConfig& config); 75 scoped_ptr<ProxyResolver> resolver_;
156 76
157 // Tries to update the configuration if it hasn't been checked in a while. 77 // The thread where |resolver_| is run on.
158 void UpdateConfigIfOld(); 78 // Note that declaration ordering is important here. |thread_| needs to be
79 // destroyed *before* |resolver_|, in case |resolver_| is currently
80 // executing on |thread_|.
81 scoped_ptr<base::Thread> thread_;
159 82
160 // Returns true if this ProxyService is downloading a PAC script on behalf 83 PendingJobsQueue pending_jobs_;
161 // of ProxyResolverWithoutFetch. Resolve requests will be frozen until
162 // the fetch has completed.
163 bool IsFetchingPacScript() const {
164 return in_progress_fetch_config_id_ != ProxyConfig::INVALID_ID;
165 }
166
167 // Callback for when the PAC script has finished downloading.
168 void OnScriptFetchCompletion(int result);
169
170 // Returns ERR_IO_PENDING if the request cannot be completed synchronously.
171 // Otherwise it fills |result| with the proxy information for |url|.
172 // Completing synchronously means we don't need to query ProxyResolver.
173 // (ProxyResolver runs on PAC thread.)
174 int TryToCompleteSynchronously(const GURL& url, ProxyInfo* result);
175
176 // Set |result| with the proxy to use for |url|, based on |rules|.
177 void ApplyProxyRules(const GURL& url,
178 const ProxyConfig::ProxyRules& rules,
179 ProxyInfo* result);
180
181 // Starts the PAC thread if it isn't already running.
182 void InitPacThread();
183
184 // Starts the next request from |pending_requests_| is possible.
185 // |recent_req| is the request that just got added, or NULL.
186 void ProcessPendingRequests(PacRequest* recent_req);
187
188 // Removes the front entry of the requests queue. |expected_req| is our
189 // expectation of what the front of the request queue is; it is only used by
190 // DCHECK for verification purposes.
191 void RemoveFrontOfRequestQueue(PacRequest* expected_req);
192
193 // Called to indicate that a PacRequest completed. The |config_id| parameter
194 // indicates the proxy configuration that was queried. |result_code| is OK
195 // if the PAC file could be downloaded and executed. Otherwise, it is an
196 // error code, indicating a bad proxy configuration.
197 void DidCompletePacRequest(int config_id, int result_code);
198
199 // Returns true if the URL passed in should not go through the proxy server.
200 // 1. If the bypass proxy list contains the string <local> and the URL
201 // passed in is a local URL, i.e. a URL without a DOT (.)
202 // 2. The URL matches one of the entities in the proxy bypass list.
203 bool ShouldBypassProxyForURL(const GURL& url);
204
205 scoped_ptr<ProxyConfigService> config_service_;
206 scoped_ptr<ProxyResolver> resolver_;
207 scoped_ptr<base::Thread> pac_thread_;
208
209 // We store the proxy config and a counter (ID) that is incremented each time
210 // the config changes.
211 ProxyConfig config_;
212
213 // Increasing ID to give to the next ProxyConfig that we set.
214 int next_config_id_;
215
216 // Indicates that the configuration is bad and should be ignored.
217 bool config_is_bad_;
218
219 // The time when the proxy configuration was last read from the system.
220 base::TimeTicks config_last_update_time_;
221
222 // Map of the known bad proxies and the information about the retry time.
223 ProxyRetryInfoMap proxy_retry_info_;
224
225 // FIFO queue of pending/inprogress requests.
226 typedef std::deque<scoped_refptr<PacRequest> > PendingRequestsQueue;
227 PendingRequestsQueue pending_requests_;
228
229 // The fetcher to use when downloading PAC scripts for the ProxyResolver.
230 // This dependency can be NULL if our ProxyResolver has no need for
231 // external PAC script fetching.
232 scoped_ptr<ProxyScriptFetcher> proxy_script_fetcher_;
233
234 // Callback for when |proxy_script_fetcher_| is done.
235 CompletionCallbackImpl<ProxyService> proxy_script_fetcher_callback_;
236
237 // The ID of the configuration for which we last downloaded a PAC script.
238 // If no PAC script has been fetched yet, will be ProxyConfig::INVALID_ID.
239 ProxyConfig::ID fetched_pac_config_id_;
240
241 // The error corresponding with |fetched_pac_config_id_|, or OK.
242 int fetched_pac_error_;
243
244 // The ID of the configuration for which we are currently downloading the
245 // PAC script. If no fetch is in progress, will be ProxyConfig::INVALID_ID.
246 ProxyConfig::ID in_progress_fetch_config_id_;
247
248 // The results of the current in progress fetch, or empty string.
249 std::string in_progress_fetch_bytes_;
250
251 DISALLOW_COPY_AND_ASSIGN(ProxyService);
252 };
253
254 // Wrapper for invoking methods on a ProxyService synchronously.
255 class SyncProxyServiceHelper
256 : public base::RefCountedThreadSafe<SyncProxyServiceHelper> {
257 public:
258 SyncProxyServiceHelper(MessageLoop* io_message_loop,
259 ProxyService* proxy_service);
260
261 int ResolveProxy(const GURL& url, ProxyInfo* proxy_info);
262 int ReconsiderProxyAfterError(const GURL& url, ProxyInfo* proxy_info);
263
264 private:
265 void StartAsyncResolve(const GURL& url);
266 void StartAsyncReconsider(const GURL& url);
267
268 void OnCompletion(int result);
269
270 MessageLoop* io_message_loop_;
271 ProxyService* proxy_service_;
272
273 base::WaitableEvent event_;
274 CompletionCallbackImpl<SyncProxyServiceHelper> callback_;
275 ProxyInfo proxy_info_;
276 int result_;
277 }; 84 };
278 85
279 } // namespace net 86 } // namespace net
280 87
281 #endif // NET_PROXY_PROXY_SERVICE_H_ 88 #endif // NET_PROXY_SINGLE_THREADED_PROXY_RESOLVER_H_
OLDNEW
« no previous file with comments | « net/proxy/proxy_service_unittest.cc ('k') | net/proxy/single_threaded_proxy_resolver.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698