DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (5350524bb654)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
#ifndef nsProtocolProxyService_h__
#define nsProtocolProxyService_h__

#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsTArray.h"
#include "nsIProtocolProxyService2.h"
#include "nsIProtocolProxyFilter.h"
#include "nsIProxyInfo.h"
#include "nsIObserver.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "prio.h"
#include "mozilla/Attributes.h"

class nsIPrefBranch;
class nsISystemProxySettings;

namespace mozilla {
namespace net {

typedef nsDataHashtable<nsCStringHashKey, uint32_t> nsFailedProxyTable;

class nsPACMan;
class nsProxyInfo;
struct nsProtocolInfo;

// CID for the nsProtocolProxyService class
// 091eedd8-8bae-4fe3-ad62-0c87351e640d
#define NS_PROTOCOL_PROXY_SERVICE_IMPL_CID        \
{ 0x091eedd8, 0x8bae, 0x4fe3, \
        { 0xad, 0x62, 0x0c, 0x87, 0x35, 0x1e, 0x64, 0x0d } }

class nsProtocolProxyService final : public nsIProtocolProxyService2
                                   , public nsIObserver
{
public:
    NS_DECL_ISUPPORTS
    NS_DECL_NSIPROTOCOLPROXYSERVICE2
    NS_DECL_NSIPROTOCOLPROXYSERVICE
    NS_DECL_NSIOBSERVER

    NS_DECLARE_STATIC_IID_ACCESSOR(NS_PROTOCOL_PROXY_SERVICE_IMPL_CID)

    nsProtocolProxyService();

    nsresult Init();
    nsresult DeprecatedBlockingResolve(nsIChannel *aChannel,
                                       uint32_t aFlags,
                                       nsIProxyInfo **retval);

protected:
    friend class nsAsyncResolveRequest;
    friend class TestProtocolProxyService_LoadHostFilters_Test; // for gtest

    ~nsProtocolProxyService();

    /**
     * This method is called whenever a preference may have changed or
     * to initialize all preferences.
     *
     * @param prefs
     *        This must be a pointer to the root pref branch.
     * @param name
     *        This can be the name of a fully-qualified preference, or it can
     *        be null, in which case all preferences will be initialized.
     */
    void PrefsChanged(nsIPrefBranch *prefs, const char *name);

    /**
     * This method is called to create a nsProxyInfo instance from the given
     * PAC-style proxy string.  It parses up to the end of the string, or to
     * the next ';' character.
     * 
     * @param proxy
     *        The PAC-style proxy string to parse.  This must not be null.
     * @param aResolveFlags
     *        The flags passed to Resolve or AsyncResolve that are stored in 
     *        proxyInfo.
     * @param result
     *        Upon return this points to a newly allocated nsProxyInfo or null
     *        if the proxy string was invalid.
     *
     * @return A pointer beyond the parsed proxy string (never null).
     */
    const char * ExtractProxyInfo(const char *proxy,
                                              uint32_t aResolveFlags,
                                              nsProxyInfo **result);

    /**
     * Load the specified PAC file.
     * 
     * @param pacURI
     *        The URI spec of the PAC file to load.
     */
    nsresult ConfigureFromPAC(const nsCString &pacURI, bool forceReload);

    /**
     * This method builds a list of nsProxyInfo objects from the given PAC-
     * style string.
     *
     * @param pacString
     *        The PAC-style proxy string to parse.  This may be empty.
     * @param aResolveFlags
     *        The flags passed to Resolve or AsyncResolve that are stored in 
     *        proxyInfo.
     * @param result
     *        The resulting list of proxy info objects.
     */
    void ProcessPACString(const nsCString &pacString,
                                      uint32_t aResolveFlags,
                                      nsIProxyInfo **result);

    /**
     * This method generates a string valued identifier for the given
     * nsProxyInfo object.
     *
     * @param pi
     *        The nsProxyInfo object from which to generate the key.
     * @param result
     *        Upon return, this parameter holds the generated key.
     */
    void GetProxyKey(nsProxyInfo *pi, nsCString &result);

    /**
     * @return Seconds since start of session.
     */
    uint32_t SecondsSinceSessionStart();

    /**
     * This method removes the specified proxy from the disabled list.
     *
     * @param pi
     *        The nsProxyInfo object identifying the proxy to enable.
     */
    void EnableProxy(nsProxyInfo *pi);

    /**
     * This method adds the specified proxy to the disabled list.
     *
     * @param pi
     *        The nsProxyInfo object identifying the proxy to disable.
     */
    void DisableProxy(nsProxyInfo *pi);

    /**
     * This method tests to see if the given proxy is disabled.
     *
     * @param pi
     *        The nsProxyInfo object identifying the proxy to test.
     *
     * @return True if the specified proxy is disabled.
     */
    bool IsProxyDisabled(nsProxyInfo *pi);

    /**
     * This method queries the protocol handler for the given scheme to check
     * for the protocol flags and default port.
     *
     * @param uri
     *        The URI to query.
     * @param info
     *        Holds information about the protocol upon return.  Pass address
     *        of structure when you call this method.  This parameter must not
     *        be null.
     */
    nsresult GetProtocolInfo(nsIURI *uri, nsProtocolInfo *result);

    /**
     * This method is an internal version nsIProtocolProxyService::newProxyInfo
     * that expects a string literal for the type.
     *
     * @param type
     *        The proxy type.
     * @param host
     *        The proxy host name (UTF-8 ok).
     * @param port
     *        The proxy port number.
     * @param username
     *        The username for the proxy (ASCII). May be "", but not null.
     * @param password
     *        The password for the proxy (ASCII). May be "", but not null.
     * @param flags
     *        The proxy flags (nsIProxyInfo::flags).
     * @param timeout
     *        The failover timeout for this proxy.
     * @param next
     *        The next proxy to try if this one fails.
     * @param aResolveFlags
     *        The flags passed to resolve (from nsIProtocolProxyService).
     * @param result
     *        The resulting nsIProxyInfo object.
     */
    nsresult NewProxyInfo_Internal(const char *type,
                                               const nsACString &host,
                                               int32_t port,
                                               const nsACString &username,
                                               const nsACString &password,
                                               uint32_t flags,
                                               uint32_t timeout,
                                               nsIProxyInfo *next,
                                               uint32_t aResolveFlags,
                                               nsIProxyInfo **result);

    /**
     * This method is an internal version of Resolve that does not query PAC.
     * It performs all of the built-in processing, and reports back to the
     * caller with either the proxy info result or a flag to instruct the
     * caller to use PAC instead.
     *
     * @param channel
     *        The channel to test.
     * @param info
     *        Information about the URI's protocol.
     * @param flags
     *        The flags passed to either the resolve or the asyncResolve method.
     * @param usePAC
     *        If this flag is set upon return, then PAC should be queried to
     *        resolve the proxy info.
     * @param result
     *        The resulting proxy info or null.
     */
    nsresult Resolve_Internal(nsIChannel *channel,
                              const nsProtocolInfo &info,
                              uint32_t flags,
                              bool *usePAC,
                              nsIProxyInfo **result);

    /**
     * This method applies the registered filters to the given proxy info
     * list, and returns a possibly modified list.
     *
     * @param channel
     *        The channel corresponding to this proxy info list.
     * @param info
     *        Information about the URI's protocol.
     * @param proxyInfo
     *        The proxy info list to be modified.  This is an inout param.
     */
    void ApplyFilters(nsIChannel *channel, const nsProtocolInfo &info,
                                  nsIProxyInfo **proxyInfo);

    /**
     * This method is a simple wrapper around ApplyFilters that takes the
     * proxy info list inout param as a nsCOMPtr.
     */
    inline void ApplyFilters(nsIChannel *channel, const nsProtocolInfo &info,
                             nsCOMPtr<nsIProxyInfo> &proxyInfo)
    {
      nsIProxyInfo *pi = nullptr;
      proxyInfo.swap(pi);
      ApplyFilters(channel, info, &pi);
      proxyInfo.swap(pi);
    }

    /**
     * This method prunes out disabled and disallowed proxies from a given
     * proxy info list.
     *
     * @param info
     *        Information about the URI's protocol.
     * @param proxyInfo
     *        The proxy info list to be modified.  This is an inout param.
     */
    void PruneProxyInfo(const nsProtocolInfo &info,
                                    nsIProxyInfo **proxyInfo);

    /**
     * This method populates mHostFiltersArray from the given string.
     *
     * @param hostFilters
     *        A "no-proxy-for" exclusion list.
     */
    void LoadHostFilters(const nsACString& hostFilters);

    /**
     * This method checks the given URI against mHostFiltersArray.
     *
     * @param uri
     *        The URI to test.
     * @param defaultPort
     *        The default port for the given URI.
     *
     * @return True if the URI can use the specified proxy.
     */
    bool CanUseProxy(nsIURI *uri, int32_t defaultPort);

    /**
     * Disable Prefetch in the DNS service if a proxy is in use.
     *
     * @param aProxy
     *        The proxy information
     */
    void MaybeDisableDNSPrefetch(nsIProxyInfo *aProxy);

private:
    nsresult SetupPACThread();
    nsresult ResetPACThread();
    nsresult ReloadNetworkPAC();

public:
    // The Sun Forte compiler and others implement older versions of the
    // C++ standard's rules on access and nested classes.  These structs
    // need to be public in order to deal with those compilers.

    struct HostInfoIP {
        uint16_t   family;
        uint16_t   mask_len;
        PRIPv6Addr addr; // possibly IPv4-mapped address
    };

    struct HostInfoName {
        char    *host;
        uint32_t host_len;
    };

protected:

    // simplified array of filters defined by this struct
    struct HostInfo {
        bool    is_ipaddr;
        int32_t port;
        union {
            HostInfoIP   ip;
            HostInfoName name;
        };

        HostInfo()
            : is_ipaddr(false)
            , port(0)
            { /* other members intentionally uninitialized */ }
       ~HostInfo() {
            if (!is_ipaddr && name.host)
                free(name.host);
        }
    };

    // An instance of this struct is allocated for each registered
    // nsIProtocolProxyFilter and each nsIProtocolProxyChannelFilter.
    struct FilterLink {
      struct FilterLink                *next;
      uint32_t                          position;
      nsCOMPtr<nsIProtocolProxyFilter> filter;
      nsCOMPtr<nsIProtocolProxyChannelFilter> channelFilter;
      FilterLink(uint32_t p, nsIProtocolProxyFilter *f)
        : next(nullptr), position(p), filter(f), channelFilter(nullptr) {}
      FilterLink(uint32_t p, nsIProtocolProxyChannelFilter *cf)
        : next(nullptr), position(p), filter(nullptr), channelFilter(cf) {}
      // Chain deletion to simplify cleaning up the filter links
      ~FilterLink() { if (next) delete next; }
    };

private:
    // Private methods to insert and remove FilterLinks from the FilterLink chain.
    nsresult InsertFilterLink(FilterLink *link, uint32_t position);
    nsresult RemoveFilterLink(nsISupports *givenObject);

protected:
    // Indicates if local hosts (plain hostnames, no dots) should use the proxy
    bool mFilterLocalHosts;

    // Holds an array of HostInfo objects
    nsTArray<nsAutoPtr<HostInfo> > mHostFiltersArray;

    // Points to the start of a sorted by position, singly linked list
    // of FilterLink objects.
    FilterLink                  *mFilters;

    uint32_t                     mProxyConfig;

    nsCString                    mHTTPProxyHost;
    int32_t                      mHTTPProxyPort;

    nsCString                    mFTPProxyHost;
    int32_t                      mFTPProxyPort;

    nsCString                    mHTTPSProxyHost;
    int32_t                      mHTTPSProxyPort;

    // mSOCKSProxyTarget could be a host, a domain socket path,
    // or a named-pipe name.
    nsCString                    mSOCKSProxyTarget;
    int32_t                      mSOCKSProxyPort;
    int32_t                      mSOCKSProxyVersion;
    bool                         mSOCKSProxyRemoteDNS;
    bool                         mProxyOverTLS;

    RefPtr<nsPACMan>           mPACMan;  // non-null if we are using PAC
    nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;

    PRTime                       mSessionStart;
    nsFailedProxyTable           mFailedProxies;
    int32_t                      mFailedProxyTimeout;

private:
    nsresult AsyncResolveInternal(nsIChannel *channel, uint32_t flags,
                                  nsIProtocolProxyCallback *callback,
                                  nsICancelable **result,
                                  bool isSyncOK);

};

NS_DEFINE_STATIC_IID_ACCESSOR(nsProtocolProxyService, NS_PROTOCOL_PROXY_SERVICE_IMPL_CID)

} // namespace net
} // namespace mozilla

#endif // !nsProtocolProxyService_h__