diff options
Diffstat (limited to 'netwerk/base/nsProtocolProxyService.h')
-rw-r--r-- | netwerk/base/nsProtocolProxyService.h | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/netwerk/base/nsProtocolProxyService.h b/netwerk/base/nsProtocolProxyService.h new file mode 100644 index 000000000..9fe24699e --- /dev/null +++ b/netwerk/base/nsProtocolProxyService.h @@ -0,0 +1,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__ |