tor-browser

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

nsDocShellLoadState.cpp (57103B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      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 #include "nsDocShellLoadState.h"
      8 #include "nsIDocShell.h"
      9 #include "nsDocShell.h"
     10 #include "nsILoadInfo.h"
     11 #include "nsIProtocolHandler.h"
     12 #include "nsISHEntry.h"
     13 #include "nsIURIFixup.h"
     14 #include "nsIWebNavigation.h"
     15 #include "nsIChannel.h"
     16 #include "nsIURLQueryStringStripper.h"
     17 #include "nsIXULRuntime.h"
     18 #include "nsNetUtil.h"
     19 #include "nsQueryObject.h"
     20 #include "ReferrerInfo.h"
     21 #include "mozilla/BasePrincipal.h"
     22 #include "mozilla/ClearOnShutdown.h"
     23 #include "mozilla/Components.h"
     24 #include "mozilla/dom/BrowsingContext.h"
     25 #include "mozilla/dom/ContentChild.h"
     26 #include "mozilla/dom/ContentParent.h"
     27 #include "mozilla/dom/FormData.h"
     28 #include "mozilla/dom/LoadURIOptionsBinding.h"
     29 #include "mozilla/dom/Navigation.h"
     30 #include "mozilla/dom/NavigationUtils.h"
     31 #include "mozilla/dom/nsHTTPSOnlyUtils.h"
     32 #include "mozilla/StaticPrefs_browser.h"
     33 #include "mozilla/StaticPrefs_fission.h"
     34 #include "mozilla/glean/AntitrackingMetrics.h"
     35 
     36 #include "mozilla/OriginAttributes.h"
     37 #include "mozilla/NullPrincipal.h"
     38 #include "mozilla/StaticPtr.h"
     39 
     40 #include "mozilla/dom/PContent.h"
     41 
     42 using namespace mozilla;
     43 using namespace mozilla::dom;
     44 
     45 // Global reference to the URI fixup service.
     46 static mozilla::StaticRefPtr<nsIURIFixup> sURIFixup;
     47 
     48 nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI)
     49    : nsDocShellLoadState(aURI, nsContentUtils::GenerateLoadIdentifier()) {}
     50 
     51 nsDocShellLoadState::nsDocShellLoadState(
     52    const DocShellLoadStateInit& aLoadState, mozilla::ipc::IProtocol* aActor,
     53    bool* aReadSuccess)
     54    : mNotifiedBeforeUnloadListeners(false),
     55      mLoadIdentifier(aLoadState.LoadIdentifier()) {
     56  // If we return early, we failed to read in the data.
     57  *aReadSuccess = false;
     58  if (!aLoadState.URI()) {
     59    MOZ_ASSERT_UNREACHABLE("Cannot create a LoadState with a null URI!");
     60    return;
     61  }
     62 
     63  mResultPrincipalURI = aLoadState.ResultPrincipalURI();
     64  mResultPrincipalURIIsSome = aLoadState.ResultPrincipalURIIsSome();
     65  mKeepResultPrincipalURIIfSet = aLoadState.KeepResultPrincipalURIIfSet();
     66  mLoadReplace = aLoadState.LoadReplace();
     67  mInheritPrincipal = aLoadState.InheritPrincipal();
     68  mPrincipalIsExplicit = aLoadState.PrincipalIsExplicit();
     69  mNotifiedBeforeUnloadListeners = aLoadState.NotifiedBeforeUnloadListeners();
     70  mForceAllowDataURI = aLoadState.ForceAllowDataURI();
     71  mIsExemptFromHTTPSFirstMode = aLoadState.IsExemptFromHTTPSFirstMode();
     72  mOriginalFrameSrc = aLoadState.OriginalFrameSrc();
     73  mShouldCheckForRecursion = aLoadState.ShouldCheckForRecursion();
     74  mIsFormSubmission = aLoadState.IsFormSubmission();
     75  mNeedsCompletelyLoadedDocument = aLoadState.NeedsCompletelyLoadedDocument();
     76  mHistoryBehavior = aLoadState.HistoryBehavior();
     77  mLoadType = aLoadState.LoadType();
     78  mTarget = aLoadState.Target();
     79  mTargetBrowsingContext = aLoadState.TargetBrowsingContext();
     80  mLoadFlags = aLoadState.LoadFlags();
     81  mInternalLoadFlags = aLoadState.InternalLoadFlags();
     82  mFirstParty = aLoadState.FirstParty();
     83  mHasValidUserGestureActivation = aLoadState.HasValidUserGestureActivation();
     84  mTextDirectiveUserActivation = aLoadState.TextDirectiveUserActivation();
     85  mAllowFocusMove = aLoadState.AllowFocusMove();
     86  mTypeHint = aLoadState.TypeHint();
     87  mFileName = aLoadState.FileName();
     88  mIsFromProcessingFrameAttributes =
     89      aLoadState.IsFromProcessingFrameAttributes();
     90  mReferrerInfo = aLoadState.ReferrerInfo();
     91  mURI = aLoadState.URI();
     92  mOriginalURI = aLoadState.OriginalURI();
     93  mSourceBrowsingContext = aLoadState.SourceBrowsingContext();
     94  mBaseURI = aLoadState.BaseURI();
     95  mTriggeringPrincipal = aLoadState.TriggeringPrincipal();
     96  mPrincipalToInherit = aLoadState.PrincipalToInherit();
     97  mPartitionedPrincipalToInherit = aLoadState.PartitionedPrincipalToInherit();
     98  mTriggeringSandboxFlags = aLoadState.TriggeringSandboxFlags();
     99  mTriggeringWindowId = aLoadState.TriggeringWindowId();
    100  mTriggeringStorageAccess = aLoadState.TriggeringStorageAccess();
    101  mTriggeringClassificationFlags = aLoadState.TriggeringClassificationFlags();
    102  mTriggeringRemoteType = aLoadState.TriggeringRemoteType();
    103  mSchemelessInput = aLoadState.SchemelessInput();
    104  mForceMediaDocument = aLoadState.forceMediaDocument();
    105  mHttpsUpgradeTelemetry = aLoadState.HttpsUpgradeTelemetry();
    106  mPolicyContainer = aLoadState.PolicyContainer();
    107  mOriginalURIString = aLoadState.OriginalURIString();
    108  mCancelContentJSEpoch = aLoadState.CancelContentJSEpoch();
    109  mPostDataStream = aLoadState.PostDataStream();
    110  mHeadersStream = aLoadState.HeadersStream();
    111  mSrcdocData = aLoadState.SrcdocData();
    112  mChannelInitialized = aLoadState.ChannelInitialized();
    113  mIsMetaRefresh = aLoadState.IsMetaRefresh();
    114  if (aLoadState.loadingSessionHistoryInfo().isSome()) {
    115    mLoadingSessionHistoryInfo = MakeUnique<LoadingSessionHistoryInfo>(
    116        aLoadState.loadingSessionHistoryInfo().ref());
    117  }
    118  mUnstrippedURI = aLoadState.UnstrippedURI();
    119  mRemoteTypeOverride = aLoadState.RemoteTypeOverride();
    120  mIsCaptivePortalTab = aLoadState.IsCaptivePortalTab();
    121  mIsInitialAboutBlankHandlingProhibited =
    122      aLoadState.IsInitialAboutBlankHandlingProhibited();
    123 
    124  if (aLoadState.NavigationAPIState()) {
    125    mNavigationAPIState = MakeRefPtr<nsStructuredCloneContainer>();
    126    mNavigationAPIState->CopyFromClonedMessageData(
    127        *aLoadState.NavigationAPIState());
    128  }
    129  // We know this was created remotely, as we just received it over IPC.
    130  mWasCreatedRemotely = true;
    131 
    132  // If we're in the parent process, potentially validate against a LoadState
    133  // which we sent to the source content process.
    134  if (XRE_IsParentProcess()) {
    135    mozilla::ipc::IToplevelProtocol* top = aActor->ToplevelProtocol();
    136    if (!top ||
    137        top->GetProtocolId() != mozilla::ipc::ProtocolId::PContentMsgStart ||
    138        top->GetSide() != mozilla::ipc::ParentSide) {
    139      aActor->FatalError("nsDocShellLoadState must be received over PContent");
    140      return;
    141    }
    142    ContentParent* cp = static_cast<ContentParent*>(top);
    143 
    144    // If this load was sent down to the content process as a navigation
    145    // request, ensure it still matches the one we sent down.
    146    if (RefPtr<nsDocShellLoadState> originalState =
    147            cp->TakePendingLoadStateForId(mLoadIdentifier)) {
    148      if (const char* mismatch = ValidateWithOriginalState(originalState)) {
    149        aActor->FatalError(
    150            nsPrintfCString(
    151                "nsDocShellLoadState %s changed while in content process",
    152                mismatch)
    153                .get());
    154        return;
    155      }
    156    } else if (mTriggeringRemoteType != cp->GetRemoteType()) {
    157      // If we don't have a previous load to compare to, the content process
    158      // must be the triggering process.
    159      aActor->FatalError(
    160          "nsDocShellLoadState with invalid triggering remote type");
    161      return;
    162    }
    163  }
    164 
    165  // We successfully read in the data - return a success value.
    166  *aReadSuccess = true;
    167 }
    168 
    169 nsDocShellLoadState::nsDocShellLoadState(const nsDocShellLoadState& aOther)
    170    : mReferrerInfo(aOther.mReferrerInfo),
    171      mURI(aOther.mURI),
    172      mOriginalURI(aOther.mOriginalURI),
    173      mResultPrincipalURI(aOther.mResultPrincipalURI),
    174      mResultPrincipalURIIsSome(aOther.mResultPrincipalURIIsSome),
    175      mTriggeringPrincipal(aOther.mTriggeringPrincipal),
    176      mTriggeringSandboxFlags(aOther.mTriggeringSandboxFlags),
    177      mTriggeringWindowId(aOther.mTriggeringWindowId),
    178      mTriggeringStorageAccess(aOther.mTriggeringStorageAccess),
    179      mTriggeringClassificationFlags(aOther.mTriggeringClassificationFlags),
    180      mPolicyContainer(aOther.mPolicyContainer),
    181      mKeepResultPrincipalURIIfSet(aOther.mKeepResultPrincipalURIIfSet),
    182      mLoadReplace(aOther.mLoadReplace),
    183      mInheritPrincipal(aOther.mInheritPrincipal),
    184      mPrincipalIsExplicit(aOther.mPrincipalIsExplicit),
    185      mNotifiedBeforeUnloadListeners(aOther.mNotifiedBeforeUnloadListeners),
    186      mPrincipalToInherit(aOther.mPrincipalToInherit),
    187      mPartitionedPrincipalToInherit(aOther.mPartitionedPrincipalToInherit),
    188      mForceAllowDataURI(aOther.mForceAllowDataURI),
    189      mIsExemptFromHTTPSFirstMode(aOther.mIsExemptFromHTTPSFirstMode),
    190      mHttpsFirstDowngradeData(aOther.GetHttpsFirstDowngradeData()),
    191      mOriginalFrameSrc(aOther.mOriginalFrameSrc),
    192      mShouldCheckForRecursion(aOther.mShouldCheckForRecursion),
    193      mIsFormSubmission(aOther.mIsFormSubmission),
    194      mNeedsCompletelyLoadedDocument(aOther.mNeedsCompletelyLoadedDocument),
    195      mHistoryBehavior(aOther.mHistoryBehavior),
    196      mLoadType(aOther.mLoadType),
    197      mSHEntry(aOther.mSHEntry),
    198      mTarget(aOther.mTarget),
    199      mTargetBrowsingContext(aOther.mTargetBrowsingContext),
    200      mPostDataStream(aOther.mPostDataStream),
    201      mHeadersStream(aOther.mHeadersStream),
    202      mSrcdocData(aOther.mSrcdocData),
    203      mSourceBrowsingContext(aOther.mSourceBrowsingContext),
    204      mBaseURI(aOther.mBaseURI),
    205      mLoadFlags(aOther.mLoadFlags),
    206      mInternalLoadFlags(aOther.mInternalLoadFlags),
    207      mFirstParty(aOther.mFirstParty),
    208      mHasValidUserGestureActivation(aOther.mHasValidUserGestureActivation),
    209      mTextDirectiveUserActivation(aOther.mTextDirectiveUserActivation),
    210      mAllowFocusMove(aOther.mAllowFocusMove),
    211      mTypeHint(aOther.mTypeHint),
    212      mFileName(aOther.mFileName),
    213      mIsFromProcessingFrameAttributes(aOther.mIsFromProcessingFrameAttributes),
    214      mPendingRedirectedChannel(aOther.mPendingRedirectedChannel),
    215      mOriginalURIString(aOther.mOriginalURIString),
    216      mCancelContentJSEpoch(aOther.mCancelContentJSEpoch),
    217      mLoadIdentifier(aOther.mLoadIdentifier),
    218      mChannelInitialized(aOther.mChannelInitialized),
    219      mIsMetaRefresh(aOther.mIsMetaRefresh),
    220      mWasCreatedRemotely(aOther.mWasCreatedRemotely),
    221      mUnstrippedURI(aOther.mUnstrippedURI),
    222      mRemoteTypeOverride(aOther.mRemoteTypeOverride),
    223      mTriggeringRemoteType(aOther.mTriggeringRemoteType),
    224      mSchemelessInput(aOther.mSchemelessInput),
    225      mForceMediaDocument(aOther.mForceMediaDocument),
    226      mHttpsUpgradeTelemetry(aOther.mHttpsUpgradeTelemetry),
    227      mNavigationAPIState(aOther.mNavigationAPIState),
    228      mIsInitialAboutBlankHandlingProhibited(
    229          aOther.mIsInitialAboutBlankHandlingProhibited) {
    230  MOZ_DIAGNOSTIC_ASSERT(
    231      XRE_IsParentProcess(),
    232      "Cloning a nsDocShellLoadState with the same load identifier is only "
    233      "allowed in the parent process, as it could break triggering remote type "
    234      "tracking in content.");
    235  if (aOther.mLoadingSessionHistoryInfo) {
    236    mLoadingSessionHistoryInfo = MakeUnique<LoadingSessionHistoryInfo>(
    237        *aOther.mLoadingSessionHistoryInfo);
    238  }
    239 }
    240 
    241 nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI, uint64_t aLoadIdentifier)
    242    : mURI(aURI),
    243      mResultPrincipalURIIsSome(false),
    244      mTriggeringSandboxFlags(0),
    245      mTriggeringWindowId(0),
    246      mTriggeringStorageAccess(false),
    247      mTriggeringClassificationFlags({0, 0}),
    248      mKeepResultPrincipalURIIfSet(false),
    249      mLoadReplace(false),
    250      mInheritPrincipal(false),
    251      mPrincipalIsExplicit(false),
    252      mNotifiedBeforeUnloadListeners(false),
    253      mForceAllowDataURI(false),
    254      mIsExemptFromHTTPSFirstMode(false),
    255      mOriginalFrameSrc(false),
    256      mShouldCheckForRecursion(false),
    257      mIsFormSubmission(false),
    258      mNeedsCompletelyLoadedDocument(false),
    259      mHistoryBehavior(Nothing()),
    260      mLoadType(LOAD_NORMAL),
    261      mSrcdocData(VoidString()),
    262      mLoadFlags(0),
    263      mInternalLoadFlags(0),
    264      mFirstParty(false),
    265      mHasValidUserGestureActivation(false),
    266      mAllowFocusMove(false),
    267      mTypeHint(VoidCString()),
    268      mFileName(VoidString()),
    269      mIsFromProcessingFrameAttributes(false),
    270      mLoadIdentifier(aLoadIdentifier),
    271      mChannelInitialized(false),
    272      mIsMetaRefresh(false),
    273      mWasCreatedRemotely(false),
    274      mTriggeringRemoteType(XRE_IsContentProcess()
    275                                ? ContentChild::GetSingleton()->GetRemoteType()
    276                                : NOT_REMOTE_TYPE),
    277      mSchemelessInput(nsILoadInfo::SchemelessInputTypeUnset),
    278      mIsInitialAboutBlankHandlingProhibited(false) {
    279  MOZ_ASSERT(aURI, "Cannot create a LoadState with a null URI!");
    280 
    281  // For https telemetry we set a flag indicating whether the load is https.
    282  // There are some corner cases, e.g. view-source and also about: pages.
    283  // about: pages, when hitting the network, always redirect to https.
    284  // Since we record https telemetry only within nsHTTPSChannel, it's fine
    285  // to set the flag here.
    286  nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
    287  if (innerURI->SchemeIs("https") || innerURI->SchemeIs("about")) {
    288    mHttpsUpgradeTelemetry = nsILoadInfo::ALREADY_HTTPS;
    289  } else {
    290    mHttpsUpgradeTelemetry = nsILoadInfo::NO_UPGRADE;
    291  }
    292 }
    293 
    294 nsDocShellLoadState::~nsDocShellLoadState() {
    295  if (mWasCreatedRemotely && XRE_IsContentProcess() &&
    296      ContentChild::GetSingleton()->CanSend()) {
    297    ContentChild::GetSingleton()->SendCleanupPendingLoadState(mLoadIdentifier);
    298  }
    299 }
    300 
    301 nsresult nsDocShellLoadState::CreateFromPendingChannel(
    302    nsIChannel* aPendingChannel, uint64_t aLoadIdentifier,
    303    uint64_t aRegistrarId, nsDocShellLoadState** aResult) {
    304  // Create the nsDocShellLoadState object with default state pulled from the
    305  // passed-in channel.
    306  nsCOMPtr<nsIURI> uri;
    307  nsresult rv = aPendingChannel->GetURI(getter_AddRefs(uri));
    308  if (NS_WARN_IF(NS_FAILED(rv))) {
    309    return rv;
    310  }
    311 
    312  RefPtr<nsDocShellLoadState> loadState =
    313      new nsDocShellLoadState(uri, aLoadIdentifier);
    314  loadState->mPendingRedirectedChannel = aPendingChannel;
    315  loadState->mChannelRegistrarId = aRegistrarId;
    316 
    317  // Pull relevant state from the channel, and store it on the
    318  // nsDocShellLoadState.
    319  nsCOMPtr<nsIURI> originalUri;
    320  rv = aPendingChannel->GetOriginalURI(getter_AddRefs(originalUri));
    321  if (NS_WARN_IF(NS_FAILED(rv))) {
    322    return rv;
    323  }
    324  loadState->SetOriginalURI(originalUri);
    325 
    326  nsCOMPtr<nsILoadInfo> loadInfo = aPendingChannel->LoadInfo();
    327  loadState->SetTriggeringPrincipal(loadInfo->TriggeringPrincipal());
    328 
    329  // Return the newly created loadState.
    330  loadState.forget(aResult);
    331  return NS_OK;
    332 }
    333 
    334 static uint32_t WebNavigationFlagsToFixupFlags(nsIURI* aURI,
    335                                               const nsACString& aURIString,
    336                                               uint32_t aNavigationFlags) {
    337  if (aURI) {
    338    aNavigationFlags &= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
    339  }
    340  uint32_t fixupFlags = nsIURIFixup::FIXUP_FLAG_NONE;
    341  if (aNavigationFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
    342    fixupFlags |= nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
    343  }
    344  if (aNavigationFlags & nsIWebNavigation::LOAD_FLAGS_FIXUP_SCHEME_TYPOS) {
    345    fixupFlags |= nsIURIFixup::FIXUP_FLAG_FIX_SCHEME_TYPOS;
    346  }
    347  return fixupFlags;
    348 };
    349 
    350 nsresult nsDocShellLoadState::CreateFromLoadURIOptions(
    351    BrowsingContext* aBrowsingContext, const nsAString& aURI,
    352    const LoadURIOptions& aLoadURIOptions, nsDocShellLoadState** aResult) {
    353  uint32_t loadFlags = aLoadURIOptions.mLoadFlags;
    354 
    355  NS_ASSERTION(
    356      (loadFlags & nsDocShell::INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0,
    357      "Unexpected flags");
    358 
    359  nsCOMPtr<nsIURI> uri;
    360  nsresult rv = NS_OK;
    361 
    362  NS_ConvertUTF16toUTF8 uriString(aURI);
    363  // Cleanup the empty spaces that might be on each end.
    364  uriString.Trim(" ");
    365  // Eliminate embedded newlines, which single-line text fields now allow:
    366  uriString.StripCRLF();
    367  NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
    368 
    369  // Just create a URI and see what happens...
    370  rv = NS_NewURI(getter_AddRefs(uri), uriString);
    371  bool fixup = true;
    372  if (NS_SUCCEEDED(rv) && uri &&
    373      (uri->SchemeIs("about") || uri->SchemeIs("chrome"))) {
    374    // Avoid third party fixup as a performance optimization.
    375    loadFlags &= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
    376    fixup = false;
    377  } else if (!sURIFixup && !XRE_IsContentProcess()) {
    378    nsCOMPtr<nsIURIFixup> uriFixup = components::URIFixup::Service();
    379    if (uriFixup) {
    380      sURIFixup = uriFixup;
    381      ClearOnShutdown(&sURIFixup);
    382    } else {
    383      fixup = false;
    384    }
    385  }
    386 
    387  nsAutoString searchProvider, keyword;
    388  RefPtr<nsIInputStream> fixupStream;
    389  if (fixup) {
    390    uint32_t fixupFlags =
    391        WebNavigationFlagsToFixupFlags(uri, uriString, loadFlags);
    392 
    393    // If we don't allow keyword lookups for this URL string, make sure to
    394    // update loadFlags to indicate this as well.
    395    if (!(fixupFlags & nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP)) {
    396      loadFlags &= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
    397    }
    398    // Ensure URIFixup will use the right search engine in Private Browsing.
    399    if (aBrowsingContext->UsePrivateBrowsing()) {
    400      fixupFlags |= nsIURIFixup::FIXUP_FLAG_PRIVATE_CONTEXT;
    401    }
    402 
    403    if (!XRE_IsContentProcess()) {
    404      nsCOMPtr<nsIURIFixupInfo> fixupInfo;
    405      sURIFixup->GetFixupURIInfo(uriString, fixupFlags,
    406                                 getter_AddRefs(fixupInfo));
    407      if (fixupInfo) {
    408        // We could fix the uri, clear NS_ERROR_MALFORMED_URI.
    409        rv = NS_OK;
    410        fixupInfo->GetPreferredURI(getter_AddRefs(uri));
    411        fixupInfo->SetConsumer(aBrowsingContext);
    412        fixupInfo->GetKeywordProviderName(searchProvider);
    413        fixupInfo->GetKeywordAsSent(keyword);
    414        // GetFixupURIInfo only returns a post data stream if it succeeded
    415        // and changed the URI, in which case we should override the
    416        // passed-in post data by passing this as an override arg to
    417        // our internal method.
    418        fixupInfo->GetPostData(getter_AddRefs(fixupStream));
    419 
    420        if (fixupInfo &&
    421            loadFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
    422          nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
    423          if (serv) {
    424            serv->NotifyObservers(fixupInfo, "keyword-uri-fixup",
    425                                  PromiseFlatString(aURI).get());
    426          }
    427        }
    428        nsDocShell::MaybeNotifyKeywordSearchLoading(searchProvider, keyword);
    429      }
    430    }
    431  }
    432 
    433  if (rv == NS_ERROR_MALFORMED_URI) {
    434    MOZ_ASSERT(!uri);
    435    return rv;
    436  }
    437 
    438  if (NS_FAILED(rv) || !uri) {
    439    return NS_ERROR_FAILURE;
    440  }
    441 
    442  RefPtr<nsDocShellLoadState> loadState;
    443  rv = CreateFromLoadURIOptions(
    444      aBrowsingContext, uri, aLoadURIOptions, loadFlags,
    445      fixupStream ? fixupStream : aLoadURIOptions.mPostData,
    446      getter_AddRefs(loadState));
    447  NS_ENSURE_SUCCESS(rv, rv);
    448  loadState->SetOriginalURIString(uriString);
    449  loadState.forget(aResult);
    450  return NS_OK;
    451 }
    452 
    453 nsresult nsDocShellLoadState::CreateFromLoadURIOptions(
    454    BrowsingContext* aBrowsingContext, nsIURI* aURI,
    455    const LoadURIOptions& aLoadURIOptions, nsDocShellLoadState** aResult) {
    456  return CreateFromLoadURIOptions(aBrowsingContext, aURI, aLoadURIOptions,
    457                                  aLoadURIOptions.mLoadFlags,
    458                                  aLoadURIOptions.mPostData, aResult);
    459 }
    460 
    461 nsresult nsDocShellLoadState::CreateFromLoadURIOptions(
    462    BrowsingContext* aBrowsingContext, nsIURI* aURI,
    463    const LoadURIOptions& aLoadURIOptions, uint32_t aLoadFlagsOverride,
    464    nsIInputStream* aPostDataOverride, nsDocShellLoadState** aResult) {
    465  nsresult rv = NS_OK;
    466  uint32_t loadFlags = aLoadFlagsOverride;
    467  RefPtr<nsIInputStream> postData = aPostDataOverride;
    468  uint64_t available;
    469  if (postData) {
    470    rv = postData->Available(&available);
    471    NS_ENSURE_SUCCESS(rv, rv);
    472    if (available == 0) {
    473      return NS_ERROR_INVALID_ARG;
    474    }
    475  }
    476 
    477  if (aLoadURIOptions.mHeaders) {
    478    rv = aLoadURIOptions.mHeaders->Available(&available);
    479    NS_ENSURE_SUCCESS(rv, rv);
    480    if (available == 0) {
    481      return NS_ERROR_INVALID_ARG;
    482    }
    483  }
    484 
    485  bool forceAllowDataURI =
    486      loadFlags & nsIWebNavigation::LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
    487 
    488  // Don't pass certain flags that aren't needed and end up confusing
    489  // ConvertLoadTypeToDocShellInfoLoadType.  We do need to ensure that they are
    490  // passed to LoadURI though, since it uses them.
    491  uint32_t extraFlags = (loadFlags & EXTRA_LOAD_FLAGS);
    492  loadFlags &= ~EXTRA_LOAD_FLAGS;
    493 
    494  RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(aURI);
    495  loadState->SetReferrerInfo(aLoadURIOptions.mReferrerInfo);
    496 
    497  loadState->SetLoadType(MAKE_LOAD_TYPE(LOAD_NORMAL, loadFlags));
    498 
    499  loadState->SetLoadFlags(extraFlags);
    500  loadState->SetFirstParty(true);
    501  loadState->SetHasValidUserGestureActivation(
    502      aLoadURIOptions.mHasValidUserGestureActivation);
    503  loadState->SetTextDirectiveUserActivation(
    504      aLoadURIOptions.mTextDirectiveUserActivation);
    505  loadState->SetTriggeringSandboxFlags(aLoadURIOptions.mTriggeringSandboxFlags);
    506  loadState->SetTriggeringWindowId(aLoadURIOptions.mTriggeringWindowId);
    507  loadState->SetTriggeringStorageAccess(
    508      aLoadURIOptions.mTriggeringStorageAccess);
    509  // The load is assumed to be first-party, so the triggering classification
    510  // should be both zero.
    511  loadState->SetTriggeringClassificationFlags({0, 0});
    512  loadState->SetPostDataStream(postData);
    513  loadState->SetHeadersStream(aLoadURIOptions.mHeaders);
    514  loadState->SetBaseURI(aLoadURIOptions.mBaseURI);
    515  loadState->SetTriggeringPrincipal(aLoadURIOptions.mTriggeringPrincipal);
    516  loadState->SetPolicyContainer(aLoadURIOptions.mPolicyContainer);
    517  loadState->SetForceAllowDataURI(forceAllowDataURI);
    518  if (aLoadURIOptions.mCancelContentJSEpoch) {
    519    loadState->SetCancelContentJSEpoch(aLoadURIOptions.mCancelContentJSEpoch);
    520  }
    521 
    522  if (aLoadURIOptions.mTriggeringRemoteType.WasPassed()) {
    523    if (XRE_IsParentProcess()) {
    524      loadState->SetTriggeringRemoteType(
    525          aLoadURIOptions.mTriggeringRemoteType.Value());
    526    } else if (ContentChild::GetSingleton()->GetRemoteType() !=
    527               aLoadURIOptions.mTriggeringRemoteType.Value()) {
    528      NS_WARNING("Invalid TriggeringRemoteType from LoadURIOptions in content");
    529      return NS_ERROR_INVALID_ARG;
    530    }
    531  }
    532 
    533  if (aLoadURIOptions.mRemoteTypeOverride.WasPassed()) {
    534    loadState->SetRemoteTypeOverride(
    535        aLoadURIOptions.mRemoteTypeOverride.Value());
    536  }
    537 
    538  loadState->SetSchemelessInput(static_cast<nsILoadInfo::SchemelessInputType>(
    539      aLoadURIOptions.mSchemelessInput));
    540 
    541  loadState->SetForceMediaDocument(aLoadURIOptions.mForceMediaDocument);
    542  loadState->SetAppLinkLaunchType(aLoadURIOptions.mAppLinkLaunchType);
    543  loadState->SetIsCaptivePortalTab(aLoadURIOptions.mIsCaptivePortalTab);
    544 
    545  loadState.forget(aResult);
    546  return NS_OK;
    547 }
    548 
    549 nsIReferrerInfo* nsDocShellLoadState::GetReferrerInfo() const {
    550  return mReferrerInfo;
    551 }
    552 
    553 void nsDocShellLoadState::SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
    554  mReferrerInfo = aReferrerInfo;
    555 }
    556 
    557 nsIURI* nsDocShellLoadState::URI() const { return mURI; }
    558 
    559 void nsDocShellLoadState::SetURI(nsIURI* aURI) { mURI = aURI; }
    560 
    561 nsIURI* nsDocShellLoadState::OriginalURI() const { return mOriginalURI; }
    562 
    563 void nsDocShellLoadState::SetOriginalURI(nsIURI* aOriginalURI) {
    564  mOriginalURI = aOriginalURI;
    565 }
    566 
    567 nsIURI* nsDocShellLoadState::ResultPrincipalURI() const {
    568  return mResultPrincipalURI;
    569 }
    570 
    571 void nsDocShellLoadState::SetResultPrincipalURI(nsIURI* aResultPrincipalURI) {
    572  mResultPrincipalURI = aResultPrincipalURI;
    573 }
    574 
    575 bool nsDocShellLoadState::ResultPrincipalURIIsSome() const {
    576  return mResultPrincipalURIIsSome;
    577 }
    578 
    579 void nsDocShellLoadState::SetResultPrincipalURIIsSome(bool aIsSome) {
    580  mResultPrincipalURIIsSome = aIsSome;
    581 }
    582 
    583 bool nsDocShellLoadState::KeepResultPrincipalURIIfSet() const {
    584  return mKeepResultPrincipalURIIfSet;
    585 }
    586 
    587 void nsDocShellLoadState::SetKeepResultPrincipalURIIfSet(bool aKeep) {
    588  mKeepResultPrincipalURIIfSet = aKeep;
    589 }
    590 
    591 bool nsDocShellLoadState::LoadReplace() const { return mLoadReplace; }
    592 
    593 void nsDocShellLoadState::SetLoadReplace(bool aLoadReplace) {
    594  mLoadReplace = aLoadReplace;
    595 }
    596 
    597 nsIPrincipal* nsDocShellLoadState::TriggeringPrincipal() const {
    598  return mTriggeringPrincipal;
    599 }
    600 
    601 void nsDocShellLoadState::SetTriggeringPrincipal(
    602    nsIPrincipal* aTriggeringPrincipal) {
    603  mTriggeringPrincipal = aTriggeringPrincipal;
    604 }
    605 
    606 nsIPrincipal* nsDocShellLoadState::PrincipalToInherit() const {
    607  return mPrincipalToInherit;
    608 }
    609 
    610 void nsDocShellLoadState::SetPrincipalToInherit(
    611    nsIPrincipal* aPrincipalToInherit) {
    612  mPrincipalToInherit = aPrincipalToInherit;
    613 }
    614 
    615 nsIPrincipal* nsDocShellLoadState::PartitionedPrincipalToInherit() const {
    616  return mPartitionedPrincipalToInherit;
    617 }
    618 
    619 void nsDocShellLoadState::SetPartitionedPrincipalToInherit(
    620    nsIPrincipal* aPartitionedPrincipalToInherit) {
    621  mPartitionedPrincipalToInherit = aPartitionedPrincipalToInherit;
    622 }
    623 
    624 void nsDocShellLoadState::SetPolicyContainer(
    625    nsIPolicyContainer* aPolicyContainer) {
    626  mPolicyContainer = aPolicyContainer;
    627 }
    628 
    629 nsIPolicyContainer* nsDocShellLoadState::PolicyContainer() const {
    630  return mPolicyContainer;
    631 }
    632 
    633 void nsDocShellLoadState::SetTriggeringSandboxFlags(uint32_t flags) {
    634  mTriggeringSandboxFlags = flags;
    635 }
    636 
    637 uint32_t nsDocShellLoadState::TriggeringSandboxFlags() const {
    638  return mTriggeringSandboxFlags;
    639 }
    640 
    641 void nsDocShellLoadState::SetTriggeringWindowId(uint64_t aTriggeringWindowId) {
    642  mTriggeringWindowId = aTriggeringWindowId;
    643 }
    644 
    645 uint64_t nsDocShellLoadState::TriggeringWindowId() const {
    646  return mTriggeringWindowId;
    647 }
    648 
    649 void nsDocShellLoadState::SetTriggeringStorageAccess(
    650    bool aTriggeringStorageAccess) {
    651  mTriggeringStorageAccess = aTriggeringStorageAccess;
    652 }
    653 
    654 bool nsDocShellLoadState::TriggeringStorageAccess() const {
    655  return mTriggeringStorageAccess;
    656 }
    657 
    658 mozilla::net::ClassificationFlags
    659 nsDocShellLoadState::TriggeringClassificationFlags() const {
    660  return mTriggeringClassificationFlags;
    661 }
    662 
    663 void nsDocShellLoadState::SetTriggeringClassificationFlags(
    664    mozilla::net::ClassificationFlags aFlags) {
    665  mTriggeringClassificationFlags = aFlags;
    666 }
    667 
    668 bool nsDocShellLoadState::InheritPrincipal() const { return mInheritPrincipal; }
    669 
    670 void nsDocShellLoadState::SetInheritPrincipal(bool aInheritPrincipal) {
    671  mInheritPrincipal = aInheritPrincipal;
    672 }
    673 
    674 bool nsDocShellLoadState::PrincipalIsExplicit() const {
    675  return mPrincipalIsExplicit;
    676 }
    677 
    678 void nsDocShellLoadState::SetPrincipalIsExplicit(bool aPrincipalIsExplicit) {
    679  mPrincipalIsExplicit = aPrincipalIsExplicit;
    680 }
    681 
    682 bool nsDocShellLoadState::NotifiedBeforeUnloadListeners() const {
    683  return mNotifiedBeforeUnloadListeners;
    684 }
    685 
    686 void nsDocShellLoadState::SetNotifiedBeforeUnloadListeners(
    687    bool aNotifiedBeforeUnloadListeners) {
    688  mNotifiedBeforeUnloadListeners = aNotifiedBeforeUnloadListeners;
    689 }
    690 
    691 bool nsDocShellLoadState::ForceAllowDataURI() const {
    692  return mForceAllowDataURI;
    693 }
    694 
    695 void nsDocShellLoadState::SetForceAllowDataURI(bool aForceAllowDataURI) {
    696  mForceAllowDataURI = aForceAllowDataURI;
    697 }
    698 
    699 bool nsDocShellLoadState::IsExemptFromHTTPSFirstMode() const {
    700  return mIsExemptFromHTTPSFirstMode;
    701 }
    702 
    703 void nsDocShellLoadState::SetIsExemptFromHTTPSFirstMode(
    704    bool aIsExemptFromHTTPSFirstMode) {
    705  mIsExemptFromHTTPSFirstMode = aIsExemptFromHTTPSFirstMode;
    706 }
    707 
    708 RefPtr<HTTPSFirstDowngradeData>
    709 nsDocShellLoadState::GetHttpsFirstDowngradeData() const {
    710  return mHttpsFirstDowngradeData;
    711 }
    712 
    713 void nsDocShellLoadState::SetHttpsFirstDowngradeData(
    714    RefPtr<HTTPSFirstDowngradeData> const& aHttpsFirstTelemetryData) {
    715  mHttpsFirstDowngradeData = aHttpsFirstTelemetryData;
    716 }
    717 
    718 bool nsDocShellLoadState::OriginalFrameSrc() const { return mOriginalFrameSrc; }
    719 
    720 void nsDocShellLoadState::SetOriginalFrameSrc(bool aOriginalFrameSrc) {
    721  mOriginalFrameSrc = aOriginalFrameSrc;
    722 }
    723 
    724 bool nsDocShellLoadState::ShouldCheckForRecursion() const {
    725  return mShouldCheckForRecursion;
    726 }
    727 
    728 void nsDocShellLoadState::SetShouldCheckForRecursion(
    729    bool aShouldCheckForRecursion) {
    730  mShouldCheckForRecursion = aShouldCheckForRecursion;
    731 }
    732 
    733 bool nsDocShellLoadState::IsFormSubmission() const { return mIsFormSubmission; }
    734 
    735 void nsDocShellLoadState::SetIsFormSubmission(bool aIsFormSubmission) {
    736  mIsFormSubmission = aIsFormSubmission;
    737 }
    738 
    739 bool nsDocShellLoadState::NeedsCompletelyLoadedDocument() const {
    740  return mNeedsCompletelyLoadedDocument;
    741 }
    742 
    743 void nsDocShellLoadState::SetNeedsCompletelyLoadedDocument(
    744    bool aNeedsCompletelyLoadedDocument) {
    745  mNeedsCompletelyLoadedDocument = aNeedsCompletelyLoadedDocument;
    746 }
    747 
    748 Maybe<mozilla::dom::NavigationHistoryBehavior>
    749 nsDocShellLoadState::HistoryBehavior() const {
    750  return mHistoryBehavior;
    751 }
    752 
    753 void nsDocShellLoadState::SetHistoryBehavior(
    754    mozilla::dom::NavigationHistoryBehavior aHistoryBehavior) {
    755  mHistoryBehavior = Some(aHistoryBehavior);
    756 }
    757 
    758 void nsDocShellLoadState::ResetHistoryBehavior() {
    759  mHistoryBehavior = Nothing();
    760 }
    761 
    762 uint32_t nsDocShellLoadState::LoadType() const { return mLoadType; }
    763 
    764 void nsDocShellLoadState::SetLoadType(uint32_t aLoadType) {
    765  mLoadType = aLoadType;
    766 }
    767 
    768 mozilla::dom::UserNavigationInvolvement
    769 nsDocShellLoadState::UserNavigationInvolvement() const {
    770  return mUserNavigationInvolvement;
    771 }
    772 
    773 void nsDocShellLoadState::SetUserNavigationInvolvement(
    774    mozilla::dom::UserNavigationInvolvement aUserNavigationInvolvement) {
    775  mUserNavigationInvolvement = aUserNavigationInvolvement;
    776 }
    777 
    778 nsISHEntry* nsDocShellLoadState::SHEntry() const { return mSHEntry; }
    779 
    780 void nsDocShellLoadState::SetSHEntry(nsISHEntry* aSHEntry) {
    781  mSHEntry = aSHEntry;
    782  nsCOMPtr<SessionHistoryEntry> she = do_QueryInterface(aSHEntry);
    783  if (she) {
    784    mLoadingSessionHistoryInfo = MakeUnique<LoadingSessionHistoryInfo>(she);
    785    mLoadingSessionHistoryInfo->mTriggeringNavigationType =
    786        NavigationUtils::NavigationTypeFromLoadType(LoadType());
    787    MOZ_ASSERT(mLoadingSessionHistoryInfo->mTriggeringNavigationType);
    788  } else {
    789    mLoadingSessionHistoryInfo = nullptr;
    790  }
    791 }
    792 
    793 void nsDocShellLoadState::SetLoadingSessionHistoryInfo(
    794    const mozilla::dom::LoadingSessionHistoryInfo& aLoadingInfo) {
    795  SetLoadingSessionHistoryInfo(
    796      MakeUnique<mozilla::dom::LoadingSessionHistoryInfo>(aLoadingInfo));
    797 }
    798 
    799 void nsDocShellLoadState::SetLoadingSessionHistoryInfo(
    800    mozilla::UniquePtr<mozilla::dom::LoadingSessionHistoryInfo> aLoadingInfo) {
    801  mLoadingSessionHistoryInfo = std::move(aLoadingInfo);
    802 }
    803 
    804 const mozilla::dom::LoadingSessionHistoryInfo*
    805 nsDocShellLoadState::GetLoadingSessionHistoryInfo() const {
    806  return mLoadingSessionHistoryInfo.get();
    807 }
    808 
    809 void nsDocShellLoadState::SetLoadIsFromSessionHistory(
    810    int32_t aOffset, bool aLoadingCurrentEntry) {
    811  if (mLoadingSessionHistoryInfo) {
    812    mLoadingSessionHistoryInfo->mLoadIsFromSessionHistory = true;
    813    mLoadingSessionHistoryInfo->mOffset = aOffset;
    814    mLoadingSessionHistoryInfo->mLoadingCurrentEntry = aLoadingCurrentEntry;
    815  }
    816 }
    817 
    818 void nsDocShellLoadState::ClearLoadIsFromSessionHistory() {
    819  if (mLoadingSessionHistoryInfo) {
    820    mLoadingSessionHistoryInfo->mLoadIsFromSessionHistory = false;
    821  }
    822  mSHEntry = nullptr;
    823 }
    824 
    825 bool nsDocShellLoadState::LoadIsFromSessionHistory() const {
    826  return mLoadingSessionHistoryInfo
    827             ? mLoadingSessionHistoryInfo->mLoadIsFromSessionHistory
    828             : !!mSHEntry;
    829 }
    830 
    831 void nsDocShellLoadState::MaybeStripTrackerQueryStrings(
    832    BrowsingContext* aContext) {
    833  MOZ_ASSERT(aContext);
    834 
    835  // Return early if the triggering principal doesn't exist. This could happen
    836  // when loading a URL by using a browsing context in the Browser Toolbox.
    837  if (!TriggeringPrincipal()) {
    838    return;
    839  }
    840 
    841  // We don't need to strip for sub frames because the query string has been
    842  // stripped in the top-level content. Also, we don't apply stripping if it
    843  // is triggered by addons.
    844  //
    845  // Note that we don't need to do the stripping if the channel has been
    846  // initialized. This means that this has been loaded speculatively in the
    847  // parent process before and the stripping was happening by then.
    848  if (GetChannelInitialized() || !aContext->IsTopContent() ||
    849      BasePrincipal::Cast(TriggeringPrincipal())->AddonPolicy()) {
    850    return;
    851  }
    852 
    853  // We don't strip the URI if it's the same-site navigation. Note that we will
    854  // consider the system principal triggered load as third-party in case the
    855  // user copies and pastes a URL which has tracking query parameters or an
    856  // loading from external applications, such as clicking a link in an email
    857  // client.
    858  bool isThirdPartyURI = false;
    859  if (!TriggeringPrincipal()->IsSystemPrincipal() &&
    860      (NS_FAILED(
    861           TriggeringPrincipal()->IsThirdPartyURI(URI(), &isThirdPartyURI)) ||
    862       !isThirdPartyURI)) {
    863    return;
    864  }
    865 
    866  glean::contentblocking::query_stripping_count
    867      .EnumGet(glean::contentblocking::QueryStrippingCountLabel::eNavigation)
    868      .Add();
    869 
    870  nsCOMPtr<nsIURI> strippedURI;
    871 
    872  nsresult rv;
    873  nsCOMPtr<nsIURLQueryStringStripper> queryStripper =
    874      components::URLQueryStringStripper::Service(&rv);
    875  NS_ENSURE_SUCCESS_VOID(rv);
    876 
    877  uint32_t numStripped;
    878 
    879  queryStripper->Strip(URI(), aContext->UsePrivateBrowsing(),
    880                       getter_AddRefs(strippedURI), &numStripped);
    881  if (numStripped) {
    882    if (!mUnstrippedURI) {
    883      mUnstrippedURI = URI();
    884    }
    885    SetURI(strippedURI);
    886 
    887    glean::contentblocking::query_stripping_count
    888        .EnumGet(glean::contentblocking::QueryStrippingCountLabel::
    889                     eStripfornavigation)
    890        .Add();
    891    glean::contentblocking::query_stripping_param_count.AccumulateSingleSample(
    892        numStripped);
    893  }
    894 
    895 #ifdef DEBUG
    896  // Make sure that unstripped URI is the same as URI() but only the query
    897  // string could be different.
    898  if (mUnstrippedURI) {
    899    nsCOMPtr<nsIURI> uri;
    900    (void)queryStripper->Strip(mUnstrippedURI, aContext->UsePrivateBrowsing(),
    901                               getter_AddRefs(uri), &numStripped);
    902    bool equals = false;
    903    (void)URI()->Equals(uri, &equals);
    904    MOZ_ASSERT(equals);
    905  }
    906 #endif
    907 }
    908 
    909 const nsString& nsDocShellLoadState::Target() const { return mTarget; }
    910 
    911 void nsDocShellLoadState::SetTarget(const nsAString& aTarget) {
    912  mTarget = aTarget;
    913 }
    914 
    915 nsIInputStream* nsDocShellLoadState::PostDataStream() const {
    916  return mPostDataStream;
    917 }
    918 
    919 void nsDocShellLoadState::SetPostDataStream(nsIInputStream* aStream) {
    920  mPostDataStream = aStream;
    921 }
    922 
    923 nsIInputStream* nsDocShellLoadState::HeadersStream() const {
    924  return mHeadersStream;
    925 }
    926 
    927 void nsDocShellLoadState::SetHeadersStream(nsIInputStream* aHeadersStream) {
    928  mHeadersStream = aHeadersStream;
    929 }
    930 
    931 const nsString& nsDocShellLoadState::SrcdocData() const { return mSrcdocData; }
    932 
    933 void nsDocShellLoadState::SetSrcdocData(const nsAString& aSrcdocData) {
    934  mSrcdocData = aSrcdocData;
    935 }
    936 
    937 void nsDocShellLoadState::SetSourceBrowsingContext(
    938    BrowsingContext* aSourceBrowsingContext) {
    939  mSourceBrowsingContext = aSourceBrowsingContext;
    940 }
    941 
    942 void nsDocShellLoadState::SetTargetBrowsingContext(
    943    BrowsingContext* aTargetBrowsingContext) {
    944  mTargetBrowsingContext = aTargetBrowsingContext;
    945 }
    946 
    947 nsIURI* nsDocShellLoadState::BaseURI() const { return mBaseURI; }
    948 
    949 void nsDocShellLoadState::SetBaseURI(nsIURI* aBaseURI) { mBaseURI = aBaseURI; }
    950 
    951 void nsDocShellLoadState::GetMaybeResultPrincipalURI(
    952    mozilla::Maybe<nsCOMPtr<nsIURI>>& aRPURI) const {
    953  bool isSome = ResultPrincipalURIIsSome();
    954  aRPURI.reset();
    955 
    956  if (!isSome) {
    957    return;
    958  }
    959 
    960  nsCOMPtr<nsIURI> uri = ResultPrincipalURI();
    961  aRPURI.emplace(std::move(uri));
    962 }
    963 
    964 void nsDocShellLoadState::SetMaybeResultPrincipalURI(
    965    mozilla::Maybe<nsCOMPtr<nsIURI>> const& aRPURI) {
    966  SetResultPrincipalURI(aRPURI.refOr(nullptr));
    967  SetResultPrincipalURIIsSome(aRPURI.isSome());
    968 }
    969 
    970 uint32_t nsDocShellLoadState::LoadFlags() const { return mLoadFlags; }
    971 
    972 void nsDocShellLoadState::SetLoadFlags(uint32_t aLoadFlags) {
    973  mLoadFlags = aLoadFlags;
    974 }
    975 
    976 void nsDocShellLoadState::SetLoadFlag(uint32_t aFlag) { mLoadFlags |= aFlag; }
    977 
    978 void nsDocShellLoadState::UnsetLoadFlag(uint32_t aFlag) {
    979  mLoadFlags &= ~aFlag;
    980 }
    981 
    982 bool nsDocShellLoadState::HasLoadFlags(uint32_t aFlags) {
    983  return (mLoadFlags & aFlags) == aFlags;
    984 }
    985 
    986 uint32_t nsDocShellLoadState::InternalLoadFlags() const {
    987  return mInternalLoadFlags;
    988 }
    989 
    990 void nsDocShellLoadState::SetInternalLoadFlags(uint32_t aLoadFlags) {
    991  mInternalLoadFlags = aLoadFlags;
    992 }
    993 
    994 void nsDocShellLoadState::SetInternalLoadFlag(uint32_t aFlag) {
    995  mInternalLoadFlags |= aFlag;
    996 }
    997 
    998 void nsDocShellLoadState::UnsetInternalLoadFlag(uint32_t aFlag) {
    999  mInternalLoadFlags &= ~aFlag;
   1000 }
   1001 
   1002 bool nsDocShellLoadState::HasInternalLoadFlags(uint32_t aFlags) {
   1003  return (mInternalLoadFlags & aFlags) == aFlags;
   1004 }
   1005 
   1006 bool nsDocShellLoadState::FirstParty() const { return mFirstParty; }
   1007 
   1008 void nsDocShellLoadState::SetFirstParty(bool aFirstParty) {
   1009  mFirstParty = aFirstParty;
   1010 }
   1011 
   1012 bool nsDocShellLoadState::HasValidUserGestureActivation() const {
   1013  return mHasValidUserGestureActivation;
   1014 }
   1015 
   1016 void nsDocShellLoadState::SetHasValidUserGestureActivation(
   1017    bool aHasValidUserGestureActivation) {
   1018  mHasValidUserGestureActivation = aHasValidUserGestureActivation;
   1019 }
   1020 
   1021 void nsDocShellLoadState::SetTextDirectiveUserActivation(
   1022    bool aTextDirectiveUserActivation) {
   1023  mTextDirectiveUserActivation = aTextDirectiveUserActivation;
   1024 }
   1025 
   1026 bool nsDocShellLoadState::GetTextDirectiveUserActivation() {
   1027  return mTextDirectiveUserActivation;
   1028 }
   1029 
   1030 const nsCString& nsDocShellLoadState::TypeHint() const { return mTypeHint; }
   1031 
   1032 void nsDocShellLoadState::SetTypeHint(const nsCString& aTypeHint) {
   1033  mTypeHint = aTypeHint;
   1034 }
   1035 
   1036 const nsString& nsDocShellLoadState::FileName() const { return mFileName; }
   1037 
   1038 void nsDocShellLoadState::SetFileName(const nsAString& aFileName) {
   1039  MOZ_DIAGNOSTIC_ASSERT(aFileName.FindChar(char16_t(0)) == kNotFound,
   1040                        "The filename should never contain null characters");
   1041  mFileName = aFileName;
   1042 }
   1043 
   1044 void nsDocShellLoadState::SetRemoteTypeOverride(
   1045    const nsCString& aRemoteTypeOverride) {
   1046  MOZ_DIAGNOSTIC_ASSERT(
   1047      NS_IsAboutBlank(mURI),
   1048      "Should only have aRemoteTypeOverride for about:blank URIs");
   1049  mRemoteTypeOverride = mozilla::Some(aRemoteTypeOverride);
   1050 }
   1051 
   1052 const nsCString& nsDocShellLoadState::GetEffectiveTriggeringRemoteType() const {
   1053  // Consider non-errorpage loads from session history as being triggred by the
   1054  // parent process, as we'll validate them against the history entry.
   1055  //
   1056  // NOTE: Keep this check in-sync with the session-history validation check in
   1057  // `DocumentLoadListener::Open`!
   1058  if (LoadIsFromSessionHistory() && LoadType() != LOAD_ERROR_PAGE) {
   1059    return NOT_REMOTE_TYPE;
   1060  }
   1061  return mTriggeringRemoteType;
   1062 }
   1063 
   1064 void nsDocShellLoadState::SetTriggeringRemoteType(
   1065    const nsACString& aTriggeringRemoteType) {
   1066  MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "only settable in parent");
   1067  mTriggeringRemoteType = aTriggeringRemoteType;
   1068 }
   1069 
   1070 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
   1071 void nsDocShellLoadState::AssertProcessCouldTriggerLoadIfSystem() {
   1072  // Early check to see if we're trying to start a file URI load with a system
   1073  // principal within a web content process.
   1074  // If this assertion fails, the load will fail later during
   1075  // nsContentSecurityManager checks, however this assertion should happen
   1076  // closer to whichever caller is triggering the system-principal load.
   1077  if (mozilla::SessionHistoryInParent() &&
   1078      TriggeringPrincipal()->IsSystemPrincipal() &&
   1079      mozilla::dom::IsWebRemoteType(GetEffectiveTriggeringRemoteType())) {
   1080    bool localFile = false;
   1081    if (NS_SUCCEEDED(NS_URIChainHasFlags(
   1082            URI(), nsIProtocolHandler::URI_IS_LOCAL_FILE, &localFile)) &&
   1083        localFile) {
   1084      NS_WARNING(nsPrintfCString("Unexpected system load of file URI (%s) from "
   1085                                 "web content process",
   1086                                 URI()->GetSpecOrDefault().get())
   1087                     .get());
   1088      MOZ_CRASH("Unexpected system load of file URI from web content process");
   1089    }
   1090  }
   1091 }
   1092 #endif
   1093 
   1094 nsresult nsDocShellLoadState::SetupInheritingPrincipal(
   1095    BrowsingContext::Type aType,
   1096    const mozilla::OriginAttributes& aOriginAttributes) {
   1097  // We need a principalToInherit.
   1098  //
   1099  // If principalIsExplicit is not set there are 4 possibilities:
   1100  // (1) If the system principal or an expanded principal was passed
   1101  //     in and we're a typeContent docshell, inherit the principal
   1102  //     from the current document instead.
   1103  // (2) In all other cases when the principal passed in is not null,
   1104  //     use that principal.
   1105  // (3) If the caller has allowed inheriting from the current document,
   1106  //     or if we're being called from system code (eg chrome JS or pure
   1107  //     C++) then inheritPrincipal should be true and InternalLoad will get
   1108  //     a principal from the current document. If none of these things are
   1109  //     true, then
   1110  // (4) we don't pass a principal into the channel, and a principal will be
   1111  //     created later from the channel's internal data.
   1112  //
   1113  // If principalIsExplicit *is* set, there are 4 possibilities
   1114  // (1) If the system principal or an expanded principal was passed in
   1115  //     and we're a typeContent docshell, return an error.
   1116  // (2) In all other cases when the principal passed in is not null,
   1117  //     use that principal.
   1118  // (3) If the caller has allowed inheriting from the current document,
   1119  //     then inheritPrincipal should be true and InternalLoad will get
   1120  //     a principal from the current document. If none of these things are
   1121  //     true, then
   1122  // (4) we dont' pass a principal into the channel, and a principal will be
   1123  //     created later from the channel's internal data.
   1124  mPrincipalToInherit = mTriggeringPrincipal;
   1125  if (mPrincipalToInherit && aType != BrowsingContext::Type::Chrome) {
   1126    if (mPrincipalToInherit->IsSystemPrincipal()) {
   1127      if (mPrincipalIsExplicit) {
   1128        return NS_ERROR_DOM_SECURITY_ERR;
   1129      }
   1130      mPrincipalToInherit = nullptr;
   1131      mInheritPrincipal = true;
   1132    } else if (nsContentUtils::IsExpandedPrincipal(mPrincipalToInherit)) {
   1133      if (mPrincipalIsExplicit) {
   1134        return NS_ERROR_DOM_SECURITY_ERR;
   1135      }
   1136      // Don't inherit from the current page.  Just do the safe thing
   1137      // and pretend that we were loaded by a nullprincipal.
   1138      //
   1139      // We didn't inherit OriginAttributes here as ExpandedPrincipal doesn't
   1140      // have origin attributes.
   1141      mPrincipalToInherit = NullPrincipal::Create(aOriginAttributes);
   1142      mInheritPrincipal = false;
   1143    }
   1144  }
   1145 
   1146  if (!mPrincipalToInherit && !mInheritPrincipal && !mPrincipalIsExplicit) {
   1147    // See if there's system or chrome JS code running
   1148    mInheritPrincipal = nsContentUtils::LegacyIsCallerChromeOrNativeCode();
   1149  }
   1150 
   1151  if (mLoadFlags & nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL) {
   1152    mInheritPrincipal = false;
   1153    // Create a new null principal URI based on our precursor principal.
   1154    nsCOMPtr<nsIURI> nullPrincipalURI =
   1155        NullPrincipal::CreateURI(mPrincipalToInherit);
   1156    // If mFirstParty is true and the pref 'privacy.firstparty.isolate' is
   1157    // enabled, we will set firstPartyDomain on the origin attributes.
   1158    OriginAttributes attrs(aOriginAttributes);
   1159    if (mFirstParty) {
   1160      attrs.SetFirstPartyDomain(true, nullPrincipalURI);
   1161    }
   1162    mPrincipalToInherit = NullPrincipal::Create(attrs, nullPrincipalURI);
   1163  }
   1164 
   1165  return NS_OK;
   1166 }
   1167 
   1168 nsresult nsDocShellLoadState::SetupTriggeringPrincipal(
   1169    const mozilla::OriginAttributes& aOriginAttributes) {
   1170  // If the triggeringPrincipal is not set, we first try to create a principal
   1171  // from the referrer, since the referrer URI reflects the web origin that
   1172  // triggered the load. If there is no referrer URI, we fall back to using the
   1173  // SystemPrincipal. It's safe to assume that no provided triggeringPrincipal
   1174  // and no referrer simulate a load that was triggered by the system. It's
   1175  // important to note that this block of code needs to appear *after* the block
   1176  // where we munge the principalToInherit, because otherwise we would never
   1177  // enter code blocks checking if the principalToInherit is null and we will
   1178  // end up with a wrong inheritPrincipal flag.
   1179  if (!mTriggeringPrincipal) {
   1180    if (mReferrerInfo) {
   1181      nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetOriginalReferrer();
   1182      mTriggeringPrincipal =
   1183          BasePrincipal::CreateContentPrincipal(referrer, aOriginAttributes);
   1184 
   1185      if (!mTriggeringPrincipal) {
   1186        return NS_ERROR_FAILURE;
   1187      }
   1188    } else {
   1189      mTriggeringPrincipal = nsContentUtils::GetSystemPrincipal();
   1190    }
   1191  }
   1192  return NS_OK;
   1193 }
   1194 
   1195 void nsDocShellLoadState::CalculateLoadURIFlags() {
   1196  if (mInheritPrincipal) {
   1197    MOZ_ASSERT(
   1198        !mPrincipalToInherit || !mPrincipalToInherit->IsSystemPrincipal(),
   1199        "Should not inherit SystemPrincipal");
   1200    mInternalLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL;
   1201  }
   1202 
   1203  if (mReferrerInfo && !mReferrerInfo->GetSendReferrer()) {
   1204    mInternalLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER;
   1205  }
   1206  if (mLoadFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
   1207    mInternalLoadFlags |=
   1208        nsDocShell::INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
   1209  }
   1210 
   1211  if (mLoadFlags & nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD) {
   1212    mInternalLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_FIRST_LOAD;
   1213  }
   1214 
   1215  if (mLoadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CLASSIFIER) {
   1216    mInternalLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER;
   1217  }
   1218 
   1219  if (mLoadFlags & nsIWebNavigation::LOAD_FLAGS_FORCE_ALLOW_COOKIES) {
   1220    mInternalLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES;
   1221  }
   1222 
   1223  if (mLoadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_LOAD_URI_DELEGATE) {
   1224    mInternalLoadFlags |=
   1225        nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_LOAD_URI_DELEGATE;
   1226  }
   1227 
   1228  if (!mSrcdocData.IsVoid()) {
   1229    mInternalLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_IS_SRCDOC;
   1230  }
   1231 
   1232  if (mForceAllowDataURI) {
   1233    mInternalLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
   1234  }
   1235 
   1236  if (mOriginalFrameSrc) {
   1237    mInternalLoadFlags |= nsDocShell::INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC;
   1238  }
   1239 }
   1240 
   1241 nsLoadFlags nsDocShellLoadState::CalculateChannelLoadFlags(
   1242    BrowsingContext* aBrowsingContext, bool aUriModified,
   1243    Maybe<bool> aIsEmbeddingBlockedError) {
   1244  MOZ_ASSERT(aBrowsingContext);
   1245 
   1246  nsLoadFlags loadFlags = aBrowsingContext->GetDefaultLoadFlags();
   1247 
   1248  if (FirstParty()) {
   1249    // tag first party URL loads
   1250    loadFlags |= nsIChannel::LOAD_INITIAL_DOCUMENT_URI;
   1251  }
   1252 
   1253  const uint32_t loadType = LoadType();
   1254 
   1255  // These values aren't available for loads initiated in the Parent process.
   1256  MOZ_ASSERT_IF(loadType == LOAD_ERROR_PAGE, aIsEmbeddingBlockedError.isSome());
   1257 
   1258  if (loadType == LOAD_ERROR_PAGE) {
   1259    // Error pages are LOAD_BACKGROUND, unless it's an
   1260    // XFO / frame-ancestors error for which we want an error page to load
   1261    // but additionally want the onload() event to fire.
   1262    if (!*aIsEmbeddingBlockedError) {
   1263      loadFlags |= nsIChannel::LOAD_BACKGROUND;
   1264    }
   1265  }
   1266 
   1267  // Mark the channel as being a document URI and allow content sniffing...
   1268  loadFlags |=
   1269      nsIChannel::LOAD_DOCUMENT_URI | nsIChannel::LOAD_CALL_CONTENT_SNIFFERS;
   1270 
   1271  if (nsDocShell::SandboxFlagsImplyCookies(
   1272          aBrowsingContext->GetSandboxFlags())) {
   1273    loadFlags |= nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE;
   1274  }
   1275 
   1276  // Load attributes depend on load type...
   1277  switch (loadType) {
   1278    case LOAD_HISTORY: {
   1279      // Only send VALIDATE_NEVER if mLSHE's URI was never changed via
   1280      // push/replaceState (bug 669671).
   1281      if (!aUriModified) {
   1282        loadFlags |= nsIRequest::VALIDATE_NEVER;
   1283      }
   1284      break;
   1285    }
   1286 
   1287    case LOAD_RELOAD_CHARSET_CHANGE_BYPASS_PROXY_AND_CACHE:
   1288    case LOAD_RELOAD_CHARSET_CHANGE_BYPASS_CACHE:
   1289      loadFlags |=
   1290          nsIRequest::LOAD_BYPASS_CACHE | nsIRequest::LOAD_FRESH_CONNECTION;
   1291      [[fallthrough]];
   1292 
   1293    case LOAD_REFRESH:
   1294      loadFlags |= nsIRequest::VALIDATE_ALWAYS;
   1295      break;
   1296 
   1297    case LOAD_NORMAL_BYPASS_CACHE:
   1298    case LOAD_NORMAL_BYPASS_PROXY:
   1299    case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE:
   1300    case LOAD_RELOAD_BYPASS_CACHE:
   1301    case LOAD_RELOAD_BYPASS_PROXY:
   1302    case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
   1303    case LOAD_REPLACE_BYPASS_CACHE:
   1304      loadFlags |=
   1305          nsIRequest::LOAD_BYPASS_CACHE | nsIRequest::LOAD_FRESH_CONNECTION;
   1306      break;
   1307 
   1308    case LOAD_RELOAD_NORMAL:
   1309      if (!StaticPrefs::
   1310              browser_soft_reload_only_force_validate_top_level_document()) {
   1311        loadFlags |= nsIRequest::VALIDATE_ALWAYS;
   1312        break;
   1313      }
   1314      [[fallthrough]];
   1315    case LOAD_NORMAL:
   1316    case LOAD_LINK:
   1317      // Set cache checking flags
   1318      switch (StaticPrefs::browser_cache_check_doc_frequency()) {
   1319        case 0:
   1320          loadFlags |= nsIRequest::VALIDATE_ONCE_PER_SESSION;
   1321          break;
   1322        case 1:
   1323          loadFlags |= nsIRequest::VALIDATE_ALWAYS;
   1324          break;
   1325        case 2:
   1326          loadFlags |= nsIRequest::VALIDATE_NEVER;
   1327          break;
   1328      }
   1329      break;
   1330  }
   1331 
   1332  if (HasInternalLoadFlags(nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER)) {
   1333    loadFlags |= nsIChannel::LOAD_BYPASS_URL_CLASSIFIER;
   1334  }
   1335 
   1336  // If the user pressed shift-reload, then do not allow ServiceWorker
   1337  // interception to occur. See step 12.1 of the SW HandleFetch algorithm.
   1338  if (IsForceReloadType(loadType)) {
   1339    loadFlags |= nsIChannel::LOAD_BYPASS_SERVICE_WORKER;
   1340  }
   1341 
   1342  return loadFlags;
   1343 }
   1344 
   1345 const char* nsDocShellLoadState::ValidateWithOriginalState(
   1346    nsDocShellLoadState* aOriginalState) {
   1347  MOZ_ASSERT(mLoadIdentifier == aOriginalState->mLoadIdentifier);
   1348 
   1349  // Check that `aOriginalState` is sufficiently similar to this state that
   1350  // they're performing the same load.
   1351  auto uriEq = [](nsIURI* a, nsIURI* b) -> bool {
   1352    bool eq = false;
   1353    return a == b || (a && b && NS_SUCCEEDED(a->Equals(b, &eq)) && eq);
   1354  };
   1355  if (!uriEq(mURI, aOriginalState->mURI)) {
   1356    return "URI";
   1357  }
   1358  if (!uriEq(mUnstrippedURI, aOriginalState->mUnstrippedURI)) {
   1359    return "UnstrippedURI";
   1360  }
   1361  if (!uriEq(mOriginalURI, aOriginalState->mOriginalURI)) {
   1362    return "OriginalURI";
   1363  }
   1364  if (!uriEq(mBaseURI, aOriginalState->mBaseURI)) {
   1365    return "BaseURI";
   1366  }
   1367 
   1368  if (!mTriggeringPrincipal->Equals(aOriginalState->mTriggeringPrincipal)) {
   1369    return "TriggeringPrincipal";
   1370  }
   1371  if (mTriggeringSandboxFlags != aOriginalState->mTriggeringSandboxFlags) {
   1372    return "TriggeringSandboxFlags";
   1373  }
   1374  if (mTriggeringRemoteType != aOriginalState->mTriggeringRemoteType) {
   1375    return "TriggeringRemoteType";
   1376  }
   1377 
   1378  if (mOriginalURIString != aOriginalState->mOriginalURIString) {
   1379    return "OriginalURIString";
   1380  }
   1381 
   1382  if (mRemoteTypeOverride != aOriginalState->mRemoteTypeOverride) {
   1383    return "RemoteTypeOverride";
   1384  }
   1385 
   1386  if (mSourceBrowsingContext.ContextId() !=
   1387      aOriginalState->mSourceBrowsingContext.ContextId()) {
   1388    return "SourceBrowsingContext";
   1389  }
   1390 
   1391  // FIXME: Consider calculating less information in the target process so that
   1392  // we can validate more properties more easily.
   1393  // FIXME: Identify what other flags will not change when sent through a
   1394  // content process.
   1395 
   1396  return nullptr;
   1397 }
   1398 
   1399 DocShellLoadStateInit nsDocShellLoadState::Serialize(
   1400    mozilla::ipc::IProtocol* aActor) {
   1401  MOZ_ASSERT(aActor);
   1402  DocShellLoadStateInit loadState;
   1403  loadState.ResultPrincipalURI() = mResultPrincipalURI;
   1404  loadState.ResultPrincipalURIIsSome() = mResultPrincipalURIIsSome;
   1405  loadState.KeepResultPrincipalURIIfSet() = mKeepResultPrincipalURIIfSet;
   1406  loadState.LoadReplace() = mLoadReplace;
   1407  loadState.InheritPrincipal() = mInheritPrincipal;
   1408  loadState.PrincipalIsExplicit() = mPrincipalIsExplicit;
   1409  loadState.NotifiedBeforeUnloadListeners() = mNotifiedBeforeUnloadListeners;
   1410  loadState.ForceAllowDataURI() = mForceAllowDataURI;
   1411  loadState.IsExemptFromHTTPSFirstMode() = mIsExemptFromHTTPSFirstMode;
   1412  loadState.OriginalFrameSrc() = mOriginalFrameSrc;
   1413  loadState.ShouldCheckForRecursion() = mShouldCheckForRecursion;
   1414  loadState.IsFormSubmission() = mIsFormSubmission;
   1415  loadState.NeedsCompletelyLoadedDocument() = mNeedsCompletelyLoadedDocument;
   1416  loadState.HistoryBehavior() = mHistoryBehavior;
   1417  loadState.LoadType() = mLoadType;
   1418  loadState.userNavigationInvolvement() = mUserNavigationInvolvement;
   1419  loadState.Target() = mTarget;
   1420  loadState.TargetBrowsingContext() = mTargetBrowsingContext;
   1421  loadState.LoadFlags() = mLoadFlags;
   1422  loadState.InternalLoadFlags() = mInternalLoadFlags;
   1423  loadState.FirstParty() = mFirstParty;
   1424  loadState.HasValidUserGestureActivation() = mHasValidUserGestureActivation;
   1425  loadState.TextDirectiveUserActivation() = mTextDirectiveUserActivation;
   1426  loadState.AllowFocusMove() = mAllowFocusMove;
   1427  loadState.TypeHint() = mTypeHint;
   1428  loadState.FileName() = mFileName;
   1429  loadState.IsFromProcessingFrameAttributes() =
   1430      mIsFromProcessingFrameAttributes;
   1431  loadState.URI() = mURI;
   1432  loadState.OriginalURI() = mOriginalURI;
   1433  loadState.SourceBrowsingContext() = mSourceBrowsingContext;
   1434  loadState.BaseURI() = mBaseURI;
   1435  loadState.TriggeringPrincipal() = mTriggeringPrincipal;
   1436  loadState.PrincipalToInherit() = mPrincipalToInherit;
   1437  loadState.PartitionedPrincipalToInherit() = mPartitionedPrincipalToInherit;
   1438  loadState.TriggeringSandboxFlags() = mTriggeringSandboxFlags;
   1439  loadState.TriggeringWindowId() = mTriggeringWindowId;
   1440  loadState.TriggeringStorageAccess() = mTriggeringStorageAccess;
   1441  loadState.TriggeringClassificationFlags() = mTriggeringClassificationFlags;
   1442  loadState.TriggeringRemoteType() = mTriggeringRemoteType;
   1443  loadState.SchemelessInput() = mSchemelessInput;
   1444  loadState.HttpsUpgradeTelemetry() = mHttpsUpgradeTelemetry;
   1445  loadState.PolicyContainer() = mPolicyContainer;
   1446  loadState.OriginalURIString() = mOriginalURIString;
   1447  loadState.CancelContentJSEpoch() = mCancelContentJSEpoch;
   1448  loadState.ReferrerInfo() = mReferrerInfo;
   1449  loadState.PostDataStream() = mPostDataStream;
   1450  loadState.HeadersStream() = mHeadersStream;
   1451  loadState.SrcdocData() = mSrcdocData;
   1452  loadState.ResultPrincipalURI() = mResultPrincipalURI;
   1453  loadState.LoadIdentifier() = mLoadIdentifier;
   1454  loadState.ChannelInitialized() = mChannelInitialized;
   1455  loadState.IsMetaRefresh() = mIsMetaRefresh;
   1456  loadState.forceMediaDocument() = mForceMediaDocument;
   1457  if (mLoadingSessionHistoryInfo) {
   1458    loadState.loadingSessionHistoryInfo().emplace(*mLoadingSessionHistoryInfo);
   1459  }
   1460  loadState.UnstrippedURI() = mUnstrippedURI;
   1461  loadState.RemoteTypeOverride() = mRemoteTypeOverride;
   1462  loadState.IsCaptivePortalTab() = mIsCaptivePortalTab;
   1463  loadState.IsInitialAboutBlankHandlingProhibited() =
   1464      mIsInitialAboutBlankHandlingProhibited;
   1465 
   1466  if (mNavigationAPIState) {
   1467    loadState.NavigationAPIState().emplace();
   1468    DebugOnly<bool> success = mNavigationAPIState->BuildClonedMessageData(
   1469        *loadState.NavigationAPIState());
   1470    MOZ_ASSERT(success);
   1471  }
   1472 
   1473  if (XRE_IsParentProcess()) {
   1474    mozilla::ipc::IToplevelProtocol* top = aActor->ToplevelProtocol();
   1475    MOZ_RELEASE_ASSERT(top &&
   1476                           top->GetProtocolId() ==
   1477                               mozilla::ipc::ProtocolId::PContentMsgStart &&
   1478                           top->GetSide() == mozilla::ipc::ParentSide,
   1479                       "nsDocShellLoadState must be sent over PContent");
   1480    ContentParent* cp = static_cast<ContentParent*>(top);
   1481    cp->StorePendingLoadState(this);
   1482  }
   1483 
   1484  return loadState;
   1485 }
   1486 
   1487 nsIURI* nsDocShellLoadState::GetUnstrippedURI() const { return mUnstrippedURI; }
   1488 
   1489 void nsDocShellLoadState::SetUnstrippedURI(nsIURI* aUnstrippedURI) {
   1490  mUnstrippedURI = aUnstrippedURI;
   1491 }
   1492 
   1493 void nsDocShellLoadState::SetSourceElement(mozilla::dom::Element* aElement) {
   1494  mSourceElement = do_GetWeakReference(aElement);
   1495 }
   1496 already_AddRefed<Element> nsDocShellLoadState::GetSourceElement() const {
   1497  nsCOMPtr<Element> element = do_QueryReferent(mSourceElement);
   1498  return element.forget();
   1499 }
   1500 
   1501 nsIStructuredCloneContainer* nsDocShellLoadState::GetNavigationAPIState()
   1502    const {
   1503  return mNavigationAPIState;
   1504 }
   1505 
   1506 void nsDocShellLoadState::SetNavigationAPIState(
   1507    nsIStructuredCloneContainer* aNavigationAPIState) {
   1508  mNavigationAPIState =
   1509      static_cast<nsStructuredCloneContainer*>(aNavigationAPIState);
   1510 }
   1511 
   1512 NavigationAPIMethodTracker* nsDocShellLoadState::GetNavigationAPIMethodTracker()
   1513    const {
   1514  return mNavigationAPIMethodTracker;
   1515 }
   1516 
   1517 void nsDocShellLoadState::SetNavigationAPIMethodTracker(
   1518    NavigationAPIMethodTracker* aTracker) {
   1519  mNavigationAPIMethodTracker = aTracker;
   1520 }
   1521 
   1522 NavigationType nsDocShellLoadState::GetNavigationType() const {
   1523  return NavigationUtils::NavigationTypeFromLoadType(LoadType())
   1524      .valueOr(NavigationType::Push);
   1525 }
   1526 
   1527 mozilla::dom::FormData* nsDocShellLoadState::GetFormDataEntryList() {
   1528  return mFormDataEntryList;
   1529 }
   1530 
   1531 void nsDocShellLoadState::SetFormDataEntryList(
   1532    mozilla::dom::FormData* aFormDataEntryList) {
   1533  mFormDataEntryList = aFormDataEntryList;
   1534 }
   1535 
   1536 uint32_t nsDocShellLoadState::GetAppLinkLaunchType() const {
   1537  return mAppLinkLaunchType;
   1538 }
   1539 
   1540 void nsDocShellLoadState::SetAppLinkLaunchType(uint32_t aAppLinkLaunchType) {
   1541  mAppLinkLaunchType = aAppLinkLaunchType;
   1542 }
   1543 
   1544 bool nsDocShellLoadState::GetIsCaptivePortalTab() const {
   1545  return mIsCaptivePortalTab;
   1546 }
   1547 
   1548 void nsDocShellLoadState::SetIsCaptivePortalTab(bool aIsCaptivePortalTab) {
   1549  mIsCaptivePortalTab = aIsCaptivePortalTab;
   1550 }