/* 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 protocol PHttpChannel;
include ClientIPCTypes;
include URIParams;
include IPCServiceWorkerDescriptor;
include IPCStream;
include PBackgroundSharedTypes;
include DOMTypes;
include ProtocolTypes;

include "mozilla/dom/DomSecurityIPCUtils.h";
include "mozilla/dom/FetchIPCTypes.h";
include "mozilla/dom/FeaturePolicyUtils.h";
include "mozilla/dom/NavigationAPIIPCUtils.h";
include "mozilla/dom/PropertyBagUtils.h";
include "mozilla/dom/ReferrerInfoUtils.h";
include "mozilla/ipc/URIUtils.h";
include "mozilla/dom/ConsoleReportIPCUtils.h";
include "mozilla/net/CacheInfoIPCTypes.h";
include "mozilla/AntiTrackingIPCUtils.h";
include "mozilla/net/ClassOfService.h";

using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
using mozilla::net::RequestHeaderTuples from "mozilla/net/PHttpChannelParams.h";
using struct nsHttpAtom from "nsHttp.h";
[MoveOnly] using class mozilla::net::nsHttpResponseHead from "nsHttpResponseHead.h";
using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
[RefCounted] using class nsIPropertyBag2 from "nsIPropertyBag2.h";
[RefCounted] using class nsDOMNavigationTiming from "nsDOMNavigationTiming.h";
[RefCounted] using class nsDocShellLoadState from "nsDocShellLoadState.h";
using nsContentPolicyType from "nsIContentPolicy.h";
using mozilla::net::PreferredAlternativeDataDeliveryTypeIPC from "nsICacheInfoChannel.h";
using mozilla::dom::ForceMediaDocument from "mozilla/dom/LoadURIOptionsBinding.h";
using nsILoadInfo::CrossOriginEmbedderPolicy from "nsILoadInfo.h";
using nsILoadInfo::StoragePermissionState from "nsILoadInfo.h";
using nsILoadInfo::IPAddressSpace from "nsILoadInfo.h";
using struct mozilla::dom::LoadingSessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h";
using mozilla::dom::RequestMode from "mozilla/dom/RequestBinding.h";
using mozilla::net::LinkHeader from "nsNetUtil.h";
using mozilla::dom::FeaturePolicyInfo from "mozilla/dom/FeaturePolicy.h";
using nsILoadInfo::HTTPSUpgradeTelemetryType from "nsILoadInfo.h";
using nsILoadInfo::SchemelessInputType from "nsILoadInfo.h";
using mozilla::dom::UserNavigationInvolvement from "mozilla/dom/UserNavigationInvolvement.h";
using mozilla::RFPTargetSet from "nsRFPService.h";
using PropertiesFile from "nsContentUtils.h";
[RefCounted] using mozilla::dom::ParentProcessChannelHandle from "mozilla/dom/ParentProcessChannelHandle.h";

namespace mozilla {
namespace net {

//-----------------------------------------------------------------------------
// CookieJarSettings IPDL structs
//-----------------------------------------------------------------------------

struct CookiePermissionData
{
  PrincipalInfo principalInfo;
  uint32_t cookiePermission;
};

struct CookieJarSettingsArgs
{
  // Copy of the cookie jar settings for the top-level document.
  uint32_t cookieBehavior;
  bool isFirstPartyIsolated;
  bool shouldResistFingerprinting;
  bool isOnContentBlockingAllowList;
  CookiePermissionData[] cookiePermissions;
  bool isFixed;
  nsString partitionKey;
  bool hasFingerprintingRandomizationKey;
  uint8_t[] fingerprintingRandomizationKey;
  uint64_t topLevelWindowContextId;
};

//-----------------------------------------------------------------------------
// CookieChange
//-----------------------------------------------------------------------------

struct CookieChange
{
  bool added;
  CookieStruct cookie;
  OriginAttributes originAttributes;
};

//-----------------------------------------------------------------------------
// Preferrer alternative data type
//-----------------------------------------------------------------------------

struct PreferredAlternativeDataTypeParams
{
  nsCString type;
  nsCString contentType;
  PreferredAlternativeDataDeliveryTypeIPC deliverAltData;
};

//-----------------------------------------------------------------------------
// LoadInfo IPDL structs
//-----------------------------------------------------------------------------

struct RedirectHistoryEntryInfo
{
  PrincipalInfo       principalInfo;
  URIParams?          referrerUri;
  nsCString           remoteAddress;
};

struct InterceptionInfoArg
{
  PrincipalInfo?              triggeringPrincipalInfo;
  nsContentPolicyType         contentPolicyType;
  RedirectHistoryEntryInfo[]  redirectChain;
  bool                        fromThirdParty;
};

struct LoadInfoArgs
{
  PrincipalInfo?              requestingPrincipalInfo;
  PrincipalInfo               triggeringPrincipalInfo;
  PrincipalInfo?              principalToInheritInfo;
  PrincipalInfo?              topLevelPrincipalInfo;
  URIParams?                  resultPrincipalURI;
  nsCString                   triggeringRemoteType;
  nsID                        sandboxedNullPrincipalID;
  uint32_t                    securityFlags;
  uint32_t                    sandboxFlags;
  uint32_t                    triggeringSandboxFlags;
  uint64_t                    triggeringWindowId;
  bool                        triggeringStorageAccess;
  uint32_t                    triggeringFirstPartyClassificationFlags;
  uint32_t                    triggeringThirdPartyClassificationFlags;
  nsContentPolicyType         contentPolicyType;
  uint32_t                    tainting;
  bool                        blockAllMixedContent;
  bool                        upgradeInsecureRequests;
  bool                        browserUpgradeInsecureRequests;
  bool                        browserDidUpgradeInsecureRequests;
  bool                        browserWouldUpgradeInsecureRequests;
  bool                        forceAllowDataURI;
  bool                        allowInsecureRedirectToDataURI;
  ForceMediaDocument          forceMediaDocument;
  bool                        skipContentPolicyCheckForWebRequest;
  bool                        originalFrameSrcLoad;
  bool                        forceInheritPrincipalDropped;
  uint64_t                    innerWindowID;
  uint64_t                    browsingContextID;
  uint64_t                    associatedBrowsingContextID;
  uint64_t                    frameBrowsingContextID;
  bool                        initialSecurityCheckDone;
  bool                        isInThirdPartyContext;
  bool?                       isThirdPartyContextToTopWindow;
  bool                        isOn3PCBExceptionList;
  bool                        isFormSubmission;
  bool                        isGETRequest;
  bool                        sendCSPViolationEvents;
  OriginAttributes            originAttributes;
  RedirectHistoryEntryInfo[]  redirectChainIncludingInternalRedirects;
  RedirectHistoryEntryInfo[]  redirectChain;
  SchemelessInputType         schemelessInput;
  HTTPSUpgradeTelemetryType   httpsUpgradeTelemetry;

  /**
   * ClientInfo structure representing the window or worker that triggered
   * this network request.  May be Nothing if its a system internal request.
   */
  IPCClientInfo?              clientInfo;

  /**
   * Non-subresource requests will result in the creation of a window or
   * worker client.  The reserved and initial ClientInfo values represent
   * this resulting client.  An initial ClientInfo represents an initial
   * about:blank window that will be re-used while a reserved ClientInfo
   * represents a to-be-newly-created window/worker.
   */
  IPCClientInfo?              reservedClientInfo;
  IPCClientInfo?              initialClientInfo;

  /**
   * Subresource loads may have a controller set based on their owning
   * window/worker client.  We must send this across IPC to support
   * performing interception in the parent.
   */
  IPCServiceWorkerDescriptor? controller;

  nsCString[]                 corsUnsafeHeaders;
  bool                        forcePreflight;
  bool                        isPreflight;
  bool                        loadTriggeredFromExternal;
  bool                        serviceWorkerTaintingSynthesized;
  bool                        documentHasUserInteracted;
  bool allowListFutureDocumentsCreatedFromThisRedirectChain;
  bool needForCheckingAntiTrackingHeuristic;
  nsString                    cspNonce;
  nsString                    integrityMetadata;
  bool                        skipContentSniffing;
  uint32_t                    httpsOnlyStatus;
  bool                        hstsStatus;
  bool                        hasValidUserGestureActivation;
  bool                        textDirectiveUserActivation;
  bool                        allowDeprecatedSystemRequests;
  bool                        isInDevToolsContext;
  bool                        parserCreatedScript;
  RequestMode?                requestMode;
  bool                        isFromProcessingFrameAttributes;
  bool                        isMediaRequest;
  bool                        isFromObjectOrEmbed;
  CookieJarSettingsArgs       cookieJarSettings;
  uint32_t                    requestBlockingReason;
  PolicyContainerArgs?        policyContainerToInherit;
  StoragePermissionState      storagePermission;
  IPAddressSpace              parentIPAddressSpace;
  IPAddressSpace              ipAddressSpace;
  RFPTargetSet?               overriddenFingerprintingSettings;
  bool                        isMetaRefresh;
  CrossOriginEmbedderPolicy   loadingEmbedderPolicy;
  bool                        originTrialCoepCredentiallessEnabledForTopLevel;
  nullable nsIURI             unstrippedURI;
  InterceptionInfoArg?        interceptionInfo;
  bool                        isNewWindowTarget;
  UserNavigationInvolvement   userNavigationInvolvement;
  FeaturePolicyInfo?          containerFeaturePolicyInfo;
  // https://html.spec.whatwg.org/#dom-location-ancestororigins
  PrincipalInfo?[]             ancestorOrigins;
};

/**
 * This structure is used to carry selected properties of a LoadInfo
 * object to child processes to merge LoadInfo changes from the parent
 * process.  We don't want to use LoadInfoArgs for that since it's
 * too huge and we only care about small subpart of properties anyway.
 */
struct ParentLoadInfoForwarderArgs
{
  // WebExtextensions' WebRequest API allows extensions to intercept and
  // redirect a channel to a data URI. This modifications happens in
  // the parent and needs to be mirrored to the child so that security
  // checks can pass.
  bool allowInsecureRedirectToDataURI;

  // The ServiceWorker controller that may be set in the parent when
  // interception occurs.
  IPCServiceWorkerDescriptor? controller;

  // The service worker may synthesize a Response with a particular
  // tainting value.
  uint32_t tainting;

  // This flag is used for any browsing context where we should not sniff
  // the content type. E.g if an iframe has the XCTO nosniff header, then
  // that flag is set to true so we skip content sniffing for that browsing
  bool skipContentSniffing;

  uint32_t httpsOnlyStatus;

  SchemelessInputType schemelessInput;

  HTTPSUpgradeTelemetryType httpsUpgradeTelemetry;

  bool hstsStatus;

  // Returns true if at the time of the loadinfo construction the document
  // that triggered this load has the bit hasValidTransientUserGestureActivation
  // set or the load was triggered from External. (Mostly this bool is used
  // in the context of Sec-Fetch-User.)
  bool hasValidUserGestureActivation;

  // Returns true if at the time of the loadinfo construction the document
  // that triggered this load has an user activation, so that if the new
  // document has a text fragment, its first text directive can be scrolled to.
  bool textDirectiveUserActivation;

  // The SystemPrincipal is disallowed to make requests to the public web
  // and all requests will be cancelled. Setting this flag to true prevents
  // the request from being cancelled.
  bool allowDeprecatedSystemRequests;

  bool isInDevToolsContext;

  // Only ever returns true if the loadinfo is of TYPE_SCRIPT and
  // the script was created by the HTML parser.
  bool parserCreatedScript;

  RequestMode? requestMode;

  // Sandbox Flags of the Document that triggered the load
  uint32_t triggeringSandboxFlags;

  // Window ID and UsingStorageAccess of the Document that triggered the load.
  // Used by the Storage Access API to determine if SubDocument loads should
  // be partitioned or not.
  uint64_t triggeringWindowId;
  bool triggeringStorageAccess;

  // We must also note that the tainting value was explicitly set
  // by the service worker.
  bool serviceWorkerTaintingSynthesized;

  bool documentHasUserInteracted;
  bool allowListFutureDocumentsCreatedFromThisRedirectChain;

  CookieJarSettingsArgs? cookieJarSettings;

  FeaturePolicyInfo? containerFeaturePolicyInfo;

  uint32_t requestBlockingReason;

  StoragePermissionState storagePermission;

  RFPTargetSet? overriddenFingerprintingSettings;

  bool isMetaRefresh;

  bool? isThirdPartyContextToTopWindow;

  bool isInThirdPartyContext;

  bool isOn3PCBExceptionList;

  nullable nsIURI unstrippedURI;

  UserNavigationInvolvement userNavigationInvolvement;

  // IMPORTANT: when you add new properites here you must also update
  // LoadInfoToParentLoadInfoForwarder and MergeParentLoadInfoForwarder
  // in BackgroundUtils.cpp/.h!
};

/**
 * This structure is used to carry selected properties of a LoadInfo
 * object to the parent process that might have changed in the child
 * during a redirect.  We don't want to use LoadInfoArgs for that since
 * it's too huge and we only care about small subpart of properties
 * anyway.
 */
struct ChildLoadInfoForwarderArgs
{
  // The reserved and initial ClientInfo values may change during a
  // redirect if the new channel is cross-origin to the old channel.
  IPCClientInfo? reservedClientInfo;
  IPCClientInfo? initialClientInfo;

  // The ServiceWorker controller may be cleared in the child during
  // a redirect.
  IPCServiceWorkerDescriptor? controller;

  uint32_t requestBlockingReason;
};

//-----------------------------------------------------------------------------
// HTTP IPDL structs
//-----------------------------------------------------------------------------

struct CorsPreflightArgs
{
  nsCString[]   unsafeHeaders;
};

struct HttpChannelOpenArgs
{
  nullable nsIURI             uri;
  // - TODO: bug 571161: unclear if any HTTP channel clients ever
  // set originalURI != uri (about:credits?); also not clear if
  // chrome channel would ever need to know.  Get rid of next arg?
  nullable nsIURI             original;
  nullable nsIURI             doc;
  nullable nsIReferrerInfo    referrerInfo;
  nullable nsIURI             apiRedirectTo;
  nullable nsIURI             topWindowURI;
  RequestHeaderTuples         requestHeaders;
  PreferredAlternativeDataTypeParams[] preferredAlternativeTypes;
  TimeStamp                   launchServiceWorkerStart;
  TimeStamp                   launchServiceWorkerEnd;
  TimeStamp                   dispatchFetchEventStart;
  TimeStamp                   dispatchFetchEventEnd;
  TimeStamp                   handleFetchEventStart;
  TimeStamp                   handleFetchEventEnd;
  TimeStamp                   navigationStartTimeStamp;
  uint64_t                    startPos;
  uint64_t                    requestContextID;
  uint64_t                    channelId;
  uint64_t                    contentWindowId;
  uint64_t                    browserId;
  uint64_t                    earlyHintPreloaderId;
  nsCString                   requestMethod;
  ClassOfService              classOfService;
  nsCString                   entityID;
  nsCString                   appCacheClientID;
  CorsPreflightArgs?          preflightArgs;
  nsCString                   contentTypeHint;
  IPCStream?                  uploadStream;
  LoadInfoArgs                loadInfo;
  uint32_t                    loadFlags;
  uint32_t                    thirdPartyFlags;
  uint32_t                    tlsFlags;
  uint32_t                    cacheKey;
  uint32_t                    initialRwin;
  uint32_t                    redirectMode;
  int16_t                     priority;
  bool                        allowSTS;
  bool                        resumeAt;
  bool                        allowSpdy;
  bool                        allowHttp3;
  bool                        allowAltSvc;
  bool                        beConservative;
  bool                        bypassProxy;
  bool                        blockAuthPrompt;
  bool                        allowStaleCacheContent;
  RequestMode                 requestMode;
  bool                        forceValidateCacheContent;
  bool                        preferCacheLoadOverBypass;
  bool                        forceMainDocumentChannel;
  uint8_t                     redirectionLimit;
  nsString                    classicScriptHintCharset;
  nsString                    documentCharacterSet;
  bool                        isUserAgentHeaderModified;
  nsString                    initiatorType;
};

struct HttpChannelConnectArgs
{
  uint32_t registrarId;
};

union HttpChannelCreationArgs
{
  HttpChannelOpenArgs;      // For AsyncOpen: the common case.
  HttpChannelConnectArgs;   // Used for redirected-to channels
};

struct ProxyInfoCloneArgs
{
  nsCString type;
  nsCString host;
  int32_t port;
  nsCString masqueTemplate;
  nsCString alpn;
  nsCString username;
  nsCString password;
  uint32_t flags;
  uint32_t timeout;
  uint32_t resolveFlags;
  nsCString proxyAuthorizationHeader;
  nsCString connectionIsolationKey;
};

struct HttpConnectionInfoCloneArgs
{
  nsCString host;
  int32_t port;
  nsCString npnToken;
  nsCString username;
  OriginAttributes originAttributes;
  bool endToEndSSL;
  nsCString routedHost;
  int32_t routedPort;
  bool anonymous;
  bool aPrivate; // use prefix to avoid code generation error
  bool insecureScheme;
  bool noSpdy;
  bool beConservative;
  bool bypassProxy;
  bool anonymousAllowClientCert;
  bool fallbackConnection;
  uint32_t tlsFlags;
  bool isolated;
  bool isTrrServiceChannel;
  uint8_t trrMode;
  bool isIPv4Disabled;
  bool isIPv6Disabled;
  bool isHttp3Disabled;
  nsCString topWindowOrigin;
  bool isHttp3;
  bool webTransport;
  uint64_t webTransportId;
  bool hasIPHintAddress;
  bool http3Only;
  nsCString echConfig;
  bool happyEyeballsEnabled;
  ProxyInfoCloneArgs[] proxyInfo;
};

struct ConsoleReportCollected {
  uint32_t errorFlags;
  nsCString category;
  PropertiesFile propertiesFile;
  nsCString sourceFileURI;
  uint32_t lineNumber;
  uint32_t columnNumber;
  nsCString messageName;
  nsString[] stringParams;
};

struct CookieStruct
{
  nsCString name;
  nsCString value;
  nsCString host;
  nsCString path;
  int64_t   expiryInMSec;
  int64_t   lastAccessedInUSec;
  int64_t   creationTimeInUSec;
  int64_t   updateTimeInUSec;
  bool      isHttpOnly;
  bool      isSession;
  bool      isSecure;
  bool      isPartitioned;
  int32_t   sameSite;
  uint8_t   schemeMap;
};

struct CookieStructTable
{
  OriginAttributes attrs;
  CookieStruct[] cookies;
};

struct DocumentCreationArgs {
  uint32_t loadFlags;
  bool uriModified;
  bool isEmbeddingBlockedError;
};

struct ObjectCreationArgs {
  uint32_t loadFlags;
  uint64_t embedderInnerWindowId;
  nsContentPolicyType contentPolicyType;
  bool isUrgentStart;
};

union DocumentChannelElementCreationArgs {
  DocumentCreationArgs;
  ObjectCreationArgs;
};

struct DocumentChannelCreationArgs {
  nsDocShellLoadState loadState;
  TimeStamp asyncOpenTime;
  uint64_t channelId;
  uint32_t cacheKey;
  nullable nsDOMNavigationTiming timing;
  IPCClientInfo? initialClientInfo;
  DocumentChannelElementCreationArgs elementCreationArgs;
  uint64_t parentInitiatedNavigationEpoch;
};

struct EarlyHintConnectArgs {
  LinkHeader link;
  uint64_t earlyHintPreloaderId;
};

struct RedirectToRealChannelArgs {
  uint32_t registrarId;
  nullable nsIURI uri;
  uint32_t newLoadFlags;
  ReplacementChannelConfigInit? init;
  LoadInfoArgs loadInfo;
  uint64_t channelId;
  nullable nsIURI originalURI;
  uint32_t redirectMode;
  uint32_t redirectFlags;
  uint32_t? contentDisposition;
  nsString? contentDispositionFilename;
  nullable nsIPropertyBag2 properties;
  uint32_t loadStateExternalLoadFlags;
  uint32_t loadStateInternalLoadFlags;
  uint32_t loadStateLoadType;
  nullable nsDOMNavigationTiming timing;
  nsString srcdocData;
  nullable nsIURI baseUri;
  LoadingSessionHistoryInfo? loadingSessionHistoryInfo;
  uint64_t loadIdentifier;
  nsCString? originalUriString;
  EarlyHintConnectArgs[] earlyHints;
  uint32_t earlyHintLinkType;
  nullable nsIReferrerInfo referrerInfo;
  nullable ParentProcessChannelHandle channelHandle;
};

struct TimingStructArgs {
  TimeStamp domainLookupStart;
  TimeStamp domainLookupEnd;
  TimeStamp connectStart;
  TimeStamp tcpConnectEnd;
  TimeStamp secureConnectionStart;
  TimeStamp connectEnd;
  TimeStamp requestStart;
  TimeStamp responseStart;
  TimeStamp firstInterimResponseStart;
  TimeStamp finalResponseHeadersStart;
  TimeStamp responseEnd;
  TimeStamp transactionPending;
};

struct ResourceTimingStructArgs {
  TimeStamp domainLookupStart;
  TimeStamp domainLookupEnd;
  TimeStamp connectStart;
  TimeStamp tcpConnectEnd;
  TimeStamp secureConnectionStart;
  TimeStamp connectEnd;
  TimeStamp requestStart;
  TimeStamp responseStart;
  TimeStamp firstInterimResponseStart;
  TimeStamp finalResponseHeadersStart;
  TimeStamp responseEnd;
  TimeStamp fetchStart;
  TimeStamp redirectStart;
  TimeStamp redirectEnd;
  uint64_t transferSize;
  uint64_t encodedBodySize;
  uint64_t decodedBodySize;

  // Not actually part of resource timing, but not part of the transaction
  // timings either. These need to be passed to HttpChannelChild along with
  // the rest of the timings so the timing information in the child is complete.
  TimeStamp cacheReadStart;
  TimeStamp cacheReadEnd;

  TimeStamp transactionPending;
};

struct HttpActivity
{
  nsCString host;
  int32_t port;
  bool endToEndSSL;
};

struct HttpConnectionActivity
{
  nsCString connInfoKey;
  nsCString host;
  int32_t port;
  bool ssl;
  bool hasECH;
  bool isHttp3;
};

union HttpActivityArgs
{
  uint64_t;
  HttpActivity;
  HttpConnectionActivity;
};

struct TransactionObserverResult
{
  bool versionOk;
  bool authOk;
  nsresult closeReason;
};

struct SpeculativeConnectionOverriderArgs {
  uint32_t parallelSpeculativeConnectLimit;
  bool ignoreIdle;
  bool allow1918;
};

//-----------------------------------------------------------------------------
// GIO IPDL structs
//-----------------------------------------------------------------------------

struct GIOChannelOpenArgs
{
  URIParams                 uri;
  uint64_t                  startPos;
  nsCString                 entityID;
  IPCStream?                uploadStream;
  LoadInfoArgs              loadInfo;
  uint32_t                  loadFlags;
};

struct GIOChannelConnectArgs
{
  uint32_t channelId;
};

union GIOChannelCreationArgs
{
  GIOChannelOpenArgs;      // For AsyncOpen: the common case.
  GIOChannelConnectArgs;   // Used for redirected-to channels
};

//-----------------------------------------------------------------------------
// File IPDL structs
//-----------------------------------------------------------------------------

struct FileChannelInfo
{
  nullable nsIURI        uri;
  nullable nsIURI        originalURI;
  uint32_t               loadFlags;
  LoadInfoArgs           loadInfo;
  nsCString              contentType;
  uint64_t               channelId;
};

//-----------------------------------------------------------------------------
// GeckoView's Android Content IPDL structs
//-----------------------------------------------------------------------------

struct GeckoViewContentChannelOpenArgs
{
  URIParams uri;
  LoadInfoArgs loadInfo;
  uint32_t loadFlags;
};

struct GeckoViewContentChannelConnectArgs
{
  uint32_t channelId;
};

union GeckoViewContentChannelArgs
{
  GeckoViewContentChannelOpenArgs;
  GeckoViewContentChannelConnectArgs;
};

struct RemoteStreamInfo {
  nullable nsIInputStream inputStream;
  nsCString contentType;
  int64_t contentLength;
};
} // namespace net
} // namespace mozilla
