/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: ft=cpp tw=78 sw=2 et ts=2 sts=2 cin
 * 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/. */

#include "nsISupports.idl"
#include "nsIContentPolicy.idl"

interface nsIChannel;
interface nsIDOMDocument;
interface nsINode;
interface nsIPrincipal;
interface nsIRedirectHistoryEntry;
interface nsIURI;
%{C++
#include "nsTArray.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/LoadTainting.h"
#include "mozilla/UniquePtr.h"
#include "nsStringFwd.h"

namespace mozilla {
namespace dom {
class ClientInfo;
class ClientSource;
class ServiceWorkerDescriptor;
} // namespace dom
} // namespace mozilla
%}

[ref] native nsIRedirectHistoryEntryArray(const nsTArray<nsCOMPtr<nsIRedirectHistoryEntry>>);
native OriginAttributes(mozilla::OriginAttributes);
[ref] native const_OriginAttributesRef(const mozilla::OriginAttributes);
[ref] native StringArrayRef(const nsTArray<nsCString>);
[ref] native Uint64ArrayRef(const nsTArray<uint64_t>);
[ref] native PrincipalArrayRef(const nsTArray<nsCOMPtr<nsIPrincipal>>);
[ref] native const_ClientInfoRef(const mozilla::dom::ClientInfo);
      native UniqueClientSource(mozilla::UniquePtr<mozilla::dom::ClientSource>);
      native UniqueClientSourceMove(mozilla::UniquePtr<mozilla::dom::ClientSource>&&);
[ref] native const_MaybeClientInfoRef(const mozilla::Maybe<mozilla::dom::ClientInfo>);
[ref] native const_ServiceWorkerDescriptorRef(const mozilla::dom::ServiceWorkerDescriptor);
[ref] native const_MaybeServiceWorkerDescriptorRef(const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>);

typedef unsigned long nsSecurityFlags;

/**
 * The LoadInfo object contains information about a network load, why it
 * was started, and how we plan on using the resulting response.
 * If a network request is redirected, the new channel will receive a new
 * LoadInfo object. The new object will contain mostly the same
 * information as the pre-redirect one, but updated as appropriate.
 * For detailed information about what parts of LoadInfo are updated on
 * redirect, see documentation on individual properties.
 */
[scriptable, builtinclass, uuid(ddc65bf9-2f60-41ab-b22a-4f1ae9efcd36)]
interface nsILoadInfo : nsISupports
{
  /**
   * *** DEPRECATED ***
   * No LoadInfo created within Gecko should contain this security flag.
   * Please use any of the five security flags defined underneath.
   * We only keep this security flag to provide backwards compatibilty.
   */
  const unsigned long SEC_NORMAL = 0;

  /**
   * The following five flags determine the security mode and hence what kind of
   * security checks should be performed throughout the lifetime of the channel.
   *
   *    * SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS
   *    * SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED
   *    * SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS
   *    * SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL
   *    * SEC_REQUIRE_CORS_DATA_INHERITS
   *
   * Exactly one of these flags are required to be set in order to allow
   * the channel to perform the correct security checks (SOP, CORS, ...) and
   * return the correct result principal. If none or more than one of these
   * flags are set AsyncOpen2 will fail.
   */

  /*
   * Enforce the same origin policy where data: loads inherit the principal.
   * See the documentation for principalToInherit, which describes exactly what
   * principal is inherited.
   */
  const unsigned long SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS = (1<<0);

  /*
   * Enforce the same origin policy but data: loads are blocked.
   */
  const unsigned long SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED = (1<<1);

  /**
   * Allow loads from other origins. Loads from data: will inherit the
   * principal.  See the documentation for principalToInherit, which describes
   * exactly what principal is inherited.
   *
   * Commonly used by plain <img>, <video>, <link rel=stylesheet> etc.
   */
   const unsigned long SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS = (1<<2);

  /**
   * Allow loads from other origins. Loads from data: will be allowed,
   * but the resulting resource will get a null principal.
   * Used in blink/webkit for <iframe>s. Likely also the mode
   * that should be used by most Chrome code.
   */
  const unsigned long SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL = (1<<3);

  /**
   * Allow loads from any origin, but require CORS for cross-origin loads.
   * Loads from data: are allowed and the result will inherit the principal.
   * See the documentation for principalToInherit, which describes exactly what
   * principal is inherited.
   *
   * Commonly used by <img crossorigin>, <video crossorigin>,
   * XHR, fetch(), etc.
   */
  const unsigned long SEC_REQUIRE_CORS_DATA_INHERITS = (1<<4);

  /**
   * Choose cookie policy. The default policy is equivalent to "INCLUDE" for
   * SEC_REQUIRE_SAME_ORIGIN_* and SEC_ALLOW_CROSS_ORIGIN_* modes, and
   * equivalent to "SAME_ORIGIN" for SEC_REQUIRE_CORS_DATA_INHERITS mode.
   *
   * This means that if you want to perform a CORS load with credentials, pass
   * SEC_COOKIES_INCLUDE.
   *
   * Note that these flags are still subject to the user's cookie policies.
   * For example, if the user is blocking 3rd party cookies, those cookies
   * will be blocked no matter which of these flags are set.
   */
  const unsigned long SEC_COOKIES_DEFAULT = (0 << 5);
  const unsigned long SEC_COOKIES_INCLUDE = (1 << 5);
  const unsigned long SEC_COOKIES_SAME_ORIGIN = (2 << 5);
  const unsigned long SEC_COOKIES_OMIT = (3 << 5);

  /**
   * Force inheriting of the principal.  See the documentation for
   * principalToInherit, which describes exactly what principal is inherited.
   *
   * Setting this flag will cause GetChannelResultPrincipal to return the
   * principal to be inherited as the channel principal.
   *
   * This will happen independently of the scheme of the URI that the
   * channel is loading.
   *
   * So if the principal that gets inherited is "http://a.com/", and the channel
   * is loading the URI "http://b.com/whatever", GetChannelResultPrincipal
   * will return a principal from "http://a.com/".
   *
   * This flag can not be used together with SEC_SANDBOXED.  If both are passed
   * to the LoadInfo constructor then this flag will be dropped.  If you need
   * to know whether this flag would have been present but was dropped due to
   * sandboxing, check for the forceInheritPrincipalDropped flag.
   */
  const unsigned long SEC_FORCE_INHERIT_PRINCIPAL = (1<<7);

  /**
   * Sandbox the load. The resulting resource will use a freshly created
   * null principal. So GetChannelResultPrincipal will always return a
   * null principal whenever this flag is set.
   *
   * This will happen independently of the scheme of the URI that the
   * channel is loading.
   *
   * This flag can not be used together with SEC_FORCE_INHERIT_PRINCIPAL.
   */
  const unsigned long SEC_SANDBOXED = (1<<8);

  /**
   * Inherit the Principal for about:blank.
   */
  const unsigned long SEC_ABOUT_BLANK_INHERITS = (1<<9);

  /**
   * Allow access to chrome: packages that are content accessible.
   */
  const unsigned long SEC_ALLOW_CHROME = (1<<10);

  /**
   * Disallow access to javascript: uris.
   */
  const unsigned long SEC_DISALLOW_SCRIPT = (1<<11);

  /**
   * Don't follow redirects. Instead the redirect response is returned
   * as a successful response for the channel.
   *
   * Redirects not initiated by a server response, i.e. REDIRECT_INTERNAL and
   * REDIRECT_STS_UPGRADE, are still followed.
   *
   * Note: If this flag is set and the channel response is a redirect, then
   * the response body might not be available.
   * This can happen if the redirect was cached.
   */
  const unsigned long SEC_DONT_FOLLOW_REDIRECTS = (1<<12);

  /**
   * Load an error page, it should be one of following : about:neterror,
   * about:certerror, about:blocked, or about:tabcrashed.
   */
  const unsigned long SEC_LOAD_ERROR_PAGE = (1<<13);

  /**
   * Force inheriting of the principal, overruling any owner that might be set
   * on the channel. (Please note that channel.owner is deprecated and will be
   * removed within Bug 1286838).  See the documentation for principalToInherit,
   * which describes exactly what principal is inherited.
   *
   * Setting this flag will cause GetChannelResultPrincipal to return the
   * principal to be inherited as the channel principal.
   *
   * This will happen independently of the scheme of the URI that the
   * channel is loading.
   */
  const unsigned long SEC_FORCE_INHERIT_PRINCIPAL_OVERRULE_OWNER = (1<<14);

  /**
   * This is the principal of the network request's caller/requester where
   * the resulting resource will be used. I.e. it is the principal which
   * will get access to the result of the request. (Where "get access to"
   * might simply mean "embed" depending on the type of resource that is
   * loaded).
   *
   * For example for an image, it is the principal of the document where
   * the image is rendered. For a stylesheet it is the principal of the
   * document where the stylesheet will be applied.
   *
   * So if document at http://a.com/page.html loads an image from
   * http://b.com/pic.jpg, then loadingPrincipal will be
   * http://a.com/page.html.
   *
   * For <iframe> and <frame> loads, the LoadingPrincipal is the
   * principal of the parent document. For top-level loads, the
   * LoadingPrincipal is null. For all loads except top-level loads
   * the LoadingPrincipal is never null.
   *
   * If the loadingPrincipal is the system principal, no security checks
   * will be done at all. There will be no security checks on the initial
   * load or any subsequent redirects. This means there will be no
   * nsIContentPolicy checks or any CheckLoadURI checks. Because of
   * this, never set the loadingPrincipal to the system principal when
   * the URI to be loaded is controlled by a webpage.
   * If the loadingPrincipal and triggeringPrincipal are both
   * codebase-principals, then we will always call into
   * nsIContentPolicies and CheckLoadURI. The call to nsIContentPolicies
   * and CheckLoadURI happen even if the URI to be loaded is same-origin
   * with the loadingPrincipal or triggeringPrincipal.
   */
  readonly attribute nsIPrincipal loadingPrincipal;

  /**
   * A C++-friendly version of loadingPrincipal.
   */
  [noscript, notxpcom, nostdcall, binaryname(LoadingPrincipal)]
  nsIPrincipal binaryLoadingPrincipal();

  /**
   * This is the principal which caused the network load to start. I.e.
   * this is the principal which provided the URL to be loaded. This is
   * often the same as the LoadingPrincipal, but there are a few cases
   * where that's not true.
   *
   * For example for loads into an <iframe>, the LoadingPrincipal is always
   * the principal of the parent document. However the triggeringPrincipal
   * is the principal of the document which provided the URL that the
   * <iframe> is navigating to. This could be the previous document inside
   * the <iframe> which set document.location. Or a document elsewhere in
   * the frame tree which contained a <a target="..."> which targetted the
   * <iframe>.
   *
   * If a stylesheet links to a sub-resource, like an @imported stylesheet,
   * or a background image, then the triggeringPrincipal is the principal
   * of the stylesheet, while the LoadingPrincipal is the principal of the
   * document being styled.
   *
   * The triggeringPrincipal is never null.
   *
   * If the triggeringPrincipal is the system principal, no security checks
   * will be done at all. There will be no security checks on the initial
   * load or any subsequent redirects. This means there will be no
   * nsIContentPolicy checks or any CheckLoadURI checks. Because of
   * this, never set the triggeringPrincipal to the system principal when
   * the URI to be loaded is controlled by a webpage.
   * If the loadingPrincipal and triggeringPrincipal are both
   * codebase-principals, then we will always call into
   * nsIContentPolicies and CheckLoadURI. The call to nsIContentPolicies
   * and CheckLoadURI happen even if the URI to be loaded is same-origin
   * with the loadingPrincipal or triggeringPrincipal.
   */
  readonly attribute nsIPrincipal triggeringPrincipal;

  /**
   * A C++-friendly version of triggeringPrincipal.
   */
  [noscript, notxpcom, nostdcall, binaryname(TriggeringPrincipal)]
  nsIPrincipal binaryTriggeringPrincipal();

  /**
   * For non-document loads the principalToInherit is always null. For
   * loads of type TYPE_DOCUMENT or TYPE_SUBDOCUMENT the principalToInherit
   * might be null. If it's non null, then this is the principal that is
   * inherited if a principal needs to be inherited. If the principalToInherit
   * is null but the inherit flag is set, then the triggeringPrincipal is
   * the principal that is inherited.
   */
  attribute nsIPrincipal principalToInherit;

  /**
   * A C++-friendly version of principalToInherit.
   */
  [noscript, notxpcom, nostdcall, binaryname(PrincipalToInherit)]
  nsIPrincipal binaryPrincipalToInherit();

  /**
   * Finds the correct principal to inherit for the given channel, based on
   * the values of PrincipalToInherit and TriggeringPrincipal.
   */
  [noscript, notxpcom, nostdcall]
  nsIPrincipal FindPrincipalToInherit(in nsIChannel aChannel);

  /**
   * This is the ownerDocument of the LoadingNode. Unless the LoadingNode
   * is a Document, in which case the LoadingDocument is the same as the
   * LoadingNode.
   *
   * For top-level loads, and for loads originating from workers, the
   * LoadingDocument is null. When the LoadingDocument is not null, the
   * LoadingPrincipal is set to the principal of the LoadingDocument.
   */
  readonly attribute nsIDOMDocument loadingDocument;

  /**
   * A C++-friendly version of loadingDocument (loadingNode).
   * This is the Node where the resulting resource will be used. I.e. it is
   * the Node which will get access to the result of the request. (Where
   * "get access to" might simply mean "embed" depending on the type of
   * resource that is loaded).
   *
   * For example for an <img>/<video> it is the image/video element. For
   * document loads inside <iframe> and <frame>s, the LoadingNode is the
   * <iframe>/<frame> element. For an XMLHttpRequest, it is the Document
   * which contained the JS which initiated the XHR. For a stylesheet, it
   * is the Document that contains <link rel=stylesheet>.
   *
   * For loads triggered by the HTML pre-parser, the LoadingNode is the
   * Document which is currently being parsed.
   *
   * For top-level loads, and for loads originating from workers, the
   * LoadingNode is null. If the LoadingNode is non-null, then the
   * LoadingPrincipal is the principal of the LoadingNode.
   */
  [noscript, notxpcom, nostdcall, binaryname(LoadingNode)]
  nsINode binaryLoadingNode();

  /**
   * A C++ friendly version of the loadingContext for toplevel loads.
   * Most likely you want to query the ownerDocument or LoadingNode
   * and not this context only available for TYPE_DOCUMENT loads.
   * Please note that except for loads of TYPE_DOCUMENT, this
   * ContextForTopLevelLoad will always return null.
   */
  [noscript, notxpcom, nostdcall, binaryname(ContextForTopLevelLoad)]
  nsISupports binaryContextForTopLevelLoad();

  /**
   * The securityFlags of that channel.
   */
  readonly attribute nsSecurityFlags securityFlags;

%{ C++
  inline nsSecurityFlags GetSecurityFlags()
  {
    nsSecurityFlags result;
    mozilla::DebugOnly<nsresult> rv = GetSecurityFlags(&result);
    MOZ_ASSERT(NS_SUCCEEDED(rv));
    return result;
  }
%}

  /**
   * Allows to query only the security mode bits from above.
   */
  [infallible] readonly attribute unsigned long securityMode;

  /**
   * True if this request is embedded in a context that can't be third-party
   * (i.e. an iframe embedded in a cross-origin parent window). If this is
   * false, then this request may be third-party if it's a third-party to
   * loadingPrincipal.
   */
  [infallible] readonly attribute boolean isInThirdPartyContext;

  /**
   * See the SEC_COOKIES_* flags above. This attribute will never return
   * SEC_COOKIES_DEFAULT, but will instead return what the policy resolves to.
   * I.e. SEC_COOKIES_SAME_ORIGIN for CORS mode, and SEC_COOKIES_INCLUDE
   * otherwise.
   */
  [infallible] readonly attribute unsigned long cookiePolicy;

  /**
   * If forceInheritPrincipal is true, the data coming from the channel should
   * inherit its principal, even when the data is loaded over http:// or another
   * protocol that would normally use a URI-based principal.
   *
   * See the documentation for principalToInherit, which describes exactly what
   * principal is inherited.
   *
   * This attribute will never be true when loadingSandboxed is true.
   */
  [infallible] readonly attribute boolean forceInheritPrincipal;

  /**
   * If forceInheritPrincipalOverruleOwner is true, the data coming from the
   * channel should inherit the principal, even when the data is loaded over
   * http:// or another protocol that would normally use a URI-based principal
   * and even if the channel's .owner is not null.  This last is the difference
   * between forceInheritPrincipalOverruleOwner and forceInheritPrincipal: the
   * latter does _not_ overrule the .owner setting.
   *
   * See the documentation for principalToInherit, which describes exactly what
   * principal is inherited.
   */
  [infallible] readonly attribute boolean forceInheritPrincipalOverruleOwner;

  /**
   * If loadingSandboxed is true, the data coming from the channel is
   * being loaded sandboxed, so it should have a nonce origin and
   * hence should use a NullPrincipal.
   */
  [infallible] readonly attribute boolean loadingSandboxed;

  /**
   * If aboutBlankInherits is true, then about:blank should inherit
   * the principal.
   */
  [infallible] readonly attribute boolean aboutBlankInherits;

  /**
   * If allowChrome is true, then use nsIScriptSecurityManager::ALLOW_CHROME
   * when calling CheckLoadURIWithPrincipal().
   */
  [infallible] readonly attribute boolean allowChrome;

  /**
   * If disallowScript is true, then use nsIScriptSecurityManager::DISALLOW_SCRIPT
   * when calling CheckLoadURIWithPrincipal().
   */
  [infallible] readonly attribute boolean disallowScript;

  /**
   * Returns true if SEC_DONT_FOLLOW_REDIRECTS is set.
   */
  [infallible] readonly attribute boolean dontFollowRedirects;

  /**
   * Returns true if SEC_LOAD_ERROR_PAGE is set.
   */
  [infallible] readonly attribute boolean loadErrorPage;

  /**
   * The external contentPolicyType of the channel, used for security checks
   * like Mixed Content Blocking and Content Security Policy.
   *
   * Specifically, content policy types with _INTERNAL_ in their name will
   * never get returned from this attribute.
   */
  readonly attribute nsContentPolicyType externalContentPolicyType;

%{ C++
  inline nsContentPolicyType GetExternalContentPolicyType()
  {
    nsContentPolicyType result;
    mozilla::DebugOnly<nsresult> rv = GetExternalContentPolicyType(&result);
    MOZ_ASSERT(NS_SUCCEEDED(rv));
    return result;
  }
%}

  /**
   * The internal contentPolicyType of the channel, used for constructing
   * RequestContext values when creating a fetch event for an intercepted
   * channel.
   *
   * This should not be used for the purposes of security checks, since
   * the content policy implementations cannot be expected to deal with
   * _INTERNAL_ values.  Please use the contentPolicyType attribute above
   * for that purpose.
   */
  [noscript, notxpcom]
  nsContentPolicyType internalContentPolicyType();

  /**
   * Returns true if document or any of the documents ancestors
   * up to the toplevel document make use of the CSP directive
   * 'upgrade-insecure-requests'. Used to identify upgrade
   * requests in e10s where the loadingDocument is not available.
   *
   * Warning: If the loadingDocument is null, then the
   * upgradeInsecureRequests is false.
   */
  [infallible] readonly attribute boolean upgradeInsecureRequests;

  /**
   * If true, the content of the channel is queued up and checked
   * if it matches a content signature. Note, setting this flag
   * to true will negatively impact performance since the preloader
   * can not start until all of the content is fetched from the
   * netwerk.
   *
   * Only use that in combination with TYPE_DOCUMENT.
   */
  [infallible] attribute boolean verifySignedContent;

  /**
   * If true, this load will fail if it has no SRI integrity
   */
  [infallible] attribute boolean enforceSRI;

  /**
   * If true, toplevel data: URI navigation is allowed
   */
  [infallible] attribute boolean forceAllowDataURI;

  /**
   * If true, this is the load of a frame's original src attribute
   */
  [infallible] attribute boolean originalFrameSrcLoad;

  /**
   * The SEC_FORCE_INHERIT_PRINCIPAL flag may be dropped when a load info
   * object is created.  Specifically, it will be dropped if the SEC_SANDBOXED
   * flag is also present.  This flag is set if SEC_FORCE_INHERIT_PRINCIPAL was
   * dropped.
   */
  [infallible] readonly attribute boolean forceInheritPrincipalDropped;

  /**
   * These are the window IDs of the window in which the element being
   * loaded lives. parentOuterWindowID is the window ID of this window's
   * parent. topOuterWindowID is the ID of the top-level window of the same
   * docShell type.
   *
   * Note that these window IDs can be 0 if the window is not
   * available. parentOuterWindowID and topOuterWindowID will be the same as
   * outerWindowID if the window has no parent.
   */
  [infallible] readonly attribute unsigned long long innerWindowID;
  [infallible] readonly attribute unsigned long long outerWindowID;
  [infallible] readonly attribute unsigned long long parentOuterWindowID;
  [infallible] readonly attribute unsigned long long topOuterWindowID;

  /**
   * Only when the element being loaded is <frame src="foo.html">
   * (or, more generally, if the element QIs to nsIFrameLoaderOwner),
   * the frameOuterWindowID is the outer window containing the
   * foo.html document.
   *
   * Note: For other cases, frameOuterWindowID is 0.
   */
  [infallible] readonly attribute unsigned long long frameOuterWindowID;

  /**
   * Resets the PrincipalToInherit to a freshly created NullPrincipal
   * which inherits the origin attributes from the loadInfo.
   *
   * WARNING: Please only use that function if you know exactly what
   * you are doing!!!
   */
  void resetPrincipalToInheritToNullPrincipal();

  /**
   * Customized OriginAttributes within LoadInfo to allow overwriting of the
   * default originAttributes from the loadingPrincipal.
   *
   * In chrome side, originAttributes.privateBrowsingId will always be 0 even if
   * the usePrivateBrowsing is true, because chrome docshell won't set
   * privateBrowsingId on origin attributes (See bug 1278664). This is to make
   * sure nsILoadInfo and nsILoadContext have the same origin attributes.
   */
  [implicit_jscontext, binaryname(ScriptableOriginAttributes)]
  attribute jsval originAttributes;

  [noscript, nostdcall, binaryname(GetOriginAttributes)]
  OriginAttributes binaryGetOriginAttributes();

  [noscript, nostdcall, binaryname(SetOriginAttributes)]
  void binarySetOriginAttributes(in const_OriginAttributesRef aOriginAttrs);

%{ C++
  inline mozilla::OriginAttributes GetOriginAttributes()
  {
    mozilla::OriginAttributes result;
    mozilla::DebugOnly<nsresult> rv = GetOriginAttributes(&result);
    MOZ_ASSERT(NS_SUCCEEDED(rv));
    return result;
  }
%}

  /**
   * Whenever a channel is openend by asyncOpen2() [or also open2()],
   * lets set this flag so that redirects of such channels are also
   * openend using asyncOpen2() [open2()].
   *
   * Please note, once the flag is set to true it must remain true
   * throughout the lifetime of the channel. Trying to set it
   * to anything else than true will be discareded.
   *
   */
  [infallible] attribute boolean enforceSecurity;

  /**
   * Whenever a channel is evaluated by the ContentSecurityManager
   * the first time, we set this flag to true to indicate that
   * subsequent calls of AsyncOpen2() do not have to enforce all
   * security checks again. E.g., after a redirect there is no
   * need to set up CORS again. We need this separate flag
   * because the redirectChain might also contain internal
   * redirects which might pollute the redirectChain so we can't
   * rely on the size of the redirectChain-array to query whether
   * a channel got redirected or not.
   *
   * Please note, once the flag is set to true it must remain true
   * throughout the lifetime of the channel. Trying to set it
   * to anything else than true will be discarded.
   *
   */
  [infallible] attribute boolean initialSecurityCheckDone;

  /**
   * Returns true if the load was triggered from an external application
   * (e.g. Thunderbird). Please note that this flag will only ever be true
   * if the load is of TYPE_DOCUMENT. 
   */
  [infallible] attribute boolean loadTriggeredFromExternal;

  /**
   * True if the tainting has been set by the service worker.
   */
  [noscript, infallible] readonly attribute boolean serviceWorkerTaintingSynthesized;

  /**
   * Whenever a channel gets redirected, append the redirect history entry of
   * the channel which contains principal referrer and remote address [before
   * the channels got redirected] to the loadinfo, so that at every point this
   * array provides us information about all the redirects this channel went
   * through.
   * @param entry, the nsIRedirectHistoryEntry before the channel
   *         got redirected.
   * @param aIsInternalRedirect should be true if the channel is going
   *        through an internal redirect, otherwise false.
   */
  void appendRedirectHistoryEntry(in nsIRedirectHistoryEntry entry,
                                  in boolean isInternalRedirect);

  /**
   * An array of nsIRedirectHistoryEntry which stores redirects associated
   * with this channel. This array is filled whether or not the channel has
   * ever been opened. The last element of the array is associated with the
   * most recent redirect. Please note, that this array *includes* internal
   * redirects.
   */
  [implicit_jscontext]
  readonly attribute jsval redirectChainIncludingInternalRedirects;

  /**
   * A C++-friendly version of redirectChain.
   * Please note that this array has the same lifetime as the
   * loadInfo object - use with caution!
   */
  [noscript, notxpcom, nostdcall, binaryname(RedirectChainIncludingInternalRedirects)]
  nsIRedirectHistoryEntryArray binaryRedirectChainIncludingInternalRedirects();

  /**
   * Same as RedirectChain but does *not* include internal redirects.
   */
  [implicit_jscontext]
  readonly attribute jsval redirectChain;

  /**
   * A C++-friendly version of redirectChain.
   * Please note that this array has the same lifetime as the
   * loadInfo object - use with caution!
   */
  [noscript, notxpcom, nostdcall, binaryname(RedirectChain)]
  nsIRedirectHistoryEntryArray binaryRedirectChain();

  /**
   * An array of nsIPrincipals which stores the principals of the parent frames,
   * not including the frame loading this request.  The closest ancestor is at
   * index zero and the top level ancestor is at the last index.
   *
   * The ancestorPrincipals[0] entry for an iframe load will be the principal of
   * the iframe element's owner document.
   * The ancestorPrincipals[0] entry for an image loaded in an iframe will be the
   * principal of the iframe element's owner document.
   *
   * See nsIDocument::AncestorPrincipals for more information.
   *
   * Please note that this array has the same lifetime as the
   * loadInfo object - use with caution!
   */
  [noscript, notxpcom, nostdcall]
  PrincipalArrayRef AncestorPrincipals();


  /**
   * An array of outerWindowIDs which correspond to nsILoadInfo::AncestorPrincipals
   * above.  AncestorOuterWindowIDs[0] is the outerWindowID of the frame
   * associated with the principal at ancestorPrincipals[0], and so forth.
   *
   * Please note that this array has the same lifetime as the
   * loadInfo object - use with caution!
   */
  [noscript, notxpcom, nostdcall]
  Uint64ArrayRef AncestorOuterWindowIDs();

  /**
   * Sets the list of unsafe headers according to CORS spec, as well as
   * potentially forces a preflight.
   * Note that you do not need to set the Content-Type header. That will be
   * automatically detected as needed.
   *
   * Only call this function when using the SEC_REQUIRE_CORS_DATA_INHERITS mode.
   */
  [noscript, notxpcom, nostdcall]
  void setCorsPreflightInfo(in StringArrayRef unsafeHeaders,
                            in boolean forcePreflight);

  /**
   * A C++-friendly getter for the list of cors-unsafe headers.
   * Please note that this array has the same lifetime as the
   * loadInfo object - use with caution!
   */
  [noscript, notxpcom, nostdcall, binaryname(CorsUnsafeHeaders)]
  StringArrayRef corsUnsafeHeaders();

  /**
   * Returns value set through setCorsPreflightInfo.
   */
  [infallible] readonly attribute boolean forcePreflight;

  /**
   * A C++ friendly getter for the forcePreflight flag.
   */
  [infallible] readonly attribute boolean isPreflight;

  /**
  * Constants reflecting the channel tainting.  These are mainly defined here
  * for script.  Internal C++ code should use the enum defined in LoadTainting.h.
  * See LoadTainting.h for documentation.
  */
  const unsigned long TAINTING_BASIC = 0;
  const unsigned long TAINTING_CORS = 1;
  const unsigned long TAINTING_OPAQUE = 2;

  /**
   * Determine the associated channel's current tainting.  Note, this can
   * change due to a service worker intercept, so it should be checked after
   * OnStartRequest() fires.
   */
  readonly attribute unsigned long tainting;

  /**
   * Note a new tainting level and possibly increase the current tainting
   * to match.  If the tainting level is already greater than the given
   * value, then there is no effect.  It is not possible to reduce the tainting
   * level on an existing channel/loadinfo.
   */
  void maybeIncreaseTainting(in unsigned long aTainting);

  /**
   * Various helper code to provide more convenient C++ access to the tainting
   * attribute and maybeIncreaseTainting().
   */
%{C++
  static_assert(TAINTING_BASIC == static_cast<uint32_t>(mozilla::LoadTainting::Basic),
                "basic tainting enums should match");
  static_assert(TAINTING_CORS == static_cast<uint32_t>(mozilla::LoadTainting::CORS),
                "cors tainting enums should match");
  static_assert(TAINTING_OPAQUE == static_cast<uint32_t>(mozilla::LoadTainting::Opaque),
                "opaque tainting enums should match");

  mozilla::LoadTainting GetTainting()
  {
    uint32_t tainting = TAINTING_BASIC;
    MOZ_ALWAYS_SUCCEEDS(GetTainting(&tainting));
    return static_cast<mozilla::LoadTainting>(tainting);
  }

  void MaybeIncreaseTainting(mozilla::LoadTainting aTainting)
  {
    uint32_t tainting = static_cast<uint32_t>(aTainting);
    MOZ_ALWAYS_SUCCEEDS(MaybeIncreaseTainting(tainting));
  }
%}

  /**
   * Returns true if this load is for top level document.
   * Note that the load for a sub-frame's document will return false here.
   */
  [infallible] readonly attribute boolean isTopLevelLoad;

  /**
   * If this is non-null, this property represents two things: (1) the
   * URI to be used for the principal if the channel with this loadinfo
   * gets a principal based on URI and (2) the URI to use for a document
   * created from the channel with this loadinfo.
   */
  attribute nsIURI resultPrincipalURI;

  /**
   * Returns the null principal of the resulting resource if the SEC_SANDBOXED
   * flag is set.  Otherwise returns null.  This is used by
   * GetChannelResultPrincipal() to ensure that the same null principal object
   * is returned every time.
   */
  [noscript] readonly attribute nsIPrincipal sandboxedLoadingPrincipal;

  /**
   * Note which client (i.e. global) initiated this network request.  All
   * nsGlobalWindow and WorkerPrivate can be converted to a ClientInfo to
   * be set here.  While this is being added to support service worker
   * FetchEvent, it can also be used to communicate other information about
   * the source global context in the future.
   */
  [noscript, nostdcall, notxpcom]
  void SetClientInfo(in const_ClientInfoRef aClientInfo);

  /**
   * Get the ClientInfo for the global that initiated the network request,
   * if it has been set.
   */
  [noscript, nostdcall, notxpcom]
  const_MaybeClientInfoRef GetClientInfo();

  /**
   * Give a pre-allocated ClientSource to the channel LoadInfo.  This is
   * intended to be used by docshell when loading windows without an
   * initial about:blank document.  The docshell will allocate the ClientSource
   * to represent the client that will be created as a result of the navigation
   * network request.  If the channel succeeds and remains same-origin, then
   * the result nsGlobalWindow will take ownership of the reserved ClientSource.
   *
   * This method is also called when a cross-origin redirect occurs.  A new
   * ClientSource with a different UUID must be created in this case.
   *
   * This method automatically calls SetReservedClientInfo() with the
   * ClientSource::Info().
   */
  [noscript, nostdcall, notxpcom]
  void GiveReservedClientSource(in UniqueClientSourceMove aClientSource);

  /**
   * This method takes ownership of the reserved ClientSource previously
   * provided in GiveReservedClientSource().  It may return nullptr if the
   * nsILoadInfo does not own a ClientSource object.
   */
  [noscript, nostdcall, notxpcom]
  UniqueClientSource TakeReservedClientSource();

  /**
   * Note the reserved client that be created if this non-subresource
   * network request succeeds.  Depending on the type of client this
   * may be called directly or indirectly via GiveReservedClientSource().
   * For example, web workers do not call give their ClientSource to
   * the nsILoadInfo, but must still call this method to indicate the
   * reserved client for their main script load.
   */
  [noscript, nostdcall, notxpcom]
  void SetReservedClientInfo(in const_ClientInfoRef aClientInfo);

  /**
   * Return the reserved ClientInfo for this load, if one has been set.
   */
  [noscript, nostdcall, notxpcom]
  const_MaybeClientInfoRef GetReservedClientInfo();

  /**
   * Note that this non-subresource network request will result in
   * re-using an existing "initial" active client.  This mainly only
   * happens when an initial about:blank document is replaced with
   * a real load in a window.  In these cases we need to track this
   * initial client so that we may report its existence in a FetchEvent.
   *
   * Note, an nsILoadInfo may only have a reserved client or an
   * initial client.  It should never have both.
   */
  [noscript, nostdcall, notxpcom]
  void SetInitialClientInfo(in const_ClientInfoRef aClientInfo);

  /**
   * Return the initial ClientInfo for this load, if one has been set.
   */
  [noscript, nostdcall, notxpcom]
  const_MaybeClientInfoRef GetInitialClientInfo();

  /**
   * Note that this network request should be controlled by a service worker.
   * For non-subresource requests this may be set during the load when
   * the first service worker interception occurs.  For subresource requests
   * it may be set by the source client if its already controlled by a
   * service worker.
   */
  [noscript, nostdcall, notxpcom]
  void SetController(in const_ServiceWorkerDescriptorRef aServiceWorker);

  /**
   * Clear the service worker controller for this channel.  This should only
   * be used for window navigation redirects.  By default we want to keep
   * the controller in all other cases.
   */
  [noscript, nostdcall, notxpcom]
  void ClearController();

  /**
   * Get the service worker controlling this network request, if one has
   * been set.
   */
  [noscript, nostdcall, notxpcom]
  const_MaybeServiceWorkerDescriptorRef GetController();
};
