Coverage Report

Created: 2018-09-25 14:53

/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__