1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Malcolm Smith <malsmith@cs.rmit.edu.au>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef nsProtocolProxyService_h__
40 : #define nsProtocolProxyService_h__
41 :
42 : #include "nsString.h"
43 : #include "nsCOMPtr.h"
44 : #include "nsAutoPtr.h"
45 : #include "nsTArray.h"
46 : #include "nsIPrefBranch.h"
47 : #include "nsIProtocolProxyService2.h"
48 : #include "nsIProtocolProxyFilter.h"
49 : #include "nsIProxyAutoConfig.h"
50 : #include "nsISystemProxySettings.h"
51 : #include "nsIProxyInfo.h"
52 : #include "nsIObserver.h"
53 : #include "nsDataHashtable.h"
54 : #include "nsHashKeys.h"
55 : #include "nsPACMan.h"
56 : #include "prtime.h"
57 : #include "prmem.h"
58 : #include "prio.h"
59 :
60 : typedef nsDataHashtable<nsCStringHashKey, PRUint32> nsFailedProxyTable;
61 :
62 : class nsProxyInfo;
63 : struct nsProtocolInfo;
64 :
65 : class nsProtocolProxyService : public nsIProtocolProxyService2
66 : , public nsIObserver
67 : {
68 : public:
69 : NS_DECL_ISUPPORTS
70 : NS_DECL_NSIPROTOCOLPROXYSERVICE2
71 : NS_DECL_NSIPROTOCOLPROXYSERVICE
72 : NS_DECL_NSIOBSERVER
73 :
74 : nsProtocolProxyService() NS_HIDDEN;
75 :
76 : NS_HIDDEN_(nsresult) Init();
77 :
78 : protected:
79 : friend class nsAsyncResolveRequest;
80 :
81 : ~nsProtocolProxyService() NS_HIDDEN;
82 :
83 : /**
84 : * This method is called whenever a preference may have changed or
85 : * to initialize all preferences.
86 : *
87 : * @param prefs
88 : * This must be a pointer to the root pref branch.
89 : * @param name
90 : * This can be the name of a fully-qualified preference, or it can
91 : * be null, in which case all preferences will be initialized.
92 : */
93 : NS_HIDDEN_(void) PrefsChanged(nsIPrefBranch *prefs, const char *name);
94 :
95 : /**
96 : * This method is called to create a nsProxyInfo instance from the given
97 : * PAC-style proxy string. It parses up to the end of the string, or to
98 : * the next ';' character.
99 : *
100 : * @param proxy
101 : * The PAC-style proxy string to parse. This must not be null.
102 : * @param aResolveFlags
103 : * The flags passed to Resolve or AsyncResolve that are stored in
104 : * proxyInfo.
105 : * @param result
106 : * Upon return this points to a newly allocated nsProxyInfo or null
107 : * if the proxy string was invalid.
108 : *
109 : * @return A pointer beyond the parsed proxy string (never null).
110 : */
111 : NS_HIDDEN_(const char *) ExtractProxyInfo(const char *proxy,
112 : PRUint32 aResolveFlags,
113 : nsProxyInfo **result);
114 :
115 : /**
116 : * Load the specified PAC file.
117 : *
118 : * @param pacURI
119 : * The URI spec of the PAC file to load.
120 : */
121 : NS_HIDDEN_(nsresult) ConfigureFromPAC(const nsCString &pacURI, bool forceReload);
122 :
123 : /**
124 : * This method builds a list of nsProxyInfo objects from the given PAC-
125 : * style string.
126 : *
127 : * @param pacString
128 : * The PAC-style proxy string to parse. This may be empty.
129 : * @param aResolveFlags
130 : * The flags passed to Resolve or AsyncResolve that are stored in
131 : * proxyInfo.
132 : * @param result
133 : * The resulting list of proxy info objects.
134 : */
135 : NS_HIDDEN_(void) ProcessPACString(const nsCString &pacString,
136 : PRUint32 aResolveFlags,
137 : nsIProxyInfo **result);
138 :
139 : /**
140 : * This method generates a string valued identifier for the given
141 : * nsProxyInfo object.
142 : *
143 : * @param pi
144 : * The nsProxyInfo object from which to generate the key.
145 : * @param result
146 : * Upon return, this parameter holds the generated key.
147 : */
148 : NS_HIDDEN_(void) GetProxyKey(nsProxyInfo *pi, nsCString &result);
149 :
150 : /**
151 : * @return Seconds since start of session.
152 : */
153 : NS_HIDDEN_(PRUint32) SecondsSinceSessionStart();
154 :
155 : /**
156 : * This method removes the specified proxy from the disabled list.
157 : *
158 : * @param pi
159 : * The nsProxyInfo object identifying the proxy to enable.
160 : */
161 : NS_HIDDEN_(void) EnableProxy(nsProxyInfo *pi);
162 :
163 : /**
164 : * This method adds the specified proxy to the disabled list.
165 : *
166 : * @param pi
167 : * The nsProxyInfo object identifying the proxy to disable.
168 : */
169 : NS_HIDDEN_(void) DisableProxy(nsProxyInfo *pi);
170 :
171 : /**
172 : * This method tests to see if the given proxy is disabled.
173 : *
174 : * @param pi
175 : * The nsProxyInfo object identifying the proxy to test.
176 : *
177 : * @return True if the specified proxy is disabled.
178 : */
179 : NS_HIDDEN_(bool) IsProxyDisabled(nsProxyInfo *pi);
180 :
181 : /**
182 : * This method queries the protocol handler for the given scheme to check
183 : * for the protocol flags and default port.
184 : *
185 : * @param uri
186 : * The URI to query.
187 : * @param info
188 : * Holds information about the protocol upon return. Pass address
189 : * of structure when you call this method. This parameter must not
190 : * be null.
191 : */
192 : NS_HIDDEN_(nsresult) GetProtocolInfo(nsIURI *uri, nsProtocolInfo *result);
193 :
194 : /**
195 : * This method is an internal version nsIProtocolProxyService::newProxyInfo
196 : * that expects a string literal for the type.
197 : *
198 : * @param type
199 : * The proxy type.
200 : * @param host
201 : * The proxy host name (UTF-8 ok).
202 : * @param port
203 : * The proxy port number.
204 : * @param flags
205 : * The proxy flags (nsIProxyInfo::flags).
206 : * @param timeout
207 : * The failover timeout for this proxy.
208 : * @param next
209 : * The next proxy to try if this one fails.
210 : * @param aResolveFlags
211 : * The flags passed to resolve (from nsIProtocolProxyService).
212 : * @param result
213 : * The resulting nsIProxyInfo object.
214 : */
215 : NS_HIDDEN_(nsresult) NewProxyInfo_Internal(const char *type,
216 : const nsACString &host,
217 : PRInt32 port,
218 : PRUint32 flags,
219 : PRUint32 timeout,
220 : nsIProxyInfo *next,
221 : PRUint32 aResolveFlags,
222 : nsIProxyInfo **result);
223 :
224 : /**
225 : * This method is an internal version of Resolve that does not query PAC.
226 : * It performs all of the built-in processing, and reports back to the
227 : * caller with either the proxy info result or a flag to instruct the
228 : * caller to use PAC instead.
229 : *
230 : * @param uri
231 : * The URI to test.
232 : * @param info
233 : * Information about the URI's protocol.
234 : * @param flags
235 : * The flags passed to either the resolve or the asyncResolve method.
236 : * @param usePAC
237 : * If this flag is set upon return, then PAC should be queried to
238 : * resolve the proxy info.
239 : * @param result
240 : * The resulting proxy info or null.
241 : */
242 : NS_HIDDEN_(nsresult) Resolve_Internal(nsIURI *uri,
243 : const nsProtocolInfo &info,
244 : PRUint32 flags,
245 : bool *usePAC,
246 : nsIProxyInfo **result);
247 :
248 : /**
249 : * This method applies the registered filters to the given proxy info
250 : * list, and returns a possibly modified list.
251 : *
252 : * @param uri
253 : * The URI corresponding to this proxy info list.
254 : * @param info
255 : * Information about the URI's protocol.
256 : * @param proxyInfo
257 : * The proxy info list to be modified. This is an inout param.
258 : */
259 : NS_HIDDEN_(void) ApplyFilters(nsIURI *uri, const nsProtocolInfo &info,
260 : nsIProxyInfo **proxyInfo);
261 :
262 : /**
263 : * This method is a simple wrapper around ApplyFilters that takes the
264 : * proxy info list inout param as a nsCOMPtr.
265 : */
266 12 : inline void ApplyFilters(nsIURI *uri, const nsProtocolInfo &info,
267 : nsCOMPtr<nsIProxyInfo> &proxyInfo)
268 : {
269 12 : nsIProxyInfo *pi = nsnull;
270 12 : proxyInfo.swap(pi);
271 12 : ApplyFilters(uri, info, &pi);
272 12 : proxyInfo.swap(pi);
273 12 : }
274 :
275 : /**
276 : * This method prunes out disabled and disallowed proxies from a given
277 : * proxy info list.
278 : *
279 : * @param info
280 : * Information about the URI's protocol.
281 : * @param proxyInfo
282 : * The proxy info list to be modified. This is an inout param.
283 : */
284 : NS_HIDDEN_(void) PruneProxyInfo(const nsProtocolInfo &info,
285 : nsIProxyInfo **proxyInfo);
286 :
287 : /**
288 : * This method populates mHostFiltersArray from the given string.
289 : *
290 : * @param hostFilters
291 : * A "no-proxy-for" exclusion list.
292 : */
293 : NS_HIDDEN_(void) LoadHostFilters(const char *hostFilters);
294 :
295 : /**
296 : * This method checks the given URI against mHostFiltersArray.
297 : *
298 : * @param uri
299 : * The URI to test.
300 : * @param defaultPort
301 : * The default port for the given URI.
302 : *
303 : * @return True if the URI can use the specified proxy.
304 : */
305 : NS_HIDDEN_(bool) CanUseProxy(nsIURI *uri, PRInt32 defaultPort);
306 :
307 : public:
308 : // The Sun Forte compiler and others implement older versions of the
309 : // C++ standard's rules on access and nested classes. These structs
310 : // need to be public in order to deal with those compilers.
311 :
312 : struct HostInfoIP {
313 : PRUint16 family;
314 : PRUint16 mask_len;
315 : PRIPv6Addr addr; // possibly IPv4-mapped address
316 : };
317 :
318 : struct HostInfoName {
319 : char *host;
320 : PRUint32 host_len;
321 : };
322 :
323 : protected:
324 :
325 : // simplified array of filters defined by this struct
326 : struct HostInfo {
327 : bool is_ipaddr;
328 : PRInt32 port;
329 : union {
330 : HostInfoIP ip;
331 : HostInfoName name;
332 : };
333 :
334 564 : HostInfo()
335 564 : : is_ipaddr(false)
336 564 : { /* other members intentionally uninitialized */ }
337 564 : ~HostInfo() {
338 564 : if (!is_ipaddr && name.host)
339 287 : nsMemory::Free(name.host);
340 564 : }
341 : };
342 :
343 : // This structure is allocated for each registered nsIProtocolProxyFilter.
344 : struct FilterLink {
345 : struct FilterLink *next;
346 : PRUint32 position;
347 : nsCOMPtr<nsIProtocolProxyFilter> filter;
348 :
349 4 : FilterLink(PRUint32 p, nsIProtocolProxyFilter *f)
350 4 : : next(nsnull), position(p), filter(f) {}
351 :
352 : // Chain deletion to simplify cleaning up the filter links
353 8 : ~FilterLink() { if (next) delete next; }
354 : };
355 :
356 : // Indicates if local hosts (plain hostnames, no dots) should use the proxy
357 : bool mFilterLocalHosts;
358 :
359 : // Holds an array of HostInfo objects
360 : nsTArray<nsAutoPtr<HostInfo> > mHostFiltersArray;
361 :
362 : // Points to the start of a sorted by position, singly linked list
363 : // of FilterLink objects.
364 : FilterLink *mFilters;
365 :
366 : PRUint32 mProxyConfig;
367 :
368 : nsCString mHTTPProxyHost;
369 : PRInt32 mHTTPProxyPort;
370 :
371 : nsCString mFTPProxyHost;
372 : PRInt32 mFTPProxyPort;
373 :
374 : nsCString mHTTPSProxyHost;
375 : PRInt32 mHTTPSProxyPort;
376 :
377 : nsCString mSOCKSProxyHost;
378 : PRInt32 mSOCKSProxyPort;
379 : PRInt32 mSOCKSProxyVersion;
380 : bool mSOCKSProxyRemoteDNS;
381 :
382 : nsRefPtr<nsPACMan> mPACMan; // non-null if we are using PAC
383 : nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
384 :
385 : PRTime mSessionStart;
386 : nsFailedProxyTable mFailedProxies;
387 : PRInt32 mFailedProxyTimeout;
388 : };
389 :
390 : #endif // !nsProtocolProxyService_h__
|