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/. */
7 #include "nsDocShellLoadState.h"
8 #include "nsIDocShell.h"
9 #include "nsDocShell.h"
10 #include "nsIProtocolHandler.h"
11 #include "nsISHEntry.h"
12 #include "nsIURIFixup.h"
13 #include "nsIWebNavigation.h"
14 #include "nsIChannel.h"
15 #include "nsIURLQueryStringStripper.h"
16 #include "nsIXULRuntime.h"
17 #include "nsNetUtil.h"
18 #include "nsQueryObject.h"
19 #include "ReferrerInfo.h"
20 #include "mozilla/BasePrincipal.h"
21 #include "mozilla/ClearOnShutdown.h"
22 #include "mozilla/Components.h"
23 #include "mozilla/dom/BrowsingContext.h"
24 #include "mozilla/dom/ContentChild.h"
25 #include "mozilla/dom/ContentParent.h"
26 #include "mozilla/dom/LoadURIOptionsBinding.h"
27 #include "mozilla/StaticPrefs_browser.h"
28 #include "mozilla/StaticPrefs_fission.h"
29 #include "mozilla/Telemetry.h"
31 #include "mozilla/OriginAttributes.h"
32 #include "mozilla/NullPrincipal.h"
33 #include "mozilla/StaticPtr.h"
35 #include "mozilla/dom/PContent.h"
37 using namespace mozilla
;
38 using namespace mozilla::dom
;
40 // Global reference to the URI fixup service.
41 static mozilla::StaticRefPtr
<nsIURIFixup
> sURIFixup
;
43 nsDocShellLoadState::nsDocShellLoadState(nsIURI
* aURI
)
44 : nsDocShellLoadState(aURI
, nsContentUtils::GenerateLoadIdentifier()) {}
46 nsDocShellLoadState::nsDocShellLoadState(
47 const DocShellLoadStateInit
& aLoadState
, mozilla::ipc::IProtocol
* aActor
,
49 : mNotifiedBeforeUnloadListeners(false),
50 mLoadIdentifier(aLoadState
.LoadIdentifier()) {
51 // If we return early, we failed to read in the data.
52 *aReadSuccess
= false;
53 if (!aLoadState
.URI()) {
54 MOZ_ASSERT_UNREACHABLE("Cannot create a LoadState with a null URI!");
58 mResultPrincipalURI
= aLoadState
.ResultPrincipalURI();
59 mResultPrincipalURIIsSome
= aLoadState
.ResultPrincipalURIIsSome();
60 mKeepResultPrincipalURIIfSet
= aLoadState
.KeepResultPrincipalURIIfSet();
61 mLoadReplace
= aLoadState
.LoadReplace();
62 mInheritPrincipal
= aLoadState
.InheritPrincipal();
63 mPrincipalIsExplicit
= aLoadState
.PrincipalIsExplicit();
64 mForceAllowDataURI
= aLoadState
.ForceAllowDataURI();
65 mIsExemptFromHTTPSOnlyMode
= aLoadState
.IsExemptFromHTTPSOnlyMode();
66 mOriginalFrameSrc
= aLoadState
.OriginalFrameSrc();
67 mIsFormSubmission
= aLoadState
.IsFormSubmission();
68 mLoadType
= aLoadState
.LoadType();
69 mTarget
= aLoadState
.Target();
70 mTargetBrowsingContext
= aLoadState
.TargetBrowsingContext();
71 mLoadFlags
= aLoadState
.LoadFlags();
72 mInternalLoadFlags
= aLoadState
.InternalLoadFlags();
73 mFirstParty
= aLoadState
.FirstParty();
74 mHasValidUserGestureActivation
= aLoadState
.HasValidUserGestureActivation();
75 mAllowFocusMove
= aLoadState
.AllowFocusMove();
76 mTypeHint
= aLoadState
.TypeHint();
77 mFileName
= aLoadState
.FileName();
78 mIsFromProcessingFrameAttributes
=
79 aLoadState
.IsFromProcessingFrameAttributes();
80 mReferrerInfo
= aLoadState
.ReferrerInfo();
81 mURI
= aLoadState
.URI();
82 mOriginalURI
= aLoadState
.OriginalURI();
83 mSourceBrowsingContext
= aLoadState
.SourceBrowsingContext();
84 mBaseURI
= aLoadState
.BaseURI();
85 mTriggeringPrincipal
= aLoadState
.TriggeringPrincipal();
86 mPrincipalToInherit
= aLoadState
.PrincipalToInherit();
87 mPartitionedPrincipalToInherit
= aLoadState
.PartitionedPrincipalToInherit();
88 mTriggeringSandboxFlags
= aLoadState
.TriggeringSandboxFlags();
89 mTriggeringRemoteType
= aLoadState
.TriggeringRemoteType();
90 mCsp
= aLoadState
.Csp();
91 mOriginalURIString
= aLoadState
.OriginalURIString();
92 mCancelContentJSEpoch
= aLoadState
.CancelContentJSEpoch();
93 mPostDataStream
= aLoadState
.PostDataStream();
94 mHeadersStream
= aLoadState
.HeadersStream();
95 mSrcdocData
= aLoadState
.SrcdocData();
96 mChannelInitialized
= aLoadState
.ChannelInitialized();
97 mIsMetaRefresh
= aLoadState
.IsMetaRefresh();
98 if (aLoadState
.loadingSessionHistoryInfo().isSome()) {
99 mLoadingSessionHistoryInfo
= MakeUnique
<LoadingSessionHistoryInfo
>(
100 aLoadState
.loadingSessionHistoryInfo().ref());
102 mUnstrippedURI
= aLoadState
.UnstrippedURI();
103 mRemoteTypeOverride
= aLoadState
.RemoteTypeOverride();
105 // We know this was created remotely, as we just received it over IPC.
106 mWasCreatedRemotely
= true;
108 // If we're in the parent process, potentially validate against a LoadState
109 // which we sent to the source content process.
110 if (XRE_IsParentProcess()) {
111 mozilla::ipc::IToplevelProtocol
* top
= aActor
->ToplevelProtocol();
113 top
->GetProtocolId() != mozilla::ipc::ProtocolId::PContentMsgStart
||
114 top
->GetSide() != mozilla::ipc::ParentSide
) {
115 aActor
->FatalError("nsDocShellLoadState must be received over PContent");
118 ContentParent
* cp
= static_cast<ContentParent
*>(top
);
120 // If this load was sent down to the content process as a navigation
121 // request, ensure it still matches the one we sent down.
122 if (RefPtr
<nsDocShellLoadState
> originalState
=
123 cp
->TakePendingLoadStateForId(mLoadIdentifier
)) {
124 if (const char* mismatch
= ValidateWithOriginalState(originalState
)) {
127 "nsDocShellLoadState %s changed while in content process",
132 } else if (mTriggeringRemoteType
!= cp
->GetRemoteType()) {
133 // If we don't have a previous load to compare to, the content process
134 // must be the triggering process.
136 "nsDocShellLoadState with invalid triggering remote type");
141 // We successfully read in the data - return a success value.
142 *aReadSuccess
= true;
145 nsDocShellLoadState::nsDocShellLoadState(const nsDocShellLoadState
& aOther
)
146 : mReferrerInfo(aOther
.mReferrerInfo
),
148 mOriginalURI(aOther
.mOriginalURI
),
149 mResultPrincipalURI(aOther
.mResultPrincipalURI
),
150 mResultPrincipalURIIsSome(aOther
.mResultPrincipalURIIsSome
),
151 mTriggeringPrincipal(aOther
.mTriggeringPrincipal
),
152 mTriggeringSandboxFlags(aOther
.mTriggeringSandboxFlags
),
154 mKeepResultPrincipalURIIfSet(aOther
.mKeepResultPrincipalURIIfSet
),
155 mLoadReplace(aOther
.mLoadReplace
),
156 mInheritPrincipal(aOther
.mInheritPrincipal
),
157 mPrincipalIsExplicit(aOther
.mPrincipalIsExplicit
),
158 mNotifiedBeforeUnloadListeners(aOther
.mNotifiedBeforeUnloadListeners
),
159 mPrincipalToInherit(aOther
.mPrincipalToInherit
),
160 mPartitionedPrincipalToInherit(aOther
.mPartitionedPrincipalToInherit
),
161 mForceAllowDataURI(aOther
.mForceAllowDataURI
),
162 mIsExemptFromHTTPSOnlyMode(aOther
.mIsExemptFromHTTPSOnlyMode
),
163 mOriginalFrameSrc(aOther
.mOriginalFrameSrc
),
164 mIsFormSubmission(aOther
.mIsFormSubmission
),
165 mLoadType(aOther
.mLoadType
),
166 mSHEntry(aOther
.mSHEntry
),
167 mTarget(aOther
.mTarget
),
168 mTargetBrowsingContext(aOther
.mTargetBrowsingContext
),
169 mPostDataStream(aOther
.mPostDataStream
),
170 mHeadersStream(aOther
.mHeadersStream
),
171 mSrcdocData(aOther
.mSrcdocData
),
172 mSourceBrowsingContext(aOther
.mSourceBrowsingContext
),
173 mBaseURI(aOther
.mBaseURI
),
174 mLoadFlags(aOther
.mLoadFlags
),
175 mInternalLoadFlags(aOther
.mInternalLoadFlags
),
176 mFirstParty(aOther
.mFirstParty
),
177 mHasValidUserGestureActivation(aOther
.mHasValidUserGestureActivation
),
178 mAllowFocusMove(aOther
.mAllowFocusMove
),
179 mTypeHint(aOther
.mTypeHint
),
180 mFileName(aOther
.mFileName
),
181 mIsFromProcessingFrameAttributes(aOther
.mIsFromProcessingFrameAttributes
),
182 mPendingRedirectedChannel(aOther
.mPendingRedirectedChannel
),
183 mOriginalURIString(aOther
.mOriginalURIString
),
184 mCancelContentJSEpoch(aOther
.mCancelContentJSEpoch
),
185 mLoadIdentifier(aOther
.mLoadIdentifier
),
186 mChannelInitialized(aOther
.mChannelInitialized
),
187 mIsMetaRefresh(aOther
.mIsMetaRefresh
),
188 mWasCreatedRemotely(aOther
.mWasCreatedRemotely
),
189 mUnstrippedURI(aOther
.mUnstrippedURI
),
190 mRemoteTypeOverride(aOther
.mRemoteTypeOverride
),
191 mTriggeringRemoteType(aOther
.mTriggeringRemoteType
) {
192 MOZ_DIAGNOSTIC_ASSERT(
193 XRE_IsParentProcess(),
194 "Cloning a nsDocShellLoadState with the same load identifier is only "
195 "allowed in the parent process, as it could break triggering remote type "
196 "tracking in content.");
197 if (aOther
.mLoadingSessionHistoryInfo
) {
198 mLoadingSessionHistoryInfo
= MakeUnique
<LoadingSessionHistoryInfo
>(
199 *aOther
.mLoadingSessionHistoryInfo
);
203 nsDocShellLoadState::nsDocShellLoadState(nsIURI
* aURI
, uint64_t aLoadIdentifier
)
205 mResultPrincipalURIIsSome(false),
206 mTriggeringSandboxFlags(0),
207 mKeepResultPrincipalURIIfSet(false),
209 mInheritPrincipal(false),
210 mPrincipalIsExplicit(false),
211 mNotifiedBeforeUnloadListeners(false),
212 mForceAllowDataURI(false),
213 mIsExemptFromHTTPSOnlyMode(false),
214 mOriginalFrameSrc(false),
215 mIsFormSubmission(false),
216 mLoadType(LOAD_NORMAL
),
218 mSrcdocData(VoidString()),
220 mInternalLoadFlags(0),
222 mHasValidUserGestureActivation(false),
223 mAllowFocusMove(false),
224 mTypeHint(VoidCString()),
225 mFileName(VoidString()),
226 mIsFromProcessingFrameAttributes(false),
227 mLoadIdentifier(aLoadIdentifier
),
228 mChannelInitialized(false),
229 mIsMetaRefresh(false),
230 mWasCreatedRemotely(false),
231 mTriggeringRemoteType(XRE_IsContentProcess()
232 ? ContentChild::GetSingleton()->GetRemoteType()
234 MOZ_ASSERT(aURI
, "Cannot create a LoadState with a null URI!");
237 nsDocShellLoadState::~nsDocShellLoadState() {
238 if (mWasCreatedRemotely
&& XRE_IsContentProcess()) {
239 ContentChild::GetSingleton()->SendCleanupPendingLoadState(mLoadIdentifier
);
243 nsresult
nsDocShellLoadState::CreateFromPendingChannel(
244 nsIChannel
* aPendingChannel
, uint64_t aLoadIdentifier
,
245 uint64_t aRegistrarId
, nsDocShellLoadState
** aResult
) {
246 // Create the nsDocShellLoadState object with default state pulled from the
247 // passed-in channel.
248 nsCOMPtr
<nsIURI
> uri
;
249 nsresult rv
= aPendingChannel
->GetURI(getter_AddRefs(uri
));
250 if (NS_WARN_IF(NS_FAILED(rv
))) {
254 RefPtr
<nsDocShellLoadState
> loadState
=
255 new nsDocShellLoadState(uri
, aLoadIdentifier
);
256 loadState
->mPendingRedirectedChannel
= aPendingChannel
;
257 loadState
->mChannelRegistrarId
= aRegistrarId
;
259 // Pull relevant state from the channel, and store it on the
260 // nsDocShellLoadState.
261 nsCOMPtr
<nsIURI
> originalUri
;
262 rv
= aPendingChannel
->GetOriginalURI(getter_AddRefs(originalUri
));
263 if (NS_WARN_IF(NS_FAILED(rv
))) {
266 loadState
->SetOriginalURI(originalUri
);
268 nsCOMPtr
<nsILoadInfo
> loadInfo
= aPendingChannel
->LoadInfo();
269 loadState
->SetTriggeringPrincipal(loadInfo
->TriggeringPrincipal());
271 // Return the newly created loadState.
272 loadState
.forget(aResult
);
276 static uint32_t WebNavigationFlagsToFixupFlags(nsIURI
* aURI
,
277 const nsACString
& aURIString
,
278 uint32_t aNavigationFlags
) {
280 aNavigationFlags
&= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
;
282 uint32_t fixupFlags
= nsIURIFixup::FIXUP_FLAG_NONE
;
283 if (aNavigationFlags
& nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
) {
284 fixupFlags
|= nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
;
286 if (aNavigationFlags
& nsIWebNavigation::LOAD_FLAGS_FIXUP_SCHEME_TYPOS
) {
287 fixupFlags
|= nsIURIFixup::FIXUP_FLAG_FIX_SCHEME_TYPOS
;
292 nsresult
nsDocShellLoadState::CreateFromLoadURIOptions(
293 BrowsingContext
* aBrowsingContext
, const nsAString
& aURI
,
294 const LoadURIOptions
& aLoadURIOptions
, nsDocShellLoadState
** aResult
) {
295 uint32_t loadFlags
= aLoadURIOptions
.mLoadFlags
;
298 (loadFlags
& nsDocShell::INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS
) == 0,
301 nsCOMPtr
<nsIURI
> uri
;
304 NS_ConvertUTF16toUTF8
uriString(aURI
);
305 // Cleanup the empty spaces that might be on each end.
307 // Eliminate embedded newlines, which single-line text fields now allow:
308 uriString
.StripCRLF();
309 NS_ENSURE_TRUE(!uriString
.IsEmpty(), NS_ERROR_FAILURE
);
311 // Just create a URI and see what happens...
312 rv
= NS_NewURI(getter_AddRefs(uri
), uriString
);
314 if (NS_SUCCEEDED(rv
) && uri
&&
315 (uri
->SchemeIs("about") || uri
->SchemeIs("chrome"))) {
316 // Avoid third party fixup as a performance optimization.
317 loadFlags
&= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
;
319 } else if (!sURIFixup
&& !XRE_IsContentProcess()) {
320 nsCOMPtr
<nsIURIFixup
> uriFixup
= components::URIFixup::Service();
322 sURIFixup
= uriFixup
;
323 ClearOnShutdown(&sURIFixup
);
329 nsAutoString searchProvider
, keyword
;
330 RefPtr
<nsIInputStream
> fixupStream
;
332 uint32_t fixupFlags
=
333 WebNavigationFlagsToFixupFlags(uri
, uriString
, loadFlags
);
335 // If we don't allow keyword lookups for this URL string, make sure to
336 // update loadFlags to indicate this as well.
337 if (!(fixupFlags
& nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
)) {
338 loadFlags
&= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
;
340 // Ensure URIFixup will use the right search engine in Private Browsing.
341 if (aBrowsingContext
->UsePrivateBrowsing()) {
342 fixupFlags
|= nsIURIFixup::FIXUP_FLAG_PRIVATE_CONTEXT
;
345 if (!XRE_IsContentProcess()) {
346 nsCOMPtr
<nsIURIFixupInfo
> fixupInfo
;
347 sURIFixup
->GetFixupURIInfo(uriString
, fixupFlags
,
348 getter_AddRefs(fixupInfo
));
350 // We could fix the uri, clear NS_ERROR_MALFORMED_URI.
352 fixupInfo
->GetPreferredURI(getter_AddRefs(uri
));
353 fixupInfo
->SetConsumer(aBrowsingContext
);
354 fixupInfo
->GetKeywordProviderName(searchProvider
);
355 fixupInfo
->GetKeywordAsSent(keyword
);
356 // GetFixupURIInfo only returns a post data stream if it succeeded
357 // and changed the URI, in which case we should override the
358 // passed-in post data by passing this as an override arg to
359 // our internal method.
360 fixupInfo
->GetPostData(getter_AddRefs(fixupStream
));
363 loadFlags
& nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
) {
364 nsCOMPtr
<nsIObserverService
> serv
= services::GetObserverService();
366 serv
->NotifyObservers(fixupInfo
, "keyword-uri-fixup",
367 PromiseFlatString(aURI
).get());
370 nsDocShell::MaybeNotifyKeywordSearchLoading(searchProvider
, keyword
);
375 if (rv
== NS_ERROR_MALFORMED_URI
) {
380 if (NS_FAILED(rv
) || !uri
) {
381 return NS_ERROR_FAILURE
;
384 RefPtr
<nsDocShellLoadState
> loadState
;
385 rv
= CreateFromLoadURIOptions(
386 aBrowsingContext
, uri
, aLoadURIOptions
, loadFlags
,
387 fixupStream
? fixupStream
: aLoadURIOptions
.mPostData
,
388 getter_AddRefs(loadState
));
389 NS_ENSURE_SUCCESS(rv
, rv
);
390 loadState
->SetOriginalURIString(uriString
);
391 loadState
.forget(aResult
);
395 nsresult
nsDocShellLoadState::CreateFromLoadURIOptions(
396 BrowsingContext
* aBrowsingContext
, nsIURI
* aURI
,
397 const LoadURIOptions
& aLoadURIOptions
, nsDocShellLoadState
** aResult
) {
398 return CreateFromLoadURIOptions(aBrowsingContext
, aURI
, aLoadURIOptions
,
399 aLoadURIOptions
.mLoadFlags
,
400 aLoadURIOptions
.mPostData
, aResult
);
403 nsresult
nsDocShellLoadState::CreateFromLoadURIOptions(
404 BrowsingContext
* aBrowsingContext
, nsIURI
* aURI
,
405 const LoadURIOptions
& aLoadURIOptions
, uint32_t aLoadFlagsOverride
,
406 nsIInputStream
* aPostDataOverride
, nsDocShellLoadState
** aResult
) {
408 uint32_t loadFlags
= aLoadFlagsOverride
;
409 RefPtr
<nsIInputStream
> postData
= aPostDataOverride
;
412 rv
= postData
->Available(&available
);
413 NS_ENSURE_SUCCESS(rv
, rv
);
414 if (available
== 0) {
415 return NS_ERROR_INVALID_ARG
;
419 if (aLoadURIOptions
.mHeaders
) {
420 rv
= aLoadURIOptions
.mHeaders
->Available(&available
);
421 NS_ENSURE_SUCCESS(rv
, rv
);
422 if (available
== 0) {
423 return NS_ERROR_INVALID_ARG
;
427 bool forceAllowDataURI
=
428 loadFlags
& nsIWebNavigation::LOAD_FLAGS_FORCE_ALLOW_DATA_URI
;
430 // Don't pass certain flags that aren't needed and end up confusing
431 // ConvertLoadTypeToDocShellInfoLoadType. We do need to ensure that they are
432 // passed to LoadURI though, since it uses them.
433 uint32_t extraFlags
= (loadFlags
& EXTRA_LOAD_FLAGS
);
434 loadFlags
&= ~EXTRA_LOAD_FLAGS
;
436 RefPtr
<nsDocShellLoadState
> loadState
= new nsDocShellLoadState(aURI
);
437 loadState
->SetReferrerInfo(aLoadURIOptions
.mReferrerInfo
);
439 loadState
->SetLoadType(MAKE_LOAD_TYPE(LOAD_NORMAL
, loadFlags
));
441 loadState
->SetLoadFlags(extraFlags
);
442 loadState
->SetFirstParty(true);
443 loadState
->SetHasValidUserGestureActivation(
444 aLoadURIOptions
.mHasValidUserGestureActivation
);
445 loadState
->SetTriggeringSandboxFlags(aLoadURIOptions
.mTriggeringSandboxFlags
);
446 loadState
->SetPostDataStream(postData
);
447 loadState
->SetHeadersStream(aLoadURIOptions
.mHeaders
);
448 loadState
->SetBaseURI(aLoadURIOptions
.mBaseURI
);
449 loadState
->SetTriggeringPrincipal(aLoadURIOptions
.mTriggeringPrincipal
);
450 loadState
->SetCsp(aLoadURIOptions
.mCsp
);
451 loadState
->SetForceAllowDataURI(forceAllowDataURI
);
452 if (aLoadURIOptions
.mCancelContentJSEpoch
) {
453 loadState
->SetCancelContentJSEpoch(aLoadURIOptions
.mCancelContentJSEpoch
);
456 if (aLoadURIOptions
.mTriggeringRemoteType
.WasPassed()) {
457 if (XRE_IsParentProcess()) {
458 loadState
->SetTriggeringRemoteType(
459 aLoadURIOptions
.mTriggeringRemoteType
.Value());
460 } else if (ContentChild::GetSingleton()->GetRemoteType() !=
461 aLoadURIOptions
.mTriggeringRemoteType
.Value()) {
462 NS_WARNING("Invalid TriggeringRemoteType from LoadURIOptions in content");
463 return NS_ERROR_INVALID_ARG
;
467 if (aLoadURIOptions
.mRemoteTypeOverride
.WasPassed()) {
468 loadState
->SetRemoteTypeOverride(
469 aLoadURIOptions
.mRemoteTypeOverride
.Value());
472 loadState
.forget(aResult
);
476 nsIReferrerInfo
* nsDocShellLoadState::GetReferrerInfo() const {
477 return mReferrerInfo
;
480 void nsDocShellLoadState::SetReferrerInfo(nsIReferrerInfo
* aReferrerInfo
) {
481 mReferrerInfo
= aReferrerInfo
;
484 nsIURI
* nsDocShellLoadState::URI() const { return mURI
; }
486 void nsDocShellLoadState::SetURI(nsIURI
* aURI
) { mURI
= aURI
; }
488 nsIURI
* nsDocShellLoadState::OriginalURI() const { return mOriginalURI
; }
490 void nsDocShellLoadState::SetOriginalURI(nsIURI
* aOriginalURI
) {
491 mOriginalURI
= aOriginalURI
;
494 nsIURI
* nsDocShellLoadState::ResultPrincipalURI() const {
495 return mResultPrincipalURI
;
498 void nsDocShellLoadState::SetResultPrincipalURI(nsIURI
* aResultPrincipalURI
) {
499 mResultPrincipalURI
= aResultPrincipalURI
;
502 bool nsDocShellLoadState::ResultPrincipalURIIsSome() const {
503 return mResultPrincipalURIIsSome
;
506 void nsDocShellLoadState::SetResultPrincipalURIIsSome(bool aIsSome
) {
507 mResultPrincipalURIIsSome
= aIsSome
;
510 bool nsDocShellLoadState::KeepResultPrincipalURIIfSet() const {
511 return mKeepResultPrincipalURIIfSet
;
514 void nsDocShellLoadState::SetKeepResultPrincipalURIIfSet(bool aKeep
) {
515 mKeepResultPrincipalURIIfSet
= aKeep
;
518 bool nsDocShellLoadState::LoadReplace() const { return mLoadReplace
; }
520 void nsDocShellLoadState::SetLoadReplace(bool aLoadReplace
) {
521 mLoadReplace
= aLoadReplace
;
524 nsIPrincipal
* nsDocShellLoadState::TriggeringPrincipal() const {
525 return mTriggeringPrincipal
;
528 void nsDocShellLoadState::SetTriggeringPrincipal(
529 nsIPrincipal
* aTriggeringPrincipal
) {
530 mTriggeringPrincipal
= aTriggeringPrincipal
;
533 nsIPrincipal
* nsDocShellLoadState::PrincipalToInherit() const {
534 return mPrincipalToInherit
;
537 void nsDocShellLoadState::SetPrincipalToInherit(
538 nsIPrincipal
* aPrincipalToInherit
) {
539 mPrincipalToInherit
= aPrincipalToInherit
;
542 nsIPrincipal
* nsDocShellLoadState::PartitionedPrincipalToInherit() const {
543 return mPartitionedPrincipalToInherit
;
546 void nsDocShellLoadState::SetPartitionedPrincipalToInherit(
547 nsIPrincipal
* aPartitionedPrincipalToInherit
) {
548 mPartitionedPrincipalToInherit
= aPartitionedPrincipalToInherit
;
551 void nsDocShellLoadState::SetCsp(nsIContentSecurityPolicy
* aCsp
) {
555 nsIContentSecurityPolicy
* nsDocShellLoadState::Csp() const { return mCsp
; }
557 void nsDocShellLoadState::SetTriggeringSandboxFlags(uint32_t flags
) {
558 mTriggeringSandboxFlags
= flags
;
561 uint32_t nsDocShellLoadState::TriggeringSandboxFlags() const {
562 return mTriggeringSandboxFlags
;
565 bool nsDocShellLoadState::InheritPrincipal() const { return mInheritPrincipal
; }
567 void nsDocShellLoadState::SetInheritPrincipal(bool aInheritPrincipal
) {
568 mInheritPrincipal
= aInheritPrincipal
;
571 bool nsDocShellLoadState::PrincipalIsExplicit() const {
572 return mPrincipalIsExplicit
;
575 void nsDocShellLoadState::SetPrincipalIsExplicit(bool aPrincipalIsExplicit
) {
576 mPrincipalIsExplicit
= aPrincipalIsExplicit
;
579 bool nsDocShellLoadState::NotifiedBeforeUnloadListeners() const {
580 return mNotifiedBeforeUnloadListeners
;
583 void nsDocShellLoadState::SetNotifiedBeforeUnloadListeners(
584 bool aNotifiedBeforeUnloadListeners
) {
585 mNotifiedBeforeUnloadListeners
= aNotifiedBeforeUnloadListeners
;
588 bool nsDocShellLoadState::ForceAllowDataURI() const {
589 return mForceAllowDataURI
;
592 void nsDocShellLoadState::SetForceAllowDataURI(bool aForceAllowDataURI
) {
593 mForceAllowDataURI
= aForceAllowDataURI
;
596 bool nsDocShellLoadState::IsExemptFromHTTPSOnlyMode() const {
597 return mIsExemptFromHTTPSOnlyMode
;
600 void nsDocShellLoadState::SetIsExemptFromHTTPSOnlyMode(
601 bool aIsExemptFromHTTPSOnlyMode
) {
602 mIsExemptFromHTTPSOnlyMode
= aIsExemptFromHTTPSOnlyMode
;
605 bool nsDocShellLoadState::OriginalFrameSrc() const { return mOriginalFrameSrc
; }
607 void nsDocShellLoadState::SetOriginalFrameSrc(bool aOriginalFrameSrc
) {
608 mOriginalFrameSrc
= aOriginalFrameSrc
;
611 bool nsDocShellLoadState::IsFormSubmission() const { return mIsFormSubmission
; }
613 void nsDocShellLoadState::SetIsFormSubmission(bool aIsFormSubmission
) {
614 mIsFormSubmission
= aIsFormSubmission
;
617 uint32_t nsDocShellLoadState::LoadType() const { return mLoadType
; }
619 void nsDocShellLoadState::SetLoadType(uint32_t aLoadType
) {
620 mLoadType
= aLoadType
;
623 nsISHEntry
* nsDocShellLoadState::SHEntry() const { return mSHEntry
; }
625 void nsDocShellLoadState::SetSHEntry(nsISHEntry
* aSHEntry
) {
627 nsCOMPtr
<SessionHistoryEntry
> she
= do_QueryInterface(aSHEntry
);
629 mLoadingSessionHistoryInfo
= MakeUnique
<LoadingSessionHistoryInfo
>(she
);
631 mLoadingSessionHistoryInfo
= nullptr;
635 void nsDocShellLoadState::SetLoadingSessionHistoryInfo(
636 const mozilla::dom::LoadingSessionHistoryInfo
& aLoadingInfo
) {
637 SetLoadingSessionHistoryInfo(
638 MakeUnique
<mozilla::dom::LoadingSessionHistoryInfo
>(aLoadingInfo
));
641 void nsDocShellLoadState::SetLoadingSessionHistoryInfo(
642 mozilla::UniquePtr
<mozilla::dom::LoadingSessionHistoryInfo
> aLoadingInfo
) {
643 mLoadingSessionHistoryInfo
= std::move(aLoadingInfo
);
646 const mozilla::dom::LoadingSessionHistoryInfo
*
647 nsDocShellLoadState::GetLoadingSessionHistoryInfo() const {
648 return mLoadingSessionHistoryInfo
.get();
651 void nsDocShellLoadState::SetLoadIsFromSessionHistory(
652 int32_t aOffset
, bool aLoadingCurrentEntry
) {
653 if (mLoadingSessionHistoryInfo
) {
654 mLoadingSessionHistoryInfo
->mLoadIsFromSessionHistory
= true;
655 mLoadingSessionHistoryInfo
->mOffset
= aOffset
;
656 mLoadingSessionHistoryInfo
->mLoadingCurrentEntry
= aLoadingCurrentEntry
;
660 void nsDocShellLoadState::ClearLoadIsFromSessionHistory() {
661 if (mLoadingSessionHistoryInfo
) {
662 mLoadingSessionHistoryInfo
->mLoadIsFromSessionHistory
= false;
667 bool nsDocShellLoadState::LoadIsFromSessionHistory() const {
668 return mLoadingSessionHistoryInfo
669 ? mLoadingSessionHistoryInfo
->mLoadIsFromSessionHistory
673 void nsDocShellLoadState::MaybeStripTrackerQueryStrings(
674 BrowsingContext
* aContext
) {
675 MOZ_ASSERT(aContext
);
677 // Return early if the triggering principal doesn't exist. This could happen
678 // when loading a URL by using a browsing context in the Browser Toolbox.
679 if (!TriggeringPrincipal()) {
683 // We don't need to strip for sub frames because the query string has been
684 // stripped in the top-level content. Also, we don't apply stripping if it
685 // is triggered by addons.
687 // Note that we don't need to do the stripping if the channel has been
688 // initialized. This means that this has been loaded speculatively in the
689 // parent process before and the stripping was happening by then.
690 if (GetChannelInitialized() || !aContext
->IsTopContent() ||
691 BasePrincipal::Cast(TriggeringPrincipal())->AddonPolicy()) {
695 // We don't strip the URI if it's the same-site navigation. Note that we will
696 // consider the system principal triggered load as third-party in case the
697 // user copies and pastes a URL which has tracking query parameters or an
698 // loading from external applications, such as clicking a link in an email
700 bool isThirdPartyURI
= false;
701 if (!TriggeringPrincipal()->IsSystemPrincipal() &&
703 TriggeringPrincipal()->IsThirdPartyURI(URI(), &isThirdPartyURI
)) ||
708 Telemetry::AccumulateCategorical(
709 Telemetry::LABELS_QUERY_STRIPPING_COUNT::Navigation
);
711 nsCOMPtr
<nsIURI
> strippedURI
;
714 nsCOMPtr
<nsIURLQueryStringStripper
> queryStripper
=
715 components::URLQueryStringStripper::Service(&rv
);
716 NS_ENSURE_SUCCESS_VOID(rv
);
718 uint32_t numStripped
;
720 queryStripper
->Strip(URI(), aContext
->UsePrivateBrowsing(),
721 getter_AddRefs(strippedURI
), &numStripped
);
723 if (!mUnstrippedURI
) {
724 mUnstrippedURI
= URI();
728 Telemetry::AccumulateCategorical(
729 Telemetry::LABELS_QUERY_STRIPPING_COUNT::StripForNavigation
);
730 Telemetry::Accumulate(Telemetry::QUERY_STRIPPING_PARAM_COUNT
, numStripped
);
734 // Make sure that unstripped URI is the same as URI() but only the query
735 // string could be different.
736 if (mUnstrippedURI
) {
737 nsCOMPtr
<nsIURI
> uri
;
738 Unused
<< queryStripper
->Strip(mUnstrippedURI
,
739 aContext
->UsePrivateBrowsing(),
740 getter_AddRefs(uri
), &numStripped
);
742 Unused
<< URI()->Equals(uri
, &equals
);
748 const nsString
& nsDocShellLoadState::Target() const { return mTarget
; }
750 void nsDocShellLoadState::SetTarget(const nsAString
& aTarget
) {
754 nsIInputStream
* nsDocShellLoadState::PostDataStream() const {
755 return mPostDataStream
;
758 void nsDocShellLoadState::SetPostDataStream(nsIInputStream
* aStream
) {
759 mPostDataStream
= aStream
;
762 nsIInputStream
* nsDocShellLoadState::HeadersStream() const {
763 return mHeadersStream
;
766 void nsDocShellLoadState::SetHeadersStream(nsIInputStream
* aHeadersStream
) {
767 mHeadersStream
= aHeadersStream
;
770 const nsString
& nsDocShellLoadState::SrcdocData() const { return mSrcdocData
; }
772 void nsDocShellLoadState::SetSrcdocData(const nsAString
& aSrcdocData
) {
773 mSrcdocData
= aSrcdocData
;
776 void nsDocShellLoadState::SetSourceBrowsingContext(
777 BrowsingContext
* aSourceBrowsingContext
) {
778 mSourceBrowsingContext
= aSourceBrowsingContext
;
781 void nsDocShellLoadState::SetTargetBrowsingContext(
782 BrowsingContext
* aTargetBrowsingContext
) {
783 mTargetBrowsingContext
= aTargetBrowsingContext
;
786 nsIURI
* nsDocShellLoadState::BaseURI() const { return mBaseURI
; }
788 void nsDocShellLoadState::SetBaseURI(nsIURI
* aBaseURI
) { mBaseURI
= aBaseURI
; }
790 void nsDocShellLoadState::GetMaybeResultPrincipalURI(
791 mozilla::Maybe
<nsCOMPtr
<nsIURI
>>& aRPURI
) const {
792 bool isSome
= ResultPrincipalURIIsSome();
799 nsCOMPtr
<nsIURI
> uri
= ResultPrincipalURI();
800 aRPURI
.emplace(std::move(uri
));
803 void nsDocShellLoadState::SetMaybeResultPrincipalURI(
804 mozilla::Maybe
<nsCOMPtr
<nsIURI
>> const& aRPURI
) {
805 SetResultPrincipalURI(aRPURI
.refOr(nullptr));
806 SetResultPrincipalURIIsSome(aRPURI
.isSome());
809 uint32_t nsDocShellLoadState::LoadFlags() const { return mLoadFlags
; }
811 void nsDocShellLoadState::SetLoadFlags(uint32_t aLoadFlags
) {
812 mLoadFlags
= aLoadFlags
;
815 void nsDocShellLoadState::SetLoadFlag(uint32_t aFlag
) { mLoadFlags
|= aFlag
; }
817 void nsDocShellLoadState::UnsetLoadFlag(uint32_t aFlag
) {
818 mLoadFlags
&= ~aFlag
;
821 bool nsDocShellLoadState::HasLoadFlags(uint32_t aFlags
) {
822 return (mLoadFlags
& aFlags
) == aFlags
;
825 uint32_t nsDocShellLoadState::InternalLoadFlags() const {
826 return mInternalLoadFlags
;
829 void nsDocShellLoadState::SetInternalLoadFlags(uint32_t aLoadFlags
) {
830 mInternalLoadFlags
= aLoadFlags
;
833 void nsDocShellLoadState::SetInternalLoadFlag(uint32_t aFlag
) {
834 mInternalLoadFlags
|= aFlag
;
837 void nsDocShellLoadState::UnsetInternalLoadFlag(uint32_t aFlag
) {
838 mInternalLoadFlags
&= ~aFlag
;
841 bool nsDocShellLoadState::HasInternalLoadFlags(uint32_t aFlags
) {
842 return (mInternalLoadFlags
& aFlags
) == aFlags
;
845 bool nsDocShellLoadState::FirstParty() const { return mFirstParty
; }
847 void nsDocShellLoadState::SetFirstParty(bool aFirstParty
) {
848 mFirstParty
= aFirstParty
;
851 bool nsDocShellLoadState::HasValidUserGestureActivation() const {
852 return mHasValidUserGestureActivation
;
855 void nsDocShellLoadState::SetHasValidUserGestureActivation(
856 bool aHasValidUserGestureActivation
) {
857 mHasValidUserGestureActivation
= aHasValidUserGestureActivation
;
860 const nsCString
& nsDocShellLoadState::TypeHint() const { return mTypeHint
; }
862 void nsDocShellLoadState::SetTypeHint(const nsCString
& aTypeHint
) {
863 mTypeHint
= aTypeHint
;
866 const nsString
& nsDocShellLoadState::FileName() const { return mFileName
; }
868 void nsDocShellLoadState::SetFileName(const nsAString
& aFileName
) {
869 MOZ_DIAGNOSTIC_ASSERT(aFileName
.FindChar(char16_t(0)) == kNotFound
,
870 "The filename should never contain null characters");
871 mFileName
= aFileName
;
874 const nsCString
& nsDocShellLoadState::GetEffectiveTriggeringRemoteType() const {
875 // Consider non-errorpage loads from session history as being triggred by the
876 // parent process, as we'll validate them against the history entry.
878 // NOTE: Keep this check in-sync with the session-history validation check in
879 // `DocumentLoadListener::Open`!
880 if (LoadIsFromSessionHistory() && LoadType() != LOAD_ERROR_PAGE
) {
881 return NOT_REMOTE_TYPE
;
883 return mTriggeringRemoteType
;
886 void nsDocShellLoadState::SetTriggeringRemoteType(
887 const nsACString
& aTriggeringRemoteType
) {
888 MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "only settable in parent");
889 mTriggeringRemoteType
= aTriggeringRemoteType
;
892 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
893 void nsDocShellLoadState::AssertProcessCouldTriggerLoadIfSystem() {
894 // Early check to see if we're trying to start a file URI load with a system
895 // principal within a web content process.
896 // If this assertion fails, the load will fail later during
897 // nsContentSecurityManager checks, however this assertion should happen
898 // closer to whichever caller is triggering the system-principal load.
899 if (mozilla::SessionHistoryInParent() &&
900 TriggeringPrincipal()->IsSystemPrincipal() &&
901 mozilla::dom::IsWebRemoteType(GetEffectiveTriggeringRemoteType())) {
902 bool localFile
= false;
903 if (NS_SUCCEEDED(NS_URIChainHasFlags(
904 URI(), nsIProtocolHandler::URI_IS_LOCAL_FILE
, &localFile
)) &&
906 NS_WARNING(nsPrintfCString("Unexpected system load of file URI (%s) from "
907 "web content process",
908 URI()->GetSpecOrDefault().get())
910 MOZ_CRASH("Unexpected system load of file URI from web content process");
916 nsresult
nsDocShellLoadState::SetupInheritingPrincipal(
917 BrowsingContext::Type aType
,
918 const mozilla::OriginAttributes
& aOriginAttributes
) {
919 // We need a principalToInherit.
921 // If principalIsExplicit is not set there are 4 possibilities:
922 // (1) If the system principal or an expanded principal was passed
923 // in and we're a typeContent docshell, inherit the principal
924 // from the current document instead.
925 // (2) In all other cases when the principal passed in is not null,
926 // use that principal.
927 // (3) If the caller has allowed inheriting from the current document,
928 // or if we're being called from system code (eg chrome JS or pure
929 // C++) then inheritPrincipal should be true and InternalLoad will get
930 // a principal from the current document. If none of these things are
932 // (4) we don't pass a principal into the channel, and a principal will be
933 // created later from the channel's internal data.
935 // If principalIsExplicit *is* set, there are 4 possibilities
936 // (1) If the system principal or an expanded principal was passed in
937 // and we're a typeContent docshell, return an error.
938 // (2) In all other cases when the principal passed in is not null,
939 // use that principal.
940 // (3) If the caller has allowed inheriting from the current document,
941 // then inheritPrincipal should be true and InternalLoad will get
942 // a principal from the current document. If none of these things are
944 // (4) we dont' pass a principal into the channel, and a principal will be
945 // created later from the channel's internal data.
946 mPrincipalToInherit
= mTriggeringPrincipal
;
947 if (mPrincipalToInherit
&& aType
!= BrowsingContext::Type::Chrome
) {
948 if (mPrincipalToInherit
->IsSystemPrincipal()) {
949 if (mPrincipalIsExplicit
) {
950 return NS_ERROR_DOM_SECURITY_ERR
;
952 mPrincipalToInherit
= nullptr;
953 mInheritPrincipal
= true;
954 } else if (nsContentUtils::IsExpandedPrincipal(mPrincipalToInherit
)) {
955 if (mPrincipalIsExplicit
) {
956 return NS_ERROR_DOM_SECURITY_ERR
;
958 // Don't inherit from the current page. Just do the safe thing
959 // and pretend that we were loaded by a nullprincipal.
961 // We didn't inherit OriginAttributes here as ExpandedPrincipal doesn't
962 // have origin attributes.
963 mPrincipalToInherit
= NullPrincipal::Create(aOriginAttributes
);
964 mInheritPrincipal
= false;
968 if (!mPrincipalToInherit
&& !mInheritPrincipal
&& !mPrincipalIsExplicit
) {
969 // See if there's system or chrome JS code running
970 mInheritPrincipal
= nsContentUtils::LegacyIsCallerChromeOrNativeCode();
973 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL
) {
974 mInheritPrincipal
= false;
975 // Create a new null principal URI based on our precursor principal.
976 nsCOMPtr
<nsIURI
> nullPrincipalURI
=
977 NullPrincipal::CreateURI(mPrincipalToInherit
);
978 // If mFirstParty is true and the pref 'privacy.firstparty.isolate' is
979 // enabled, we will set firstPartyDomain on the origin attributes.
980 OriginAttributes
attrs(aOriginAttributes
);
982 attrs
.SetFirstPartyDomain(true, nullPrincipalURI
);
984 mPrincipalToInherit
= NullPrincipal::Create(attrs
, nullPrincipalURI
);
990 nsresult
nsDocShellLoadState::SetupTriggeringPrincipal(
991 const mozilla::OriginAttributes
& aOriginAttributes
) {
992 // If the triggeringPrincipal is not set, we first try to create a principal
993 // from the referrer, since the referrer URI reflects the web origin that
994 // triggered the load. If there is no referrer URI, we fall back to using the
995 // SystemPrincipal. It's safe to assume that no provided triggeringPrincipal
996 // and no referrer simulate a load that was triggered by the system. It's
997 // important to note that this block of code needs to appear *after* the block
998 // where we munge the principalToInherit, because otherwise we would never
999 // enter code blocks checking if the principalToInherit is null and we will
1000 // end up with a wrong inheritPrincipal flag.
1001 if (!mTriggeringPrincipal
) {
1002 if (mReferrerInfo
) {
1003 nsCOMPtr
<nsIURI
> referrer
= mReferrerInfo
->GetOriginalReferrer();
1004 mTriggeringPrincipal
=
1005 BasePrincipal::CreateContentPrincipal(referrer
, aOriginAttributes
);
1007 if (!mTriggeringPrincipal
) {
1008 return NS_ERROR_FAILURE
;
1011 mTriggeringPrincipal
= nsContentUtils::GetSystemPrincipal();
1017 void nsDocShellLoadState::CalculateLoadURIFlags() {
1018 if (mInheritPrincipal
) {
1020 !mPrincipalToInherit
|| !mPrincipalToInherit
->IsSystemPrincipal(),
1021 "Should not inherit SystemPrincipal");
1022 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL
;
1025 if (mReferrerInfo
&& !mReferrerInfo
->GetSendReferrer()) {
1026 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER
;
1028 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
) {
1029 mInternalLoadFlags
|=
1030 nsDocShell::INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
;
1033 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD
) {
1034 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_FIRST_LOAD
;
1037 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_BYPASS_CLASSIFIER
) {
1038 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER
;
1041 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_FORCE_ALLOW_COOKIES
) {
1042 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES
;
1045 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_BYPASS_LOAD_URI_DELEGATE
) {
1046 mInternalLoadFlags
|=
1047 nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_LOAD_URI_DELEGATE
;
1050 if (!mSrcdocData
.IsVoid()) {
1051 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_IS_SRCDOC
;
1054 if (mForceAllowDataURI
) {
1055 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI
;
1058 if (mOriginalFrameSrc
) {
1059 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC
;
1063 nsLoadFlags
nsDocShellLoadState::CalculateChannelLoadFlags(
1064 BrowsingContext
* aBrowsingContext
, Maybe
<bool> aUriModified
,
1065 Maybe
<bool> aIsXFOError
) {
1066 MOZ_ASSERT(aBrowsingContext
);
1068 nsLoadFlags loadFlags
= aBrowsingContext
->GetDefaultLoadFlags();
1071 // tag first party URL loads
1072 loadFlags
|= nsIChannel::LOAD_INITIAL_DOCUMENT_URI
;
1075 const uint32_t loadType
= LoadType();
1077 // These values aren't available for loads initiated in the Parent process.
1078 MOZ_ASSERT_IF(loadType
== LOAD_HISTORY
, aUriModified
.isSome());
1079 MOZ_ASSERT_IF(loadType
== LOAD_ERROR_PAGE
, aIsXFOError
.isSome());
1081 if (loadType
== LOAD_ERROR_PAGE
) {
1082 // Error pages are LOAD_BACKGROUND, unless it's an
1083 // XFO error for which we want an error page to load
1084 // but additionally want the onload() event to fire.
1085 if (!*aIsXFOError
) {
1086 loadFlags
|= nsIChannel::LOAD_BACKGROUND
;
1090 // Mark the channel as being a document URI and allow content sniffing...
1092 nsIChannel::LOAD_DOCUMENT_URI
| nsIChannel::LOAD_CALL_CONTENT_SNIFFERS
;
1094 if (nsDocShell::SandboxFlagsImplyCookies(
1095 aBrowsingContext
->GetSandboxFlags())) {
1096 loadFlags
|= nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE
;
1099 // Load attributes depend on load type...
1101 case LOAD_HISTORY
: {
1102 // Only send VALIDATE_NEVER if mLSHE's URI was never changed via
1103 // push/replaceState (bug 669671).
1104 if (!*aUriModified
) {
1105 loadFlags
|= nsIRequest::VALIDATE_NEVER
;
1110 case LOAD_RELOAD_CHARSET_CHANGE_BYPASS_PROXY_AND_CACHE
:
1111 case LOAD_RELOAD_CHARSET_CHANGE_BYPASS_CACHE
:
1113 nsIRequest::LOAD_BYPASS_CACHE
| nsIRequest::LOAD_FRESH_CONNECTION
;
1117 loadFlags
|= nsIRequest::VALIDATE_ALWAYS
;
1120 case LOAD_NORMAL_BYPASS_CACHE
:
1121 case LOAD_NORMAL_BYPASS_PROXY
:
1122 case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE
:
1123 case LOAD_RELOAD_BYPASS_CACHE
:
1124 case LOAD_RELOAD_BYPASS_PROXY
:
1125 case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE
:
1126 case LOAD_REPLACE_BYPASS_CACHE
:
1128 nsIRequest::LOAD_BYPASS_CACHE
| nsIRequest::LOAD_FRESH_CONNECTION
;
1131 case LOAD_RELOAD_NORMAL
:
1133 browser_soft_reload_only_force_validate_top_level_document()) {
1134 loadFlags
|= nsIRequest::VALIDATE_ALWAYS
;
1140 // Set cache checking flags
1141 switch (StaticPrefs::browser_cache_check_doc_frequency()) {
1143 loadFlags
|= nsIRequest::VALIDATE_ONCE_PER_SESSION
;
1146 loadFlags
|= nsIRequest::VALIDATE_ALWAYS
;
1149 loadFlags
|= nsIRequest::VALIDATE_NEVER
;
1155 if (HasInternalLoadFlags(nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER
)) {
1156 loadFlags
|= nsIChannel::LOAD_BYPASS_URL_CLASSIFIER
;
1159 // If the user pressed shift-reload, then do not allow ServiceWorker
1160 // interception to occur. See step 12.1 of the SW HandleFetch algorithm.
1161 if (IsForceReloadType(loadType
)) {
1162 loadFlags
|= nsIChannel::LOAD_BYPASS_SERVICE_WORKER
;
1168 const char* nsDocShellLoadState::ValidateWithOriginalState(
1169 nsDocShellLoadState
* aOriginalState
) {
1170 MOZ_ASSERT(mLoadIdentifier
== aOriginalState
->mLoadIdentifier
);
1172 // Check that `aOriginalState` is sufficiently similar to this state that
1173 // they're performing the same load.
1174 auto uriEq
= [](nsIURI
* a
, nsIURI
* b
) -> bool {
1176 return a
== b
|| (a
&& b
&& NS_SUCCEEDED(a
->Equals(b
, &eq
)) && eq
);
1178 if (!uriEq(mURI
, aOriginalState
->mURI
)) {
1181 if (!uriEq(mUnstrippedURI
, aOriginalState
->mUnstrippedURI
)) {
1182 return "UnstrippedURI";
1184 if (!uriEq(mOriginalURI
, aOriginalState
->mOriginalURI
)) {
1185 return "OriginalURI";
1187 if (!uriEq(mBaseURI
, aOriginalState
->mBaseURI
)) {
1191 if (!mTriggeringPrincipal
->Equals(aOriginalState
->mTriggeringPrincipal
)) {
1192 return "TriggeringPrincipal";
1194 if (mTriggeringSandboxFlags
!= aOriginalState
->mTriggeringSandboxFlags
) {
1195 return "TriggeringSandboxFlags";
1197 if (mTriggeringRemoteType
!= aOriginalState
->mTriggeringRemoteType
) {
1198 return "TriggeringRemoteType";
1201 if (mOriginalURIString
!= aOriginalState
->mOriginalURIString
) {
1202 return "OriginalURIString";
1205 if (mRemoteTypeOverride
!= aOriginalState
->mRemoteTypeOverride
) {
1206 return "RemoteTypeOverride";
1209 if (mSourceBrowsingContext
.ContextId() !=
1210 aOriginalState
->mSourceBrowsingContext
.ContextId()) {
1211 return "SourceBrowsingContext";
1214 // FIXME: Consider calculating less information in the target process so that
1215 // we can validate more properties more easily.
1216 // FIXME: Identify what other flags will not change when sent through a
1222 DocShellLoadStateInit
nsDocShellLoadState::Serialize(
1223 mozilla::ipc::IProtocol
* aActor
) {
1225 DocShellLoadStateInit loadState
;
1226 loadState
.ResultPrincipalURI() = mResultPrincipalURI
;
1227 loadState
.ResultPrincipalURIIsSome() = mResultPrincipalURIIsSome
;
1228 loadState
.KeepResultPrincipalURIIfSet() = mKeepResultPrincipalURIIfSet
;
1229 loadState
.LoadReplace() = mLoadReplace
;
1230 loadState
.InheritPrincipal() = mInheritPrincipal
;
1231 loadState
.PrincipalIsExplicit() = mPrincipalIsExplicit
;
1232 loadState
.ForceAllowDataURI() = mForceAllowDataURI
;
1233 loadState
.IsExemptFromHTTPSOnlyMode() = mIsExemptFromHTTPSOnlyMode
;
1234 loadState
.OriginalFrameSrc() = mOriginalFrameSrc
;
1235 loadState
.IsFormSubmission() = mIsFormSubmission
;
1236 loadState
.LoadType() = mLoadType
;
1237 loadState
.Target() = mTarget
;
1238 loadState
.TargetBrowsingContext() = mTargetBrowsingContext
;
1239 loadState
.LoadFlags() = mLoadFlags
;
1240 loadState
.InternalLoadFlags() = mInternalLoadFlags
;
1241 loadState
.FirstParty() = mFirstParty
;
1242 loadState
.HasValidUserGestureActivation() = mHasValidUserGestureActivation
;
1243 loadState
.AllowFocusMove() = mAllowFocusMove
;
1244 loadState
.TypeHint() = mTypeHint
;
1245 loadState
.FileName() = mFileName
;
1246 loadState
.IsFromProcessingFrameAttributes() =
1247 mIsFromProcessingFrameAttributes
;
1248 loadState
.URI() = mURI
;
1249 loadState
.OriginalURI() = mOriginalURI
;
1250 loadState
.SourceBrowsingContext() = mSourceBrowsingContext
;
1251 loadState
.BaseURI() = mBaseURI
;
1252 loadState
.TriggeringPrincipal() = mTriggeringPrincipal
;
1253 loadState
.PrincipalToInherit() = mPrincipalToInherit
;
1254 loadState
.PartitionedPrincipalToInherit() = mPartitionedPrincipalToInherit
;
1255 loadState
.TriggeringSandboxFlags() = mTriggeringSandboxFlags
;
1256 loadState
.TriggeringRemoteType() = mTriggeringRemoteType
;
1257 loadState
.Csp() = mCsp
;
1258 loadState
.OriginalURIString() = mOriginalURIString
;
1259 loadState
.CancelContentJSEpoch() = mCancelContentJSEpoch
;
1260 loadState
.ReferrerInfo() = mReferrerInfo
;
1261 loadState
.PostDataStream() = mPostDataStream
;
1262 loadState
.HeadersStream() = mHeadersStream
;
1263 loadState
.SrcdocData() = mSrcdocData
;
1264 loadState
.ResultPrincipalURI() = mResultPrincipalURI
;
1265 loadState
.LoadIdentifier() = mLoadIdentifier
;
1266 loadState
.ChannelInitialized() = mChannelInitialized
;
1267 loadState
.IsMetaRefresh() = mIsMetaRefresh
;
1268 if (mLoadingSessionHistoryInfo
) {
1269 loadState
.loadingSessionHistoryInfo().emplace(*mLoadingSessionHistoryInfo
);
1271 loadState
.UnstrippedURI() = mUnstrippedURI
;
1272 loadState
.RemoteTypeOverride() = mRemoteTypeOverride
;
1274 if (XRE_IsParentProcess()) {
1275 mozilla::ipc::IToplevelProtocol
* top
= aActor
->ToplevelProtocol();
1276 MOZ_RELEASE_ASSERT(top
&&
1277 top
->GetProtocolId() ==
1278 mozilla::ipc::ProtocolId::PContentMsgStart
&&
1279 top
->GetSide() == mozilla::ipc::ParentSide
,
1280 "nsDocShellLoadState must be sent over PContent");
1281 ContentParent
* cp
= static_cast<ContentParent
*>(top
);
1282 cp
->StorePendingLoadState(this);
1288 nsIURI
* nsDocShellLoadState::GetUnstrippedURI() const { return mUnstrippedURI
; }
1290 void nsDocShellLoadState::SetUnstrippedURI(nsIURI
* aUnstrippedURI
) {
1291 mUnstrippedURI
= aUnstrippedURI
;