/src/mozilla-central/netwerk/base/nsProtocolProxyService.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #ifndef nsProtocolProxyService_h__ |
7 | | #define nsProtocolProxyService_h__ |
8 | | |
9 | | #include "nsString.h" |
10 | | #include "nsCOMPtr.h" |
11 | | #include "nsAutoPtr.h" |
12 | | #include "nsTArray.h" |
13 | | #include "nsIProtocolProxyService2.h" |
14 | | #include "nsIProtocolProxyFilter.h" |
15 | | #include "nsIProxyInfo.h" |
16 | | #include "nsIObserver.h" |
17 | | #include "nsIThread.h" |
18 | | #include "nsDataHashtable.h" |
19 | | #include "nsHashKeys.h" |
20 | | #include "prio.h" |
21 | | #include "mozilla/Attributes.h" |
22 | | |
23 | | class nsIPrefBranch; |
24 | | class nsISystemProxySettings; |
25 | | |
26 | | namespace mozilla { |
27 | | namespace net { |
28 | | |
29 | | typedef nsDataHashtable<nsCStringHashKey, uint32_t> nsFailedProxyTable; |
30 | | |
31 | | class nsPACMan; |
32 | | class nsProxyInfo; |
33 | | struct nsProtocolInfo; |
34 | | |
35 | | // CID for the nsProtocolProxyService class |
36 | | // 091eedd8-8bae-4fe3-ad62-0c87351e640d |
37 | | #define NS_PROTOCOL_PROXY_SERVICE_IMPL_CID \ |
38 | | { 0x091eedd8, 0x8bae, 0x4fe3, \ |
39 | | { 0xad, 0x62, 0x0c, 0x87, 0x35, 0x1e, 0x64, 0x0d } } |
40 | | |
41 | | class nsProtocolProxyService final : public nsIProtocolProxyService2 |
42 | | , public nsIObserver |
43 | | { |
44 | | public: |
45 | | NS_DECL_ISUPPORTS |
46 | | NS_DECL_NSIPROTOCOLPROXYSERVICE2 |
47 | | NS_DECL_NSIPROTOCOLPROXYSERVICE |
48 | | NS_DECL_NSIOBSERVER |
49 | | |
50 | | NS_DECLARE_STATIC_IID_ACCESSOR(NS_PROTOCOL_PROXY_SERVICE_IMPL_CID) |
51 | | |
52 | | nsProtocolProxyService(); |
53 | | |
54 | | nsresult Init(); |
55 | | |
56 | | public: |
57 | | // An instance of this struct is allocated for each registered |
58 | | // nsIProtocolProxyFilter and each nsIProtocolProxyChannelFilter. |
59 | | class FilterLink { |
60 | | public: |
61 | | NS_INLINE_DECL_REFCOUNTING(FilterLink) |
62 | | |
63 | | uint32_t position; |
64 | | nsCOMPtr<nsIProtocolProxyFilter> filter; |
65 | | nsCOMPtr<nsIProtocolProxyChannelFilter> channelFilter; |
66 | | |
67 | | FilterLink(uint32_t p, nsIProtocolProxyFilter *f); |
68 | | FilterLink(uint32_t p, nsIProtocolProxyChannelFilter *cf); |
69 | | |
70 | | private: |
71 | | ~FilterLink(); |
72 | | }; |
73 | | |
74 | | protected: |
75 | | friend class nsAsyncResolveRequest; |
76 | | friend class TestProtocolProxyService_LoadHostFilters_Test; // for gtest |
77 | | |
78 | | ~nsProtocolProxyService(); |
79 | | |
80 | | /** |
81 | | * This method is called whenever a preference may have changed or |
82 | | * to initialize all preferences. |
83 | | * |
84 | | * @param prefs |
85 | | * This must be a pointer to the root pref branch. |
86 | | * @param name |
87 | | * This can be the name of a fully-qualified preference, or it can |
88 | | * be null, in which case all preferences will be initialized. |
89 | | */ |
90 | | void PrefsChanged(nsIPrefBranch *prefs, const char *name); |
91 | | |
92 | | /** |
93 | | * This method is called to create a nsProxyInfo instance from the given |
94 | | * PAC-style proxy string. It parses up to the end of the string, or to |
95 | | * the next ';' character. |
96 | | * |
97 | | * @param proxy |
98 | | * The PAC-style proxy string to parse. This must not be null. |
99 | | * @param aResolveFlags |
100 | | * The flags passed to Resolve or AsyncResolve that are stored in |
101 | | * proxyInfo. |
102 | | * @param result |
103 | | * Upon return this points to a newly allocated nsProxyInfo or null |
104 | | * if the proxy string was invalid. |
105 | | * |
106 | | * @return A pointer beyond the parsed proxy string (never null). |
107 | | */ |
108 | | const char * ExtractProxyInfo(const char *proxy, |
109 | | uint32_t aResolveFlags, |
110 | | nsProxyInfo **result); |
111 | | |
112 | | /** |
113 | | * Load the specified PAC file. |
114 | | * |
115 | | * @param pacURI |
116 | | * The URI spec of the PAC file to load. |
117 | | */ |
118 | | nsresult ConfigureFromPAC(const nsCString &pacURI, bool forceReload); |
119 | | |
120 | | /** |
121 | | * This method builds a list of nsProxyInfo objects from the given PAC- |
122 | | * style string. |
123 | | * |
124 | | * @param pacString |
125 | | * The PAC-style proxy string to parse. This may be empty. |
126 | | * @param aResolveFlags |
127 | | * The flags passed to Resolve or AsyncResolve that are stored in |
128 | | * proxyInfo. |
129 | | * @param result |
130 | | * The resulting list of proxy info objects. |
131 | | */ |
132 | | void ProcessPACString(const nsCString &pacString, |
133 | | uint32_t aResolveFlags, |
134 | | nsIProxyInfo **result); |
135 | | |
136 | | /** |
137 | | * This method generates a string valued identifier for the given |
138 | | * nsProxyInfo object. |
139 | | * |
140 | | * @param pi |
141 | | * The nsProxyInfo object from which to generate the key. |
142 | | * @param result |
143 | | * Upon return, this parameter holds the generated key. |
144 | | */ |
145 | | void GetProxyKey(nsProxyInfo *pi, nsCString &result); |
146 | | |
147 | | /** |
148 | | * @return Seconds since start of session. |
149 | | */ |
150 | | uint32_t SecondsSinceSessionStart(); |
151 | | |
152 | | /** |
153 | | * This method removes the specified proxy from the disabled list. |
154 | | * |
155 | | * @param pi |
156 | | * The nsProxyInfo object identifying the proxy to enable. |
157 | | */ |
158 | | void EnableProxy(nsProxyInfo *pi); |
159 | | |
160 | | /** |
161 | | * This method adds the specified proxy to the disabled list. |
162 | | * |
163 | | * @param pi |
164 | | * The nsProxyInfo object identifying the proxy to disable. |
165 | | */ |
166 | | void DisableProxy(nsProxyInfo *pi); |
167 | | |
168 | | /** |
169 | | * This method tests to see if the given proxy is disabled. |
170 | | * |
171 | | * @param pi |
172 | | * The nsProxyInfo object identifying the proxy to test. |
173 | | * |
174 | | * @return True if the specified proxy is disabled. |
175 | | */ |
176 | | bool IsProxyDisabled(nsProxyInfo *pi); |
177 | | |
178 | | /** |
179 | | * This method queries the protocol handler for the given scheme to check |
180 | | * for the protocol flags and default port. |
181 | | * |
182 | | * @param uri |
183 | | * The URI to query. |
184 | | * @param info |
185 | | * Holds information about the protocol upon return. Pass address |
186 | | * of structure when you call this method. This parameter must not |
187 | | * be null. |
188 | | */ |
189 | | nsresult GetProtocolInfo(nsIURI *uri, nsProtocolInfo *result); |
190 | | |
191 | | /** |
192 | | * This method is an internal version nsIProtocolProxyService::newProxyInfo |
193 | | * that expects a string literal for the type. |
194 | | * |
195 | | * @param type |
196 | | * The proxy type. |
197 | | * @param host |
198 | | * The proxy host name (UTF-8 ok). |
199 | | * @param port |
200 | | * The proxy port number. |
201 | | * @param username |
202 | | * The username for the proxy (ASCII). May be "", but not null. |
203 | | * @param password |
204 | | * The password for the proxy (ASCII). May be "", but not null. |
205 | | * @param flags |
206 | | * The proxy flags (nsIProxyInfo::flags). |
207 | | * @param timeout |
208 | | * The failover timeout for this proxy. |
209 | | * @param next |
210 | | * The next proxy to try if this one fails. |
211 | | * @param aResolveFlags |
212 | | * The flags passed to resolve (from nsIProtocolProxyService). |
213 | | * @param result |
214 | | * The resulting nsIProxyInfo object. |
215 | | */ |
216 | | nsresult NewProxyInfo_Internal(const char *type, |
217 | | const nsACString &host, |
218 | | int32_t port, |
219 | | const nsACString &username, |
220 | | const nsACString &password, |
221 | | uint32_t flags, |
222 | | uint32_t timeout, |
223 | | nsIProxyInfo *next, |
224 | | uint32_t aResolveFlags, |
225 | | nsIProxyInfo **result); |
226 | | |
227 | | /** |
228 | | * This method is an internal version of Resolve that does not query PAC. |
229 | | * It performs all of the built-in processing, and reports back to the |
230 | | * caller with either the proxy info result or a flag to instruct the |
231 | | * caller to use PAC instead. |
232 | | * |
233 | | * @param channel |
234 | | * The channel to test. |
235 | | * @param info |
236 | | * Information about the URI's protocol. |
237 | | * @param flags |
238 | | * The flags passed to either the resolve or the asyncResolve method. |
239 | | * @param usePAC |
240 | | * If this flag is set upon return, then PAC should be queried to |
241 | | * resolve the proxy info. |
242 | | * @param result |
243 | | * The resulting proxy info or null. |
244 | | */ |
245 | | nsresult Resolve_Internal(nsIChannel *channel, |
246 | | const nsProtocolInfo &info, |
247 | | uint32_t flags, |
248 | | bool *usePAC, |
249 | | nsIProxyInfo **result); |
250 | | |
251 | | /** |
252 | | * Shallow copy of the current list of registered filters so that |
253 | | * we can safely let them asynchronously process a single proxy |
254 | | * resolution request. |
255 | | */ |
256 | | void CopyFilters(nsTArray<RefPtr<FilterLink>> &aCopy); |
257 | | |
258 | | /** |
259 | | * This method applies the provided filter to the given proxy info |
260 | | * list, and expects |callback| be called on (synchronously or |
261 | | * asynchronously) to provide the updated proxyinfo list. |
262 | | */ |
263 | | bool ApplyFilter(FilterLink const* filterLink, |
264 | | nsIChannel *channel, |
265 | | const nsProtocolInfo &info, |
266 | | nsCOMPtr<nsIProxyInfo> proxyInfo, |
267 | | nsIProxyProtocolFilterResult* callback); |
268 | | |
269 | | /** |
270 | | * This method prunes out disabled and disallowed proxies from a given |
271 | | * proxy info list. |
272 | | * |
273 | | * @param info |
274 | | * Information about the URI's protocol. |
275 | | * @param proxyInfo |
276 | | * The proxy info list to be modified. This is an inout param. |
277 | | */ |
278 | | void PruneProxyInfo(const nsProtocolInfo &info, |
279 | | nsIProxyInfo **proxyInfo); |
280 | | |
281 | | /** |
282 | | * This method is a simple wrapper around PruneProxyInfo that takes the |
283 | | * proxy info list inout param as a nsCOMPtr. |
284 | | */ |
285 | | void PruneProxyInfo(const nsProtocolInfo &info, |
286 | | nsCOMPtr<nsIProxyInfo> &proxyInfo) |
287 | 0 | { |
288 | 0 | nsIProxyInfo *pi = nullptr; |
289 | 0 | proxyInfo.swap(pi); |
290 | 0 | PruneProxyInfo(info, &pi); |
291 | 0 | proxyInfo.swap(pi); |
292 | 0 | } |
293 | | |
294 | | /** |
295 | | * This method populates mHostFiltersArray from the given string. |
296 | | * |
297 | | * @param hostFilters |
298 | | * A "no-proxy-for" exclusion list. |
299 | | */ |
300 | | void LoadHostFilters(const nsACString& hostFilters); |
301 | | |
302 | | /** |
303 | | * This method checks the given URI against mHostFiltersArray. |
304 | | * |
305 | | * @param uri |
306 | | * The URI to test. |
307 | | * @param defaultPort |
308 | | * The default port for the given URI. |
309 | | * |
310 | | * @return True if the URI can use the specified proxy. |
311 | | */ |
312 | | bool CanUseProxy(nsIURI *uri, int32_t defaultPort); |
313 | | |
314 | | /** |
315 | | * Disable Prefetch in the DNS service if a proxy is in use. |
316 | | * |
317 | | * @param aProxy |
318 | | * The proxy information |
319 | | */ |
320 | | void MaybeDisableDNSPrefetch(nsIProxyInfo *aProxy); |
321 | | |
322 | | private: |
323 | | nsresult SetupPACThread(nsIEventTarget *mainThreadEventTarget = nullptr); |
324 | | nsresult ResetPACThread(); |
325 | | nsresult ReloadNetworkPAC(); |
326 | | |
327 | | nsresult AsyncConfigureFromPAC(bool aForceReload, bool aResetPACThread); |
328 | | nsresult OnAsyncGetPACURI(bool aForceReload, |
329 | | bool aResetPACThread, |
330 | | nsresult aResult, |
331 | | const nsACString& aUri); |
332 | | |
333 | | public: |
334 | | // The Sun Forte compiler and others implement older versions of the |
335 | | // C++ standard's rules on access and nested classes. These structs |
336 | | // need to be public in order to deal with those compilers. |
337 | | |
338 | | struct HostInfoIP { |
339 | | uint16_t family; |
340 | | uint16_t mask_len; |
341 | | PRIPv6Addr addr; // possibly IPv4-mapped address |
342 | | }; |
343 | | |
344 | | struct HostInfoName { |
345 | | char *host; |
346 | | uint32_t host_len; |
347 | | }; |
348 | | |
349 | | protected: |
350 | | |
351 | | // simplified array of filters defined by this struct |
352 | | struct HostInfo { |
353 | | bool is_ipaddr; |
354 | | int32_t port; |
355 | | union { |
356 | | HostInfoIP ip; |
357 | | HostInfoName name; |
358 | | }; |
359 | | |
360 | | HostInfo() |
361 | | : is_ipaddr(false) |
362 | | , port(0) |
363 | 0 | { /* other members intentionally uninitialized */ } |
364 | 0 | ~HostInfo() { |
365 | 0 | if (!is_ipaddr && name.host) |
366 | 0 | free(name.host); |
367 | 0 | } |
368 | | }; |
369 | | |
370 | | private: |
371 | | // Private methods to insert and remove FilterLinks from the FilterLink chain. |
372 | | nsresult InsertFilterLink(RefPtr<FilterLink>&& link); |
373 | | nsresult RemoveFilterLink(nsISupports *givenObject); |
374 | | |
375 | | protected: |
376 | | // Indicates if local hosts (plain hostnames, no dots) should use the proxy |
377 | | bool mFilterLocalHosts; |
378 | | |
379 | | // Holds an array of HostInfo objects |
380 | | nsTArray<nsAutoPtr<HostInfo>> mHostFiltersArray; |
381 | | |
382 | | // Filters, always sorted by the position. |
383 | | nsTArray<RefPtr<FilterLink>> mFilters; |
384 | | |
385 | | uint32_t mProxyConfig; |
386 | | |
387 | | nsCString mHTTPProxyHost; |
388 | | int32_t mHTTPProxyPort; |
389 | | |
390 | | nsCString mFTPProxyHost; |
391 | | int32_t mFTPProxyPort; |
392 | | |
393 | | nsCString mHTTPSProxyHost; |
394 | | int32_t mHTTPSProxyPort; |
395 | | |
396 | | // mSOCKSProxyTarget could be a host, a domain socket path, |
397 | | // or a named-pipe name. |
398 | | nsCString mSOCKSProxyTarget; |
399 | | int32_t mSOCKSProxyPort; |
400 | | int32_t mSOCKSProxyVersion; |
401 | | bool mSOCKSProxyRemoteDNS; |
402 | | bool mProxyOverTLS; |
403 | | bool mWPADOverDHCPEnabled; |
404 | | |
405 | | RefPtr<nsPACMan> mPACMan; // non-null if we are using PAC |
406 | | nsCOMPtr<nsISystemProxySettings> mSystemProxySettings; |
407 | | |
408 | | PRTime mSessionStart; |
409 | | nsFailedProxyTable mFailedProxies; |
410 | | int32_t mFailedProxyTimeout; |
411 | | |
412 | | private: |
413 | | nsresult AsyncResolveInternal(nsIChannel *channel, uint32_t flags, |
414 | | nsIProtocolProxyCallback *callback, |
415 | | nsICancelable **result, |
416 | | bool isSyncOK, |
417 | | nsIEventTarget *mainThreadEventTarget); |
418 | | bool mIsShutdown; |
419 | | nsCOMPtr<nsIEventTarget> mProxySettingTarget; |
420 | | }; |
421 | | |
422 | | NS_DEFINE_STATIC_IID_ACCESSOR(nsProtocolProxyService, NS_PROTOCOL_PROXY_SERVICE_IMPL_CID) |
423 | | |
424 | | } // namespace net |
425 | | } // namespace mozilla |
426 | | |
427 | | #endif // !nsProtocolProxyService_h__ |