nsProtocolProxyService.h (14005B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 "nsTArray.h" 12 #include "nsIProtocolProxyService2.h" 13 #include "nsIProtocolProxyFilter.h" 14 #include "nsIProxyInfo.h" 15 #include "nsIObserver.h" 16 #include "nsTHashMap.h" 17 #include "nsHashKeys.h" 18 #include "nsITimer.h" 19 #include "prio.h" 20 21 class nsIPrefBranch; 22 class nsISystemProxySettings; 23 24 namespace mozilla { 25 namespace net { 26 27 using nsFailedProxyTable = nsTHashMap<nsCStringHashKey, uint32_t>; 28 29 class nsPACMan; 30 class nsProxyInfo; 31 struct nsProtocolInfo; 32 33 // CID for the nsProtocolProxyService class 34 // 091eedd8-8bae-4fe3-ad62-0c87351e640d 35 #define NS_PROTOCOL_PROXY_SERVICE_IMPL_CID \ 36 {0x091eedd8, 0x8bae, 0x4fe3, {0xad, 0x62, 0x0c, 0x87, 0x35, 0x1e, 0x64, 0x0d}} 37 38 class nsProtocolProxyService final : public nsIProtocolProxyService2, 39 public nsIObserver, 40 public nsITimerCallback, 41 public nsINamed { 42 public: 43 NS_DECL_ISUPPORTS 44 NS_DECL_NSIPROTOCOLPROXYSERVICE2 45 NS_DECL_NSIPROTOCOLPROXYSERVICE 46 NS_DECL_NSIOBSERVER 47 NS_DECL_NSITIMERCALLBACK 48 NS_DECL_NSINAMED 49 50 NS_INLINE_DECL_STATIC_IID(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 friend class AsyncApplyFilters; 78 79 ~nsProtocolProxyService(); 80 81 /** 82 * This method is called whenever a preference may have changed or 83 * to initialize all preferences. 84 * 85 * @param prefs 86 * This must be a pointer to the root pref branch. 87 * @param name 88 * This can be the name of a fully-qualified preference, or it can 89 * be null, in which case all preferences will be initialized. 90 */ 91 void PrefsChanged(nsIPrefBranch* prefBranch, const char* pref); 92 93 /** 94 * This method is called to create a nsProxyInfo instance from the given 95 * PAC-style proxy string. It parses up to the end of the string, or to 96 * the next ';' character. 97 * 98 * @param proxy 99 * The PAC-style proxy string to parse. This must not be null. 100 * @param aResolveFlags 101 * The flags passed to Resolve or AsyncResolve that are stored in 102 * proxyInfo. 103 * @param result 104 * Upon return this points to a newly allocated nsProxyInfo or null 105 * if the proxy string was invalid. 106 * 107 * @return A pointer beyond the parsed proxy string (never null). 108 */ 109 const char* ExtractProxyInfo(const char* start, 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& spec, 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, uint32_t aResolveFlags, 133 nsIProxyInfo** result); 134 135 /** 136 * This method generates a string valued identifier for the given 137 * nsProxyInfo object. 138 * 139 * @param pi 140 * The nsProxyInfo object from which to generate the key. 141 * @param result 142 * Upon return, this parameter holds the generated key. 143 */ 144 void GetProxyKey(nsProxyInfo* pi, nsCString& key); 145 146 /** 147 * @return Seconds since start of session. 148 */ 149 uint32_t SecondsSinceSessionStart(); 150 151 /** 152 * This method removes the specified proxy from the disabled list. 153 * 154 * @param pi 155 * The nsProxyInfo object identifying the proxy to enable. 156 */ 157 void EnableProxy(nsProxyInfo* pi); 158 159 /** 160 * This method adds the specified proxy to the disabled list. 161 * 162 * @param pi 163 * The nsProxyInfo object identifying the proxy to disable. 164 */ 165 void DisableProxy(nsProxyInfo* pi); 166 167 /** 168 * This method tests to see if the given proxy is disabled. 169 * 170 * @param pi 171 * The nsProxyInfo object identifying the proxy to test. 172 * 173 * @return True if the specified proxy is disabled. 174 */ 175 bool IsProxyDisabled(nsProxyInfo* pi); 176 177 /** 178 * This method queries the protocol handler for the given scheme to check 179 * for the protocol flags and default port. 180 * 181 * @param uri 182 * The URI to query. 183 * @param info 184 * Holds information about the protocol upon return. Pass address 185 * of structure when you call this method. This parameter must not 186 * be null. 187 */ 188 nsresult GetProtocolInfo(nsIURI* uri, nsProtocolInfo* info); 189 190 /** 191 * This method is an internal version nsIProtocolProxyService::newProxyInfo 192 * that expects a string literal for the type. 193 * 194 * @param type 195 * The proxy type. 196 * @param host 197 * The proxy host name (UTF-8 ok). 198 * @param port 199 * The proxy port number. 200 * @param masqueTemplate 201 * The MasqueTemplate. 202 * @param username 203 * The username for the proxy (ASCII). May be "", but not null. 204 * @param password 205 * The password for the proxy (ASCII). May be "", but not null. 206 * @param flags 207 * The proxy flags (nsIProxyInfo::flags). 208 * @param timeout 209 * The failover timeout for this proxy. 210 * @param next 211 * The next proxy to try if this one fails. 212 * @param aResolveFlags 213 * The flags passed to resolve (from nsIProtocolProxyService). 214 * @param result 215 * The resulting nsIProxyInfo object. 216 */ 217 nsresult NewProxyInfo_Internal(const char* type, const nsACString& host, 218 int32_t port, const nsACString& masqueTemplate, 219 const nsACString& username, 220 const nsACString& password, 221 const nsACString& aProxyAuthorizationHeader, 222 const nsACString& aConnectionIsolationKey, 223 uint32_t flags, uint32_t timeout, 224 nsIProxyInfo* aFailoverProxy, 225 uint32_t aResolveFlags, 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, const nsProtocolInfo& info, 246 uint32_t flags, bool* usePAC, 247 nsIProxyInfo** result); 248 249 /** 250 * Shallow copy of the current list of registered filters so that 251 * we can safely let them asynchronously process a single proxy 252 * resolution request. 253 */ 254 void CopyFilters(nsTArray<RefPtr<FilterLink>>& aCopy); 255 256 /** 257 * This method applies the provided filter to the given proxy info 258 * list, and expects |callback| be called on (synchronously or 259 * asynchronously) to provide the updated proxyinfo list. 260 */ 261 bool ApplyFilter(FilterLink const* filterLink, nsIChannel* channel, 262 const nsProtocolInfo& info, nsCOMPtr<nsIProxyInfo> list, 263 nsIProxyProtocolFilterResult* callback); 264 265 /** 266 * This method prunes out disabled and disallowed proxies from a given 267 * proxy info list. 268 * 269 * @param info 270 * Information about the URI's protocol. 271 * @param proxyInfo 272 * The proxy info list to be modified. This is an inout param. 273 */ 274 void PruneProxyInfo(const nsProtocolInfo& info, nsIProxyInfo** list); 275 276 /** 277 * This method is a simple wrapper around PruneProxyInfo that takes the 278 * proxy info list inout param as a nsCOMPtr. 279 */ 280 void PruneProxyInfo(const nsProtocolInfo& info, 281 nsCOMPtr<nsIProxyInfo>& proxyInfo) { 282 nsIProxyInfo* pi = nullptr; 283 proxyInfo.swap(pi); 284 PruneProxyInfo(info, &pi); 285 proxyInfo.swap(pi); 286 } 287 288 /** 289 * This method populates mHostFiltersArray from the given string. 290 * 291 * @param hostFilters 292 * A "no-proxy-for" exclusion list. 293 */ 294 void LoadHostFilters(const nsACString& aFilters); 295 296 /** 297 * This method checks the given URI against mHostFiltersArray. 298 * 299 * @param uri 300 * The URI to test. 301 * @param defaultPort 302 * The default port for the given URI. 303 * 304 * @return True if the URI can use the specified proxy. 305 */ 306 bool CanUseProxy(nsIURI* uri, int32_t defaultPort); 307 308 /** 309 * Disable Prefetch in the DNS service if a proxy is in use. 310 * 311 * @param aProxy 312 * The proxy information 313 */ 314 void MaybeDisableDNSPrefetch(nsIProxyInfo* aProxy); 315 316 private: 317 nsresult SetupPACThread( 318 nsISerialEventTarget* mainThreadEventTarget = nullptr); 319 nsresult ResetPACThread(); 320 nsresult ReloadNetworkPAC(); 321 322 nsresult AsyncConfigureWPADOrFromPAC(bool aForceReload, bool aResetPACThread, 323 bool aSystemWPADAllowed); 324 nsresult OnAsyncGetPACURIOrSystemWPADSetting(bool aForceReload, 325 bool aResetPACThread, 326 nsresult aResult, 327 const nsACString& aUri, 328 bool aSystemWPADSetting); 329 330 static void CallOnProxyAvailableCallback(nsProtocolProxyService* aService, 331 nsIProtocolProxyCallback* aCallback, 332 nsICancelable* aRequest, 333 nsIChannel* aChannel, 334 nsIProxyInfo* aProxyInfo, 335 nsresult aStatus); 336 337 public: 338 // The Sun Forte compiler and others implement older versions of the 339 // C++ standard's rules on access and nested classes. These structs 340 // need to be public in order to deal with those compilers. 341 342 struct HostInfoIP { 343 uint16_t family; 344 uint16_t mask_len; 345 PRIPv6Addr addr; // possibly IPv4-mapped address 346 }; 347 348 struct HostInfoName { 349 char* host; 350 uint32_t host_len; 351 }; 352 353 protected: 354 // simplified array of filters defined by this struct 355 struct HostInfo { 356 bool is_ipaddr{false}; 357 int32_t port{0}; 358 // other members intentionally uninitialized 359 union { 360 HostInfoIP ip; 361 HostInfoName name; 362 }; 363 364 HostInfo() = default; 365 ~HostInfo() { 366 if (!is_ipaddr && name.host) { 367 free(name.host); 368 } 369 } 370 }; 371 372 private: 373 // Private methods to insert and remove FilterLinks from the FilterLink chain. 374 nsresult InsertFilterLink(RefPtr<FilterLink>&& link); 375 nsresult RemoveFilterLink(nsISupports* givenObject); 376 377 protected: 378 // Indicates if local hosts (plain hostnames, no dots) should use the proxy 379 bool mFilterLocalHosts{false}; 380 381 // Holds an array of HostInfo objects 382 nsTArray<UniquePtr<HostInfo>> mHostFiltersArray; 383 384 // Filters, always sorted by the position. 385 nsTArray<RefPtr<FilterLink>> mFilters; 386 387 nsTArray<nsCOMPtr<nsIProxyConfigChangedCallback>> 388 mProxyConfigChangedCallbacks; 389 390 uint32_t mProxyConfig{PROXYCONFIG_DIRECT}; 391 392 nsCString mHTTPProxyHost; 393 int32_t mHTTPProxyPort{-1}; 394 395 nsCString mHTTPSProxyHost; 396 int32_t mHTTPSProxyPort{-1}; 397 398 // mSOCKSProxyTarget could be a host, a domain socket path, 399 // or a named-pipe name. 400 nsCString mSOCKSProxyTarget; 401 int32_t mSOCKSProxyPort{-1}; 402 int32_t mSOCKSProxyVersion{nsIProxyInfo::SOCKS_V4}; 403 bool mSOCKS4ProxyRemoteDNS{false}; 404 bool mSOCKS5ProxyRemoteDNS{false}; 405 bool mProxyOverTLS{true}; 406 bool mWPADOverDHCPEnabled{false}; 407 408 RefPtr<nsPACMan> mPACMan; // non-null if we are using PAC 409 nsCOMPtr<nsISystemProxySettings> mSystemProxySettings; 410 411 PRTime mSessionStart; 412 nsFailedProxyTable mFailedProxies; 413 // 30 minute default 414 int32_t mFailedProxyTimeout{30 * 60}; 415 416 private: 417 nsresult AsyncResolveInternal(nsIChannel* channel, uint32_t flags, 418 nsIProtocolProxyCallback* callback, 419 nsICancelable** result, bool isSyncOK, 420 nsISerialEventTarget* mainThreadEventTarget); 421 422 // compute `NewProxyInfo_Internal` parameters based on mSOCKS variables 423 const char* SOCKSProxyType(); 424 bool SOCKSRemoteDNS(); 425 426 bool mIsShutdown{false}; 427 nsCOMPtr<nsITimer> mReloadPACTimer; 428 }; 429 430 } // namespace net 431 } // namespace mozilla 432 433 #endif // !nsProtocolProxyService_h__