tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsNetUtil.h (49145B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=4 sw=2 sts=2 et cin: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef nsNetUtil_h__
      8 #define nsNetUtil_h__
      9 
     10 #include <functional>
     11 #include "mozilla/Maybe.h"
     12 #include "mozilla/ResultExtensions.h"
     13 #include "nsAttrValue.h"
     14 #include "nsCOMPtr.h"
     15 #include "nsIInterfaceRequestor.h"
     16 #include "nsIInterfaceRequestorUtils.h"
     17 #include "nsILoadGroup.h"
     18 #include "nsINestedURI.h"
     19 #include "nsINetUtil.h"
     20 #include "nsIRequest.h"
     21 #include "nsILoadInfo.h"
     22 #include "nsIIOService.h"
     23 #include "nsIURI.h"
     24 #include "mozilla/NotNull.h"
     25 #include "mozilla/Services.h"
     26 #include "nsNetCID.h"
     27 #include "nsReadableUtils.h"
     28 #include "nsServiceManagerUtils.h"
     29 #include "nsString.h"
     30 #include "nsTArray.h"
     31 #include "mozilla/net/idna_glue.h"
     32 #include "mozilla/net/MozURL_ffi.h"
     33 
     34 class nsIPrincipal;
     35 class nsIAsyncStreamCopier;
     36 class nsIAuthPrompt;
     37 class nsIAuthPrompt2;
     38 class nsIChannel;
     39 class nsIChannelPolicy;
     40 class nsICookieJarSettings;
     41 class nsIDownloadObserver;
     42 class nsIEventTarget;
     43 class nsIFileProtocolHandler;
     44 class nsIFileRandomAccessStream;
     45 class nsIHttpChannel;
     46 class nsIInputStream;
     47 class nsIInputStreamPump;
     48 class nsIInterfaceRequestor;
     49 class nsIOutputStream;
     50 class nsIParentChannel;
     51 class nsIPersistentProperties;
     52 class nsIProxyInfo;
     53 class nsIRandomAccessStream;
     54 class nsIRequestObserver;
     55 class nsISerialEventTarget;
     56 class nsIStreamListener;
     57 class nsIStreamLoader;
     58 class nsIStreamLoaderObserver;
     59 class nsIIncrementalStreamLoader;
     60 class nsIIncrementalStreamLoaderObserver;
     61 
     62 namespace mozilla {
     63 class Encoding;
     64 class OriginAttributes;
     65 class OriginTrials;
     66 namespace dom {
     67 class ClientInfo;
     68 class PerformanceStorage;
     69 class ServiceWorkerDescriptor;
     70 }  // namespace dom
     71 
     72 namespace ipc {
     73 class FileDescriptor;
     74 }  // namespace ipc
     75 
     76 }  // namespace mozilla
     77 
     78 template <class>
     79 class nsCOMPtr;
     80 template <typename>
     81 struct already_AddRefed;
     82 
     83 already_AddRefed<nsIIOService> do_GetIOService(nsresult* error = nullptr);
     84 
     85 already_AddRefed<nsINetUtil> do_GetNetUtil(nsresult* error = nullptr);
     86 
     87 // private little helper function... don't call this directly!
     88 nsresult net_EnsureIOService(nsIIOService** ios, nsCOMPtr<nsIIOService>& grip);
     89 
     90 nsresult NS_NewURI(nsIURI** aURI, const nsACString& spec,
     91                   const char* charset = nullptr, nsIURI* baseURI = nullptr);
     92 
     93 nsresult NS_NewURI(nsIURI** result, const nsACString& spec,
     94                   mozilla::NotNull<const mozilla::Encoding*> encoding,
     95                   nsIURI* baseURI = nullptr);
     96 
     97 nsresult NS_NewURI(nsIURI** result, const nsAString& spec,
     98                   const char* charset = nullptr, nsIURI* baseURI = nullptr);
     99 
    100 nsresult NS_NewURI(nsIURI** result, const nsAString& spec,
    101                   mozilla::NotNull<const mozilla::Encoding*> encoding,
    102                   nsIURI* baseURI = nullptr);
    103 
    104 nsresult NS_NewURI(nsIURI** result, const char* spec,
    105                   nsIURI* baseURI = nullptr);
    106 
    107 nsresult NS_NewFileURI(
    108    nsIURI** result, nsIFile* spec,
    109    nsIIOService* ioService =
    110        nullptr);  // pass in nsIIOService to optimize callers
    111 
    112 // Functions for adding additional encoding to a URL for compatibility with
    113 // Apple's NSURL class URLWithString method.
    114 //
    115 // @param aResult
    116 //        Out parameter for the encoded URL spec
    117 // @param aSpec
    118 //        The spec for the URL to be encoded
    119 nsresult NS_GetSpecWithNSURLEncoding(nsACString& aResult,
    120                                     const nsACString& aSpec);
    121 // @param aResult
    122 //        Out parameter for the encoded URI
    123 // @param aSpec
    124 //        The spec for the URL to be encoded
    125 nsresult NS_NewURIWithNSURLEncoding(nsIURI** aResult, const nsACString& aSpec);
    126 
    127 // These methods will only mutate the URI if the ref of aInput doesn't already
    128 // match the ref we are trying to set.
    129 // If aInput has no ref, and we are calling NS_GetURIWithoutRef, or
    130 // NS_GetURIWithNewRef with an empty string, then aOutput will be the same
    131 // as aInput. The same is true if aRef is already equal to the ref of aInput.
    132 // This is OK because URIs are immutable and threadsafe.
    133 // If the URI doesn't support ref fragments aOutput will be the same as aInput.
    134 nsresult NS_GetURIWithNewRef(nsIURI* aInput, const nsACString& aRef,
    135                             nsIURI** aOutput);
    136 nsresult NS_GetURIWithoutRef(nsIURI* aInput, nsIURI** aOutput);
    137 
    138 nsresult NS_GetSanitizedURIStringFromURI(nsIURI* aUri,
    139                                         nsACString& aSanitizedSpec);
    140 
    141 /*
    142 * How to create a new Channel, using NS_NewChannel,
    143 * NS_NewChannelWithTriggeringPrincipal,
    144 * NS_NewInputStreamChannel, NS_NewChannelInternal
    145 * and it's variations:
    146 *
    147 * What specific API function to use:
    148 * * The NS_NewChannelInternal functions should almost never be directly
    149 *   called outside of necko code.
    150 * * If possible, use NS_NewChannel() providing a loading *nsINode*
    151 * * If no loading *nsINode* is available, try calling NS_NewChannel() providing
    152 *   a loading *ClientInfo*.
    153 * * If no loading *nsINode* or *ClientInfo* are available, call NS_NewChannel()
    154 *   providing a loading *nsIPrincipal*.
    155 * * Call NS_NewChannelWithTriggeringPrincipal if the triggeringPrincipal
    156 *   is different from the loadingPrincipal.
    157 * * Call NS_NewChannelInternal() providing aLoadInfo object in cases where
    158 *   you already have loadInfo object, e.g in case of a channel redirect.
    159 *
    160 * @param aURI
    161 *        nsIURI from which to make a channel
    162 * @param aLoadingNode
    163 * @param aLoadingPrincipal
    164 * @param aTriggeringPrincipal
    165 * @param aSecurityFlags
    166 * @param aContentPolicyType
    167 *        These will be used as values for the nsILoadInfo object on the
    168 *        created channel. For details, see nsILoadInfo in nsILoadInfo.idl
    169 *
    170 * Please note, if you provide both a loadingNode and a loadingPrincipal,
    171 * then loadingPrincipal must be equal to loadingNode->NodePrincipal().
    172 * But less error prone is to just supply a loadingNode.
    173 *
    174 * Note, if you provide a loading ClientInfo its principal must match the
    175 * loading principal.  Currently you must pass both as the loading principal
    176 * may have additional mutable values like CSP on it.  In the future these
    177 * will be removed from nsIPrincipal and the API can be changed to take just
    178 * the loading ClientInfo.
    179 *
    180 * Keep in mind that URIs coming from a webpage should *never* use the
    181 * systemPrincipal as the loadingPrincipal.
    182 */
    183 nsresult NS_NewChannelInternal(
    184    nsIChannel** outChannel, nsIURI* aUri, nsINode* aLoadingNode,
    185    nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal,
    186    const mozilla::Maybe<mozilla::dom::ClientInfo>& aLoadingClientInfo,
    187    const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController,
    188    nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType,
    189    nsICookieJarSettings* aCookieJarSettings = nullptr,
    190    mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
    191    nsILoadGroup* aLoadGroup = nullptr,
    192    nsIInterfaceRequestor* aCallbacks = nullptr,
    193    nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL,
    194    nsIIOService* aIoService = nullptr, uint32_t aSandboxFlags = 0);
    195 
    196 // See NS_NewChannelInternal for usage and argument description
    197 nsresult NS_NewChannelInternal(
    198    nsIChannel** outChannel, nsIURI* aUri, nsILoadInfo* aLoadInfo,
    199    mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
    200    nsILoadGroup* aLoadGroup = nullptr,
    201    nsIInterfaceRequestor* aCallbacks = nullptr,
    202    nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL,
    203    nsIIOService* aIoService = nullptr);
    204 
    205 // See NS_NewChannelInternal for usage and argument description
    206 nsresult /*NS_NewChannelWithNodeAndTriggeringPrincipal */
    207 NS_NewChannelWithTriggeringPrincipal(
    208    nsIChannel** outChannel, nsIURI* aUri, nsINode* aLoadingNode,
    209    nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags,
    210    nsContentPolicyType aContentPolicyType,
    211    mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
    212    nsILoadGroup* aLoadGroup = nullptr,
    213    nsIInterfaceRequestor* aCallbacks = nullptr,
    214    nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL,
    215    nsIIOService* aIoService = nullptr);
    216 
    217 // See NS_NewChannelInternal for usage and argument description
    218 nsresult NS_NewChannelWithTriggeringPrincipal(
    219    nsIChannel** outChannel, nsIURI* aUri, nsIPrincipal* aLoadingPrincipal,
    220    nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags,
    221    nsContentPolicyType aContentPolicyType,
    222    nsICookieJarSettings* aCookieJarSettings = nullptr,
    223    mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
    224    nsILoadGroup* aLoadGroup = nullptr,
    225    nsIInterfaceRequestor* aCallbacks = nullptr,
    226    nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL,
    227    nsIIOService* aIoService = nullptr);
    228 
    229 // See NS_NewChannelInternal for usage and argument description
    230 nsresult NS_NewChannelWithTriggeringPrincipal(
    231    nsIChannel** outChannel, nsIURI* aUri, nsIPrincipal* aLoadingPrincipal,
    232    nsIPrincipal* aTriggeringPrincipal,
    233    const mozilla::dom::ClientInfo& aLoadingClientInfo,
    234    const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController,
    235    nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType,
    236    nsICookieJarSettings* aCookieJarSettings = nullptr,
    237    mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
    238    nsILoadGroup* aLoadGroup = nullptr,
    239    nsIInterfaceRequestor* aCallbacks = nullptr,
    240    nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL,
    241    nsIIOService* aIoService = nullptr);
    242 
    243 // See NS_NewChannelInternal for usage and argument description
    244 nsresult NS_NewChannel(
    245    nsIChannel** outChannel, nsIURI* aUri, nsINode* aLoadingNode,
    246    nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType,
    247    mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
    248    nsILoadGroup* aLoadGroup = nullptr,
    249    nsIInterfaceRequestor* aCallbacks = nullptr,
    250    nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL,
    251    nsIIOService* aIoService = nullptr, uint32_t aSandboxFlags = 0);
    252 
    253 // See NS_NewChannelInternal for usage and argument description
    254 nsresult NS_NewChannel(
    255    nsIChannel** outChannel, nsIURI* aUri, nsIPrincipal* aLoadingPrincipal,
    256    nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType,
    257    nsICookieJarSettings* aCookieJarSettings = nullptr,
    258    mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
    259    nsILoadGroup* aLoadGroup = nullptr,
    260    nsIInterfaceRequestor* aCallbacks = nullptr,
    261    nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL,
    262    nsIIOService* aIoService = nullptr, uint32_t aSandboxFlags = 0);
    263 
    264 // See NS_NewChannelInternal for usage and argument description
    265 nsresult NS_NewChannel(
    266    nsIChannel** outChannel, nsIURI* aUri, nsIPrincipal* aLoadingPrincipal,
    267    const mozilla::dom::ClientInfo& aLoadingClientInfo,
    268    const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController,
    269    nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType,
    270    nsICookieJarSettings* aCookieJarSettings = nullptr,
    271    mozilla::dom::PerformanceStorage* aPerformanceStorage = nullptr,
    272    nsILoadGroup* aLoadGroup = nullptr,
    273    nsIInterfaceRequestor* aCallbacks = nullptr,
    274    nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL,
    275    nsIIOService* aIoService = nullptr, uint32_t aSandboxFlags = 0);
    276 
    277 nsresult NS_GetIsDocumentChannel(nsIChannel* aChannel, bool* aIsDocument);
    278 
    279 nsresult NS_MakeAbsoluteURI(nsACString& result, const nsACString& spec,
    280                            nsIURI* baseURI);
    281 
    282 nsresult NS_MakeAbsoluteURI(char** result, const char* spec, nsIURI* baseURI);
    283 
    284 nsresult NS_MakeAbsoluteURI(nsAString& result, const nsAString& spec,
    285                            nsIURI* baseURI);
    286 
    287 /**
    288 * This function is a helper function to get a scheme's default port.
    289 */
    290 int32_t NS_GetDefaultPort(const char* scheme,
    291                          nsIIOService* ioService = nullptr);
    292 
    293 /**
    294 * The UTS #46 ToASCII operation as parametrized by the WHATWG URL Standard.
    295 *
    296 * Use this function to prepare a host name for network protocols.
    297 *
    298 * Do not try to optimize and avoid calling this function if you already
    299 * have ASCII. This function optimizes internally, and calling it is
    300 * required for correctness!
    301 *
    302 * Use `NS_DomainToDisplayAndASCII` if you need both this function and
    303 * `NS_DomainToDisplay` together.
    304 *
    305 * The function is available to privileged JavaScript callers via
    306 * nsIIDNService.
    307 *
    308 * Rust callers that don't happen to be using XPCOM strings are better
    309 * off using the `idna` crate directly.
    310 */
    311 inline nsresult NS_DomainToASCII(const nsACString& aDomain,
    312                                 nsACString& aASCII) {
    313  return mozilla_net_domain_to_ascii_impl(&aDomain, false, &aASCII);
    314 }
    315 
    316 /**
    317 * Bogus variant for callers that try pass through IPv6 addresses or even port
    318 * numbers!
    319 */
    320 inline nsresult NS_DomainToASCIIAllowAnyGlyphfulASCII(const nsACString& aDomain,
    321                                                      nsACString& aASCII) {
    322  return mozilla_net_domain_to_ascii_impl(&aDomain, true, &aASCII);
    323 }
    324 
    325 /**
    326 * The UTS #46 ToUnicode operation as parametrized by the WHATWG URL Standard,
    327 * except potentially misleading labels are treated according to ToASCII
    328 * instead.
    329 *
    330 * Use this function to prepare a host name for display to the user.
    331 *
    332 * Use `NS_DomainToDisplayAndASCII` if you need both this function and
    333 * `NS_DomainToASCII` together.
    334 *
    335 * The function is available to privileged JavaScript callers via
    336 * nsIIDNService.
    337 *
    338 * Rust callers that don't happen to be using XPCOM strings are better
    339 * off using the `idna` crate directly. (See `idna_glue` for what policy
    340 * closure to use.)
    341 */
    342 inline nsresult NS_DomainToDisplay(const nsACString& aDomain,
    343                                   nsACString& aDisplay) {
    344  return mozilla_net_domain_to_display_impl(&aDomain, false, &aDisplay);
    345 }
    346 
    347 /**
    348 * Bogus variant for callers that try pass through IPv6 addresses or even port
    349 * numbers!
    350 */
    351 inline nsresult NS_DomainToDisplayAllowAnyGlyphfulASCII(
    352    const nsACString& aDomain, nsACString& aDisplay) {
    353  return mozilla_net_domain_to_display_impl(&aDomain, true, &aDisplay);
    354 }
    355 
    356 /**
    357 * The UTS #46 ToUnicode operation as parametrized by the WHATWG URL Standard.
    358 *
    359 * It's most likely INCORRECT to call this function, and `NS_DomainToDisplay`
    360 * should typically be called instead. Please avoid adding new callers, so
    361 * that this conversion could be removed entirely!
    362 *
    363 * The function is available to privileged JavaScript callers via
    364 * nsIIDNService.
    365 *
    366 * Rust callers that don't happen to be using XPCOM strings are better
    367 * off using the `idna` crate directly.
    368 */
    369 inline nsresult NS_DomainToUnicode(const nsACString& aDomain,
    370                                   nsACString& aUnicode) {
    371  return mozilla_net_domain_to_unicode_impl(&aDomain, false, &aUnicode);
    372 }
    373 
    374 /**
    375 * Bogus variant for callers that try pass through IPv6 addresses or even port
    376 * numbers!
    377 */
    378 inline nsresult NS_DomainToUnicodeAllowAnyGlyphfulASCII(
    379    const nsACString& aDomain, nsACString& aDisplay) {
    380  return mozilla_net_domain_to_unicode_impl(&aDomain, true, &aDisplay);
    381 }
    382 
    383 /**
    384 * This function is a helper function to get a protocol's default port if the
    385 * URI does not specify a port explicitly. Returns -1 if this protocol has no
    386 * concept of ports or if there was an error getting the port.
    387 */
    388 int32_t NS_GetRealPort(nsIURI* aURI);
    389 
    390 nsresult NS_NewInputStreamChannelInternal(
    391    nsIChannel** outChannel, nsIURI* aUri,
    392    already_AddRefed<nsIInputStream> aStream, const nsACString& aContentType,
    393    const nsACString& aContentCharset, nsILoadInfo* aLoadInfo);
    394 
    395 nsresult NS_NewInputStreamChannelInternal(
    396    nsIChannel** outChannel, nsIURI* aUri,
    397    already_AddRefed<nsIInputStream> aStream, const nsACString& aContentType,
    398    const nsACString& aContentCharset, nsINode* aLoadingNode,
    399    nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal,
    400    nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType);
    401 
    402 nsresult NS_NewInputStreamChannel(nsIChannel** outChannel, nsIURI* aUri,
    403                                  already_AddRefed<nsIInputStream> aStream,
    404                                  nsIPrincipal* aLoadingPrincipal,
    405                                  nsSecurityFlags aSecurityFlags,
    406                                  nsContentPolicyType aContentPolicyType,
    407                                  const nsACString& aContentType = ""_ns,
    408                                  const nsACString& aContentCharset = ""_ns);
    409 
    410 nsresult NS_NewInputStreamChannelInternal(
    411    nsIChannel** outChannel, nsIURI* aUri, const nsAString& aData,
    412    const nsACString& aContentType, nsINode* aLoadingNode,
    413    nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal,
    414    nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType,
    415    bool aIsSrcdocChannel = false);
    416 
    417 nsresult NS_NewInputStreamChannelInternal(nsIChannel** outChannel, nsIURI* aUri,
    418                                          const nsAString& aData,
    419                                          const nsACString& aContentType,
    420                                          nsILoadInfo* aLoadInfo,
    421                                          bool aIsSrcdocChannel = false);
    422 
    423 nsresult NS_NewInputStreamChannel(nsIChannel** outChannel, nsIURI* aUri,
    424                                  const nsAString& aData,
    425                                  const nsACString& aContentType,
    426                                  nsIPrincipal* aLoadingPrincipal,
    427                                  nsSecurityFlags aSecurityFlags,
    428                                  nsContentPolicyType aContentPolicyType,
    429                                  bool aIsSrcdocChannel = false);
    430 
    431 nsresult NS_NewInputStreamPump(
    432    nsIInputStreamPump** aResult, already_AddRefed<nsIInputStream> aStream,
    433    uint32_t aSegsize = 0, uint32_t aSegcount = 0, bool aCloseWhenDone = false,
    434    nsISerialEventTarget* aMainThreadTarget = nullptr);
    435 
    436 nsresult NS_NewLoadGroup(nsILoadGroup** result, nsIRequestObserver* obs);
    437 
    438 // Create a new nsILoadGroup that will match the given principal.
    439 nsresult NS_NewLoadGroup(nsILoadGroup** aResult, nsIPrincipal* aPrincipal);
    440 
    441 // Determine if the given loadGroup/principal pair will produce a principal
    442 // with similar permissions when passed to NS_NewChannel().  This checks for
    443 // things like making sure the browser element flag matches.  Without
    444 // an appropriate load group these values can be lost when getting the result
    445 // principal back out of the channel.  Null principals are also always allowed
    446 // as they do not have permissions to actually use the load group.
    447 bool NS_LoadGroupMatchesPrincipal(nsILoadGroup* aLoadGroup,
    448                                  nsIPrincipal* aPrincipal);
    449 
    450 nsresult NS_NewDownloader(nsIStreamListener** result,
    451                          nsIDownloadObserver* observer,
    452                          nsIFile* downloadLocation = nullptr);
    453 
    454 nsresult NS_NewStreamLoader(nsIStreamLoader** result,
    455                            nsIStreamLoaderObserver* observer,
    456                            nsIRequestObserver* requestObserver = nullptr);
    457 
    458 nsresult NS_NewIncrementalStreamLoader(
    459    nsIIncrementalStreamLoader** result,
    460    nsIIncrementalStreamLoaderObserver* observer);
    461 
    462 nsresult NS_NewStreamLoaderInternal(
    463    nsIStreamLoader** outStream, nsIURI* aUri,
    464    nsIStreamLoaderObserver* aObserver, nsINode* aLoadingNode,
    465    nsIPrincipal* aLoadingPrincipal, nsSecurityFlags aSecurityFlags,
    466    nsContentPolicyType aContentPolicyType, nsILoadGroup* aLoadGroup = nullptr,
    467    nsIInterfaceRequestor* aCallbacks = nullptr,
    468    nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL);
    469 
    470 nsresult NS_NewStreamLoader(nsIStreamLoader** outStream, nsIURI* aUri,
    471                            nsIStreamLoaderObserver* aObserver,
    472                            nsINode* aLoadingNode,
    473                            nsSecurityFlags aSecurityFlags,
    474                            nsContentPolicyType aContentPolicyType,
    475                            nsILoadGroup* aLoadGroup = nullptr,
    476                            nsIInterfaceRequestor* aCallbacks = nullptr,
    477                            nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL);
    478 
    479 nsresult NS_NewStreamLoader(nsIStreamLoader** outStream, nsIURI* aUri,
    480                            nsIStreamLoaderObserver* aObserver,
    481                            nsIPrincipal* aLoadingPrincipal,
    482                            nsSecurityFlags aSecurityFlags,
    483                            nsContentPolicyType aContentPolicyType,
    484                            nsILoadGroup* aLoadGroup = nullptr,
    485                            nsIInterfaceRequestor* aCallbacks = nullptr,
    486                            nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL);
    487 
    488 nsresult NS_NewSyncStreamListener(nsIStreamListener** result,
    489                                  nsIInputStream** stream);
    490 
    491 /**
    492 * Implement the nsIChannel::Open(nsIInputStream**) method using the channel's
    493 * AsyncOpen method.
    494 *
    495 * NOTE: Reading from the returned nsIInputStream may spin the current
    496 * thread's event queue, which could result in any event being processed.
    497 */
    498 nsresult NS_ImplementChannelOpen(nsIChannel* channel, nsIInputStream** result);
    499 
    500 nsresult NS_NewRequestObserverProxy(nsIRequestObserver** result,
    501                                    nsIRequestObserver* observer,
    502                                    nsISupports* context);
    503 
    504 nsresult NS_NewSimpleStreamListener(nsIStreamListener** result,
    505                                    nsIOutputStream* sink,
    506                                    nsIRequestObserver* observer = nullptr);
    507 
    508 nsresult NS_CheckPortSafety(int32_t port, const char* scheme,
    509                            nsIIOService* ioService = nullptr);
    510 
    511 // Determine if this URI is using a safe port.
    512 nsresult NS_CheckPortSafety(nsIURI* uri);
    513 
    514 nsresult NS_GetFileProtocolHandler(nsIFileProtocolHandler** result,
    515                                   nsIIOService* ioService = nullptr);
    516 
    517 nsresult NS_GetFileFromURLSpec(const nsACString& inURL, nsIFile** result,
    518                               nsIIOService* ioService = nullptr);
    519 
    520 nsresult NS_GetURLSpecFromFile(nsIFile* file, nsACString& url,
    521                               nsIIOService* ioService = nullptr);
    522 
    523 /**
    524 * Converts the nsIFile to the corresponding URL string.
    525 * Should only be called on files which are not directories,
    526 * is otherwise identical to NS_GetURLSpecFromFile, but is
    527 * usually more efficient.
    528 * Warning: this restriction may not be enforced at runtime!
    529 */
    530 nsresult NS_GetURLSpecFromActualFile(nsIFile* file, nsACString& url,
    531                                     nsIIOService* ioService = nullptr);
    532 
    533 /**
    534 * Converts the nsIFile to the corresponding URL string.
    535 * Should only be called on files which are directories,
    536 * is otherwise identical to NS_GetURLSpecFromFile, but is
    537 * usually more efficient.
    538 * Warning: this restriction may not be enforced at runtime!
    539 */
    540 nsresult NS_GetURLSpecFromDir(nsIFile* file, nsACString& url,
    541                              nsIIOService* ioService = nullptr);
    542 
    543 /**
    544 * Obtains the referrer for a given channel.  This first tries to obtain the
    545 * referrer from the property docshell.internalReferrer, and if that doesn't
    546 * work and the channel is an nsIHTTPChannel, we check it's referrer property.
    547 *
    548 */
    549 void NS_GetReferrerFromChannel(nsIChannel* channel, nsIURI** referrer);
    550 
    551 nsresult NS_ParseRequestContentType(const nsACString& rawContentType,
    552                                    nsCString& contentType,
    553                                    nsCString& contentCharset);
    554 
    555 nsresult NS_ParseResponseContentType(const nsACString& rawContentType,
    556                                     nsCString& contentType,
    557                                     nsCString& contentCharset);
    558 
    559 nsresult NS_ExtractCharsetFromContentType(const nsACString& rawContentType,
    560                                          nsCString& contentCharset,
    561                                          bool* hadCharset,
    562                                          int32_t* charsetStart,
    563                                          int32_t* charsetEnd);
    564 
    565 nsresult NS_NewLocalFileInputStream(nsIInputStream** result, nsIFile* file,
    566                                    int32_t ioFlags = -1, int32_t perm = -1,
    567                                    int32_t behaviorFlags = 0);
    568 
    569 mozilla::Result<nsCOMPtr<nsIInputStream>, nsresult> NS_NewLocalFileInputStream(
    570    nsIFile* file, int32_t ioFlags = -1, int32_t perm = -1,
    571    int32_t behaviorFlags = 0);
    572 
    573 nsresult NS_NewLocalFileOutputStream(nsIOutputStream** result, nsIFile* file,
    574                                     int32_t ioFlags = -1, int32_t perm = -1,
    575                                     int32_t behaviorFlags = 0);
    576 
    577 mozilla::Result<nsCOMPtr<nsIOutputStream>, nsresult>
    578 NS_NewLocalFileOutputStream(nsIFile* file, int32_t ioFlags = -1,
    579                            int32_t perm = -1, int32_t behaviorFlags = 0);
    580 
    581 nsresult NS_NewLocalFileOutputStream(nsIOutputStream** result,
    582                                     const mozilla::ipc::FileDescriptor& fd);
    583 
    584 // returns a file output stream which can be QI'ed to nsISafeOutputStream.
    585 nsresult NS_NewAtomicFileOutputStream(nsIOutputStream** result, nsIFile* file,
    586                                      int32_t ioFlags = -1, int32_t perm = -1,
    587                                      int32_t behaviorFlags = 0);
    588 
    589 // returns a file output stream which can be QI'ed to nsISafeOutputStream.
    590 nsresult NS_NewSafeLocalFileOutputStream(nsIOutputStream** result,
    591                                         nsIFile* file, int32_t ioFlags = -1,
    592                                         int32_t perm = -1,
    593                                         int32_t behaviorFlags = 0);
    594 
    595 nsresult NS_NewLocalFileRandomAccessStream(nsIRandomAccessStream** result,
    596                                           nsIFile* file, int32_t ioFlags = -1,
    597                                           int32_t perm = -1,
    598                                           int32_t behaviorFlags = 0);
    599 
    600 mozilla::Result<nsCOMPtr<nsIRandomAccessStream>, nsresult>
    601 NS_NewLocalFileRandomAccessStream(nsIFile* file, int32_t ioFlags = -1,
    602                                  int32_t perm = -1, int32_t behaviorFlags = 0);
    603 
    604 [[nodiscard]] nsresult NS_NewBufferedInputStream(
    605    nsIInputStream** aResult, already_AddRefed<nsIInputStream> aInputStream,
    606    uint32_t aBufferSize);
    607 
    608 mozilla::Result<nsCOMPtr<nsIInputStream>, nsresult> NS_NewBufferedInputStream(
    609    already_AddRefed<nsIInputStream> aInputStream, uint32_t aBufferSize);
    610 
    611 // note: the resulting stream can be QI'ed to nsISafeOutputStream iff the
    612 // provided stream supports it.
    613 nsresult NS_NewBufferedOutputStream(
    614    nsIOutputStream** aResult, already_AddRefed<nsIOutputStream> aOutputStream,
    615    uint32_t aBufferSize);
    616 
    617 /**
    618 * This function reads an inputStream and stores its content into a buffer. In
    619 * general, you should avoid using this function because, it blocks the current
    620 * thread until the operation is done.
    621 * If the inputStream is async, the reading happens on an I/O thread.
    622 *
    623 * @param aInputStream the inputStream.
    624 * @param aDest the destination buffer. if *aDest is null, it will be allocated
    625 *              with the size of the written data. if aDest is not null, aCount
    626 *              must greater than 0.
    627 * @param aCount the amount of data to read. Use -1 if you want that all the
    628 *               stream is read.
    629 * @param aWritten this pointer will be used to store the number of data
    630 *                 written in the buffer. If you don't need, pass nullptr.
    631 */
    632 nsresult NS_ReadInputStreamToBuffer(nsIInputStream* aInputStream, void** aDest,
    633                                    int64_t aCount,
    634                                    uint64_t* aWritten = nullptr);
    635 
    636 /**
    637 * See the comment for NS_ReadInputStreamToBuffer
    638 */
    639 nsresult NS_ReadInputStreamToString(nsIInputStream* aInputStream,
    640                                    nsACString& aDest, int64_t aCount,
    641                                    uint64_t* aWritten = nullptr);
    642 
    643 nsresult NS_LoadPersistentPropertiesFromURISpec(
    644    nsIPersistentProperties** outResult, const nsACString& aSpec);
    645 
    646 /**
    647 * NS_QueryNotificationCallbacks implements the canonical algorithm for
    648 * querying interfaces from a channel's notification callbacks.  It first
    649 * searches the channel's notificationCallbacks attribute, and if the interface
    650 * is not found there, then it inspects the notificationCallbacks attribute of
    651 * the channel's loadGroup.
    652 *
    653 * Note: templatized only because nsIWebSocketChannel is currently not an
    654 * nsIChannel.
    655 */
    656 template <class T>
    657 inline void NS_QueryNotificationCallbacks(T* channel, const nsIID& iid,
    658                                          void** result) {
    659  MOZ_ASSERT(channel, "null channel");
    660  *result = nullptr;
    661 
    662  nsCOMPtr<nsIInterfaceRequestor> cbs;
    663  (void)channel->GetNotificationCallbacks(getter_AddRefs(cbs));
    664  if (cbs) cbs->GetInterface(iid, result);
    665  if (!*result) {
    666    // try load group's notification callbacks...
    667    nsCOMPtr<nsILoadGroup> loadGroup;
    668    (void)channel->GetLoadGroup(getter_AddRefs(loadGroup));
    669    if (loadGroup) {
    670      loadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
    671      if (cbs) cbs->GetInterface(iid, result);
    672    }
    673  }
    674 }
    675 
    676 // template helper:
    677 // Note: "class C" templatized only because nsIWebSocketChannel is currently not
    678 // an nsIChannel.
    679 
    680 template <class C, class T>
    681 inline void NS_QueryNotificationCallbacks(C* channel, nsCOMPtr<T>& result) {
    682  NS_QueryNotificationCallbacks(channel, NS_GET_IID(T), getter_AddRefs(result));
    683 }
    684 
    685 /**
    686 * Alternate form of NS_QueryNotificationCallbacks designed for use by
    687 * nsIChannel implementations.
    688 */
    689 inline void NS_QueryNotificationCallbacks(nsIInterfaceRequestor* callbacks,
    690                                          nsILoadGroup* loadGroup,
    691                                          const nsIID& iid, void** result) {
    692  *result = nullptr;
    693 
    694  if (callbacks) callbacks->GetInterface(iid, result);
    695  if (!*result) {
    696    // try load group's notification callbacks...
    697    if (loadGroup) {
    698      nsCOMPtr<nsIInterfaceRequestor> cbs;
    699      loadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
    700      if (cbs) cbs->GetInterface(iid, result);
    701    }
    702  }
    703 }
    704 
    705 /**
    706 * Returns true if channel is using Private Browsing, or false if not.
    707 * Returns false if channel's callbacks don't implement nsILoadContext.
    708 */
    709 bool NS_UsePrivateBrowsing(nsIChannel* channel);
    710 
    711 /**
    712 * Returns true if the channel has visited any cross-origin URLs on any
    713 * URLs that it was redirected through.
    714 */
    715 bool NS_HasBeenCrossOrigin(nsIChannel* aChannel, bool aReport = false);
    716 
    717 /**
    718 * Returns true if the channel has a safe method.
    719 */
    720 bool NS_IsSafeMethodNav(nsIChannel* aChannel);
    721 
    722 // Unique first-party domain for separating the safebrowsing cookie.
    723 // Note if this value is changed, code in test_cookiejars_safebrowsing.js and
    724 // nsUrlClassifierHashCompleter.js should also be changed.
    725 #define NECKO_SAFEBROWSING_FIRST_PARTY_DOMAIN \
    726  "safebrowsing.86868755-6b82-4842-b301-72671a0db32e.mozilla"
    727 
    728 // Unique first-party domain for separating about uri.
    729 #define ABOUT_URI_FIRST_PARTY_DOMAIN \
    730  "about.ef2a7dd5-93bc-417f-a698-142c3116864f.mozilla"
    731 
    732 /**
    733 * Wraps an nsIAuthPrompt so that it can be used as an nsIAuthPrompt2. This
    734 * method is provided mainly for use by other methods in this file.
    735 *
    736 * *aAuthPrompt2 should be set to null before calling this function.
    737 */
    738 void NS_WrapAuthPrompt(nsIAuthPrompt* aAuthPrompt,
    739                       nsIAuthPrompt2** aAuthPrompt2);
    740 
    741 /**
    742 * Gets an auth prompt from an interface requestor. This takes care of wrapping
    743 * an nsIAuthPrompt so that it can be used as an nsIAuthPrompt2.
    744 */
    745 void NS_QueryAuthPrompt2(nsIInterfaceRequestor* aCallbacks,
    746                         nsIAuthPrompt2** aAuthPrompt);
    747 
    748 /**
    749 * Gets an nsIAuthPrompt2 from a channel. Use this instead of
    750 * NS_QueryNotificationCallbacks for better backwards compatibility.
    751 */
    752 void NS_QueryAuthPrompt2(nsIChannel* aChannel, nsIAuthPrompt2** aAuthPrompt);
    753 
    754 /* template helper */
    755 template <class T>
    756 inline void NS_QueryNotificationCallbacks(nsIInterfaceRequestor* callbacks,
    757                                          nsILoadGroup* loadGroup,
    758                                          nsCOMPtr<T>& result) {
    759  NS_QueryNotificationCallbacks(callbacks, loadGroup, NS_GET_IID(T),
    760                                getter_AddRefs(result));
    761 }
    762 
    763 /* template helper */
    764 template <class T>
    765 inline void NS_QueryNotificationCallbacks(
    766    const nsCOMPtr<nsIInterfaceRequestor>& aCallbacks,
    767    const nsCOMPtr<nsILoadGroup>& aLoadGroup, nsCOMPtr<T>& aResult) {
    768  NS_QueryNotificationCallbacks(aCallbacks.get(), aLoadGroup.get(), aResult);
    769 }
    770 
    771 /* template helper */
    772 template <class T>
    773 inline void NS_QueryNotificationCallbacks(const nsCOMPtr<nsIChannel>& aChannel,
    774                                          nsCOMPtr<T>& aResult) {
    775  NS_QueryNotificationCallbacks(aChannel.get(), aResult);
    776 }
    777 
    778 /**
    779 * This function returns a nsIInterfaceRequestor instance that returns the
    780 * same result as NS_QueryNotificationCallbacks when queried.  It is useful
    781 * as the value for nsISocketTransport::securityCallbacks.
    782 */
    783 nsresult NS_NewNotificationCallbacksAggregation(
    784    nsIInterfaceRequestor* callbacks, nsILoadGroup* loadGroup,
    785    nsIEventTarget* target, nsIInterfaceRequestor** result);
    786 
    787 nsresult NS_NewNotificationCallbacksAggregation(
    788    nsIInterfaceRequestor* callbacks, nsILoadGroup* loadGroup,
    789    nsIInterfaceRequestor** result);
    790 
    791 /**
    792 * Helper function for testing online/offline state of the browser.
    793 */
    794 bool NS_IsOffline();
    795 
    796 /**
    797 * Helper functions for implementing nsINestedURI::innermostURI.
    798 *
    799 * Note that NS_DoImplGetInnermostURI is "private" -- call
    800 * NS_ImplGetInnermostURI instead.
    801 */
    802 nsresult NS_DoImplGetInnermostURI(nsINestedURI* nestedURI, nsIURI** result);
    803 
    804 nsresult NS_ImplGetInnermostURI(nsINestedURI* nestedURI, nsIURI** result);
    805 
    806 /**
    807 * Helper function for testing whether the given URI, or any of its
    808 * inner URIs, has all the given protocol flags.
    809 */
    810 nsresult NS_URIChainHasFlags(nsIURI* uri, uint32_t flags, bool* result);
    811 
    812 /**
    813 * Helper function for getting the innermost URI for a given URI.  The return
    814 * value could be just the object passed in if it's not a nested URI.
    815 */
    816 already_AddRefed<nsIURI> NS_GetInnermostURI(nsIURI* aURI);
    817 
    818 /**
    819 * Helper function for getting the host name of the innermost URI for a given
    820 * URI.  The return value could be the host name of the URI passed in if it's
    821 * not a nested URI.
    822 */
    823 inline nsresult NS_GetInnermostURIHost(nsIURI* aURI, nsACString& aHost) {
    824  aHost.Truncate();
    825 
    826  // This block is optimized in order to avoid the overhead of calling
    827  // NS_GetInnermostURI() which incurs a lot of overhead in terms of
    828  // AddRef/Release calls.
    829  nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(aURI);
    830  if (nestedURI) {
    831    // We have a nested URI!
    832    nsCOMPtr<nsIURI> uri;
    833    nsresult rv = nestedURI->GetInnermostURI(getter_AddRefs(uri));
    834    if (NS_FAILED(rv)) {
    835      return rv;
    836    }
    837 
    838    rv = uri->GetAsciiHost(aHost);
    839    if (NS_FAILED(rv)) {
    840      return rv;
    841    }
    842  } else {
    843    // We have a non-nested URI!
    844    nsresult rv = aURI->GetAsciiHost(aHost);
    845    if (NS_FAILED(rv)) {
    846      return rv;
    847    }
    848  }
    849 
    850  return NS_OK;
    851 }
    852 
    853 /**
    854 * Get the "final" URI for a channel.  This is either channel's load info
    855 * resultPrincipalURI, if set, or GetOriginalURI.  In most cases (but not all)
    856 * load info resultPrincipalURI, if set, corresponds to URI of the channel if
    857 * it's required to represent the actual principal for the channel.
    858 */
    859 nsresult NS_GetFinalChannelURI(nsIChannel* channel, nsIURI** uri);
    860 
    861 // NS_SecurityHashURI must return the same hash value for any two URIs that
    862 // compare equal according to NS_SecurityCompareURIs.  Unfortunately, in the
    863 // case of files, it's not clear we can do anything better than returning
    864 // the schemeHash, so hashing files degenerates to storing them in a list.
    865 uint32_t NS_SecurityHashURI(nsIURI* aURI);
    866 
    867 bool NS_SecurityCompareURIs(nsIURI* aSourceURI, nsIURI* aTargetURI,
    868                            bool aStrictFileOriginPolicy);
    869 
    870 bool NS_URIIsLocalFile(nsIURI* aURI);
    871 
    872 bool NS_IsInternalSameURIRedirect(nsIChannel* aOldChannel,
    873                                  nsIChannel* aNewChannel, uint32_t aFlags);
    874 
    875 bool NS_IsHSTSUpgradeRedirect(nsIChannel* aOldChannel, nsIChannel* aNewChannel,
    876                              uint32_t aFlags);
    877 
    878 bool NS_ShouldRemoveAuthHeaderOnRedirect(nsIChannel* aOldChannel,
    879                                         nsIChannel* aNewChannel,
    880                                         uint32_t aFlags);
    881 
    882 nsresult NS_LinkRedirectChannels(uint64_t channelId,
    883                                 nsIParentChannel* parentChannel,
    884                                 nsIChannel** _result);
    885 
    886 /**
    887 * Returns nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP if `aHeader` is
    888 * "require-corp" and nsILoadInfo::EMBEDDER_POLICY_NULL otherwise.
    889 *
    890 * See: https://mikewest.github.io/corpp/#parsing
    891 */
    892 nsILoadInfo::CrossOriginEmbedderPolicy
    893 NS_GetCrossOriginEmbedderPolicyFromHeader(
    894    const nsACString& aHeader, bool aIsOriginTrialCoepCredentiallessEnabled);
    895 
    896 /**
    897 * Return true if the header is a dictionary where the key force-load-at-top
    898 * has the value true. Otherwise, return false.
    899 */
    900 bool NS_GetForceLoadAtTopFromHeader(const nsACString& aHeader);
    901 
    902 /** Given the first (disposition) token from a Content-Disposition header,
    903 * tell whether it indicates the content is inline or attachment
    904 * @param aDispToken the disposition token from the content-disposition header
    905 */
    906 uint32_t NS_GetContentDispositionFromToken(const nsAString& aDispToken);
    907 
    908 /** Determine the disposition (inline/attachment) of the content based on the
    909 * Content-Disposition header
    910 * @param aHeader the content-disposition header (full value)
    911 * @param aChan the channel the header came from
    912 */
    913 uint32_t NS_GetContentDispositionFromHeader(const nsACString& aHeader,
    914                                            nsIChannel* aChan = nullptr);
    915 
    916 /** Extracts the filename out of a content-disposition header
    917 * @param aFilename [out] The filename. Can be empty on error.
    918 * @param aDisposition Value of a Content-Disposition header
    919 
    920 */
    921 nsresult NS_GetFilenameFromDisposition(nsAString& aFilename,
    922                                       const nsACString& aDisposition);
    923 
    924 /**
    925 * Make sure Personal Security Manager is initialized
    926 */
    927 void net_EnsurePSMInit();
    928 
    929 /**
    930 * Test whether a URI is "about:blank".  |uri| must not be null
    931 */
    932 bool NS_IsAboutBlank(nsIURI* uri);
    933 
    934 /**
    935 * Test whether a URI is "about:blank", possibly with fragment or query.  |uri|
    936 * must not be null
    937 */
    938 bool NS_IsAboutBlankAllowQueryAndFragment(nsIURI* uri);
    939 
    940 /**
    941 * Test whether a URI is "about:srcdoc".  |uri| must not be null
    942 */
    943 bool NS_IsAboutSrcdoc(nsIURI* uri);
    944 
    945 /**
    946 * Test whether a URI has an "about", "blob", "data", "file", or an HTTP(S)
    947 * scheme.
    948 */
    949 bool NS_IsFetchScheme(nsIURI* uri);
    950 
    951 nsresult NS_GenerateHostPort(const nsCString& host, int32_t port,
    952                             nsACString& hostLine);
    953 
    954 /**
    955 * Sniff the content type for a given request or a given buffer.
    956 *
    957 * aSnifferType can be either NS_CONTENT_SNIFFER_CATEGORY or
    958 * NS_DATA_SNIFFER_CATEGORY.  The function returns the sniffed content type
    959 * in the aSniffedType argument.  This argument will not be modified if the
    960 * content type could not be sniffed.
    961 */
    962 void NS_SniffContent(const char* aSnifferType, nsIRequest* aRequest,
    963                     const uint8_t* aData, uint32_t aLength,
    964                     nsACString& aSniffedType);
    965 
    966 /**
    967 * Whether the channel was created to load a srcdoc document.
    968 * Note that view-source:about:srcdoc is classified as a srcdoc document by
    969 * this function, which may not be applicable everywhere.
    970 */
    971 bool NS_IsSrcdocChannel(nsIChannel* aChannel);
    972 
    973 /**
    974 * Return true if the given string is a reasonable HTTP header value given the
    975 * definition in RFC 2616 section 4.2.  Currently we don't pay the cost to do
    976 * full, sctrict validation here since it would require fulling parsing the
    977 * value.
    978 */
    979 bool NS_IsReasonableHTTPHeaderValue(const nsACString& aValue);
    980 
    981 /**
    982 * Return true if the given string is a valid HTTP token per RFC 2616 section
    983 * 2.2.
    984 */
    985 bool NS_IsValidHTTPToken(const nsACString& aToken);
    986 
    987 /**
    988 * Strip the leading or trailing HTTP whitespace per fetch spec section 2.2.
    989 */
    990 void NS_TrimHTTPWhitespace(const nsACString& aSource, nsACString& aDest);
    991 
    992 template <typename Char>
    993 constexpr bool NS_IsHTTPTokenPoint(Char aChar) {
    994  using UnsignedChar = typename mozilla::detail::MakeUnsignedChar<Char>::Type;
    995  auto c = static_cast<UnsignedChar>(aChar);
    996  return c == '!' || c == '#' || c == '$' || c == '%' || c == '&' ||
    997         c == '\'' || c == '*' || c == '+' || c == '-' || c == '.' ||
    998         c == '^' || c == '_' || c == '`' || c == '|' || c == '~' ||
    999         mozilla::IsAsciiAlphanumeric(c);
   1000 }
   1001 
   1002 template <typename Char>
   1003 constexpr bool NS_IsHTTPQuotedStringTokenPoint(Char aChar) {
   1004  using UnsignedChar = typename mozilla::detail::MakeUnsignedChar<Char>::Type;
   1005  auto c = static_cast<UnsignedChar>(aChar);
   1006  return c == 0x9 || (c >= ' ' && c <= '~') || mozilla::IsNonAsciiLatin1(c);
   1007 }
   1008 
   1009 template <typename Char>
   1010 constexpr bool NS_IsHTTPWhitespace(Char aChar) {
   1011  using UnsignedChar = typename mozilla::detail::MakeUnsignedChar<Char>::Type;
   1012  auto c = static_cast<UnsignedChar>(aChar);
   1013  return c == 0x9 || c == 0xA || c == 0xD || c == 0x20;
   1014 }
   1015 
   1016 /**
   1017 * Return true if the given request must be upgraded to HTTPS.
   1018 * If |aResultCallback| is provided and the storage is not ready to read, the
   1019 * result will be sent back through the callback and |aWillCallback| will be
   1020 * true. Otherwiew, the result will be set to |aShouldUpgrade| and
   1021 * |aWillCallback| is false.
   1022 */
   1023 nsresult NS_ShouldSecureUpgrade(
   1024    nsIURI* aURI, nsILoadInfo* aLoadInfo, nsIPrincipal* aChannelResultPrincipal,
   1025    bool aAllowSTS, const mozilla::OriginAttributes& aOriginAttributes,
   1026    bool& aShouldUpgrade, std::function<void(bool, nsresult)>&& aResultCallback,
   1027    bool& aWillCallback);
   1028 
   1029 /**
   1030 * Returns an https URI for channels that need to go through secure upgrades.
   1031 */
   1032 nsresult NS_GetSecureUpgradedURI(nsIURI* aURI, nsIURI** aUpgradedURI);
   1033 
   1034 nsresult NS_CompareLoadInfoAndLoadContext(nsIChannel* aChannel);
   1035 
   1036 // The type of classification to perform.
   1037 enum class ClassifyType : uint8_t {
   1038  SafeBrowsing,  // Perform Safe Browsing classification.
   1039  ETP,           // Perform URL Classification for Enhanced Tracking Protection.
   1040 };
   1041 
   1042 /**
   1043 * Return true if this channel should be classified by the URL classifier.
   1044 */
   1045 bool NS_ShouldClassifyChannel(nsIChannel* aChannel, ClassifyType aType);
   1046 
   1047 /**
   1048 * Helper to set the blocking reason on loadinfo of the channel.
   1049 */
   1050 nsresult NS_SetRequestBlockingReason(nsIChannel* channel, uint32_t reason);
   1051 nsresult NS_SetRequestBlockingReason(nsILoadInfo* loadInfo, uint32_t reason);
   1052 nsresult NS_SetRequestBlockingReasonIfNull(nsILoadInfo* loadInfo,
   1053                                           uint32_t reason);
   1054 
   1055 namespace mozilla {
   1056 namespace net {
   1057 
   1058 const static uint64_t kJS_MAX_SAFE_UINTEGER = +9007199254740991ULL;
   1059 const static int64_t kJS_MIN_SAFE_INTEGER = -9007199254740991LL;
   1060 const static int64_t kJS_MAX_SAFE_INTEGER = +9007199254740991LL;
   1061 
   1062 // Make sure a 64bit value can be captured by JS MAX_SAFE_INTEGER
   1063 bool InScriptableRange(int64_t val);
   1064 
   1065 // Make sure a 64bit value can be captured by JS MAX_SAFE_INTEGER
   1066 bool InScriptableRange(uint64_t val);
   1067 
   1068 /**
   1069 * Given the value of a single header field  (such as
   1070 * Content-Disposition and Content-Type) and the name of a parameter
   1071 * (e.g. filename, name, charset), returns the value of the parameter.
   1072 * See nsIMIMEHeaderParam.idl for more information.
   1073 *
   1074 * @param  aHeaderVal        a header string to get the value of a parameter
   1075 *                           from.
   1076 * @param  aParamName        the name of a MIME header parameter (e.g.
   1077 *                           filename, name, charset). If empty or nullptr,
   1078 *                           returns the first (possibly) _unnamed_ 'parameter'.
   1079 * @return the value of <code>aParamName</code> in Unichar(UTF-16).
   1080 */
   1081 nsresult GetParameterHTTP(const nsACString& aHeaderVal, const char* aParamName,
   1082                          nsAString& aResult);
   1083 
   1084 /**
   1085 * Helper function that determines if channel is an HTTP POST.
   1086 *
   1087 * @param aChannel
   1088 *        The channel to test
   1089 *
   1090 * @return True if channel is an HTTP post.
   1091 */
   1092 bool ChannelIsPost(nsIChannel* aChannel);
   1093 
   1094 /**
   1095 * Convenience function for verifying nsIURI scheme is either HTTP or HTTPS.
   1096 */
   1097 bool SchemeIsHttpOrHttps(nsIURI* aURI);
   1098 
   1099 // Helper functions for SetProtocol methods to follow
   1100 // step 2.1 in https://url.spec.whatwg.org/#scheme-state
   1101 bool SchemeIsSpecial(const nsACString&);
   1102 bool IsSchemeChangePermitted(nsIURI*, const nsACString&);
   1103 already_AddRefed<nsIURI> TryChangeProtocol(nsIURI*, const nsACString&);
   1104 
   1105 struct LinkHeader {
   1106  nsString mHref;
   1107  nsString mRel;
   1108  nsString mTitle;
   1109  nsString mNonce;
   1110  nsString mIntegrity;
   1111  nsString mSrcset;
   1112  nsString mSizes;
   1113  nsString mType;
   1114  nsString mMedia;
   1115  nsString mAnchor;
   1116  nsString mCrossOrigin;
   1117  nsString mReferrerPolicy;
   1118  nsString mAs;
   1119  nsString mFetchPriority;
   1120 
   1121  LinkHeader();
   1122  void Reset();
   1123 
   1124  nsresult NewResolveHref(nsIURI** aOutURI, nsIURI* aBaseURI) const;
   1125 
   1126  bool operator==(const LinkHeader& rhs) const;
   1127 
   1128  void MaybeUpdateAttribute(const nsAString& aAttribute,
   1129                            const char16_t* aValue);
   1130 };
   1131 
   1132 // Implements roughly step 2 to 4 of
   1133 // <https://httpwg.org/specs/rfc8288.html#parse-set>.
   1134 nsTArray<LinkHeader> ParseLinkHeader(const nsAString& aLinkData);
   1135 
   1136 enum ASDestination : uint8_t {
   1137  DESTINATION_INVALID,
   1138  DESTINATION_AUDIO,
   1139  DESTINATION_DOCUMENT,
   1140  DESTINATION_EMBED,
   1141  DESTINATION_FONT,
   1142  DESTINATION_IMAGE,
   1143  DESTINATION_MANIFEST,
   1144  DESTINATION_OBJECT,
   1145  DESTINATION_REPORT,
   1146  DESTINATION_SCRIPT,
   1147  DESTINATION_SERVICEWORKER,
   1148  DESTINATION_SHAREDWORKER,
   1149  DESTINATION_STYLE,
   1150  DESTINATION_TRACK,
   1151  DESTINATION_VIDEO,
   1152  DESTINATION_WORKER,
   1153  DESTINATION_XSLT,
   1154  DESTINATION_FETCH,
   1155  DESTINATION_JSON
   1156 };
   1157 
   1158 void ParseAsValue(const nsAString& aValue, nsAttrValue& aResult);
   1159 nsContentPolicyType AsValueToContentPolicy(const nsAttrValue& aValue);
   1160 bool IsScriptLikeOrInvalid(const nsAString& aAs);
   1161 
   1162 bool CheckPreloadAttrs(const nsAttrValue& aAs, const nsAString& aType,
   1163                       const nsAString& aMedia,
   1164                       mozilla::dom::Document* aDocument);
   1165 void WarnIgnoredPreload(const mozilla::dom::Document&, nsIURI&);
   1166 
   1167 // Implements parsing of Use-As-Dictionary headers for Compression Dictionary
   1168 // support.
   1169 bool NS_ParseUseAsDictionary(const nsACString& aValue, nsACString& aMatch,
   1170                             nsACString& aMatchId,
   1171                             nsTArray<nsCString>& aMatchDestItems,
   1172                             nsACString& aType);
   1173 
   1174 /**
   1175 * Returns true if the |aInput| in is part of the root domain of |aHost|.
   1176 * For example, if |aInput| is "www.mozilla.org", and we pass in
   1177 * "mozilla.org" as |aHost|, this will return true.  It would return false
   1178 * the other way around.
   1179 *
   1180 * @param aInput The host to be analyzed.
   1181 * @param aHost  The host to compare to.
   1182 */
   1183 nsresult HasRootDomain(const nsACString& aInput, const nsACString& aHost,
   1184                       bool* aResult);
   1185 
   1186 void CheckForBrokenChromeURL(nsILoadInfo* aLoadInfo, nsIURI* aURI);
   1187 
   1188 bool IsCoepCredentiallessEnabled(bool aIsOriginTrialCoepCredentiallessEnabled);
   1189 
   1190 void ParseSimpleURISchemes(const nsACString& schemeList);
   1191 
   1192 nsresult AddExtraHeaders(nsIHttpChannel* aHttpChannel,
   1193                         const nsACString& aExtraHeaders, bool aMerge = true);
   1194 
   1195 bool IsLocalOrPrivateNetworkAccess(
   1196    nsILoadInfo::IPAddressSpace aParentIPAddressSpace,
   1197    nsILoadInfo::IPAddressSpace aTargetIPAddressSpace);
   1198 bool IsPrivateNetworkAccess(
   1199    const nsILoadInfo::IPAddressSpace aParentIPAddressSpace,
   1200    const nsILoadInfo::IPAddressSpace aTargetIPAddressSpace);
   1201 bool IsLocalHostAccess(const nsILoadInfo::IPAddressSpace aParentIPAddressSpace,
   1202                       const nsILoadInfo::IPAddressSpace aTargetIPAddressSpace);
   1203 
   1204 enum ActivateStorageAccessVariant {
   1205  // The server's response instructs the user agent to activate storage access
   1206  // before continuing with the load of the resource. (This is only relevant
   1207  // when loading a new document)
   1208  //     Activate-Storage-Access: load
   1209  Load,
   1210  // The server's response instructs the user agent to activate storage access,
   1211  // then retry the request. The "allowed-origin" parameter allowlists the
   1212  // request's origin.
   1213  //     Activate-Storage-Access: retry; allowed-origin="https://foo.bar"
   1214  RetryOrigin,
   1215  // Same as above, but using a wildcard instead of explicitly naming the
   1216  // request's origin.
   1217  //     Activate-Storage-Access: retry; allowed-origin=*
   1218  RetryAny,
   1219 };
   1220 
   1221 struct ActivateStorageAccess {
   1222  ActivateStorageAccessVariant variant;
   1223  // string from allowed-origin in case ActivateOrigin of ActivateOrigin-Variant
   1224  // above
   1225  nsCString origin;
   1226 };
   1227 
   1228 Result<ActivateStorageAccess, nsresult> ParseActivateStorageAccess(
   1229    const nsACString& aActivateStorageAcess);
   1230 
   1231 }  // namespace net
   1232 }  // namespace mozilla
   1233 
   1234 #endif  // !nsNetUtil_h__