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 mIsExemptFromHTTPSFirstMode
= aLoadState
.IsExemptFromHTTPSFirstMode();
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 mTriggeringWindowId
= aLoadState
.TriggeringWindowId();
90 mTriggeringStorageAccess
= aLoadState
.TriggeringStorageAccess();
91 mTriggeringRemoteType
= aLoadState
.TriggeringRemoteType();
92 mWasSchemelessInput
= aLoadState
.WasSchemelessInput();
93 mCsp
= aLoadState
.Csp();
94 mOriginalURIString
= aLoadState
.OriginalURIString();
95 mCancelContentJSEpoch
= aLoadState
.CancelContentJSEpoch();
96 mPostDataStream
= aLoadState
.PostDataStream();
97 mHeadersStream
= aLoadState
.HeadersStream();
98 mSrcdocData
= aLoadState
.SrcdocData();
99 mChannelInitialized
= aLoadState
.ChannelInitialized();
100 mIsMetaRefresh
= aLoadState
.IsMetaRefresh();
101 if (aLoadState
.loadingSessionHistoryInfo().isSome()) {
102 mLoadingSessionHistoryInfo
= MakeUnique
<LoadingSessionHistoryInfo
>(
103 aLoadState
.loadingSessionHistoryInfo().ref());
105 mUnstrippedURI
= aLoadState
.UnstrippedURI();
106 mRemoteTypeOverride
= aLoadState
.RemoteTypeOverride();
108 // We know this was created remotely, as we just received it over IPC.
109 mWasCreatedRemotely
= true;
111 // If we're in the parent process, potentially validate against a LoadState
112 // which we sent to the source content process.
113 if (XRE_IsParentProcess()) {
114 mozilla::ipc::IToplevelProtocol
* top
= aActor
->ToplevelProtocol();
116 top
->GetProtocolId() != mozilla::ipc::ProtocolId::PContentMsgStart
||
117 top
->GetSide() != mozilla::ipc::ParentSide
) {
118 aActor
->FatalError("nsDocShellLoadState must be received over PContent");
121 ContentParent
* cp
= static_cast<ContentParent
*>(top
);
123 // If this load was sent down to the content process as a navigation
124 // request, ensure it still matches the one we sent down.
125 if (RefPtr
<nsDocShellLoadState
> originalState
=
126 cp
->TakePendingLoadStateForId(mLoadIdentifier
)) {
127 if (const char* mismatch
= ValidateWithOriginalState(originalState
)) {
130 "nsDocShellLoadState %s changed while in content process",
135 } else if (mTriggeringRemoteType
!= cp
->GetRemoteType()) {
136 // If we don't have a previous load to compare to, the content process
137 // must be the triggering process.
139 "nsDocShellLoadState with invalid triggering remote type");
144 // We successfully read in the data - return a success value.
145 *aReadSuccess
= true;
148 nsDocShellLoadState::nsDocShellLoadState(const nsDocShellLoadState
& aOther
)
149 : mReferrerInfo(aOther
.mReferrerInfo
),
151 mOriginalURI(aOther
.mOriginalURI
),
152 mResultPrincipalURI(aOther
.mResultPrincipalURI
),
153 mResultPrincipalURIIsSome(aOther
.mResultPrincipalURIIsSome
),
154 mTriggeringPrincipal(aOther
.mTriggeringPrincipal
),
155 mTriggeringSandboxFlags(aOther
.mTriggeringSandboxFlags
),
156 mTriggeringWindowId(aOther
.mTriggeringWindowId
),
157 mTriggeringStorageAccess(aOther
.mTriggeringStorageAccess
),
159 mKeepResultPrincipalURIIfSet(aOther
.mKeepResultPrincipalURIIfSet
),
160 mLoadReplace(aOther
.mLoadReplace
),
161 mInheritPrincipal(aOther
.mInheritPrincipal
),
162 mPrincipalIsExplicit(aOther
.mPrincipalIsExplicit
),
163 mNotifiedBeforeUnloadListeners(aOther
.mNotifiedBeforeUnloadListeners
),
164 mPrincipalToInherit(aOther
.mPrincipalToInherit
),
165 mPartitionedPrincipalToInherit(aOther
.mPartitionedPrincipalToInherit
),
166 mForceAllowDataURI(aOther
.mForceAllowDataURI
),
167 mIsExemptFromHTTPSFirstMode(aOther
.mIsExemptFromHTTPSFirstMode
),
168 mOriginalFrameSrc(aOther
.mOriginalFrameSrc
),
169 mIsFormSubmission(aOther
.mIsFormSubmission
),
170 mLoadType(aOther
.mLoadType
),
171 mSHEntry(aOther
.mSHEntry
),
172 mTarget(aOther
.mTarget
),
173 mTargetBrowsingContext(aOther
.mTargetBrowsingContext
),
174 mPostDataStream(aOther
.mPostDataStream
),
175 mHeadersStream(aOther
.mHeadersStream
),
176 mSrcdocData(aOther
.mSrcdocData
),
177 mSourceBrowsingContext(aOther
.mSourceBrowsingContext
),
178 mBaseURI(aOther
.mBaseURI
),
179 mLoadFlags(aOther
.mLoadFlags
),
180 mInternalLoadFlags(aOther
.mInternalLoadFlags
),
181 mFirstParty(aOther
.mFirstParty
),
182 mHasValidUserGestureActivation(aOther
.mHasValidUserGestureActivation
),
183 mAllowFocusMove(aOther
.mAllowFocusMove
),
184 mTypeHint(aOther
.mTypeHint
),
185 mFileName(aOther
.mFileName
),
186 mIsFromProcessingFrameAttributes(aOther
.mIsFromProcessingFrameAttributes
),
187 mPendingRedirectedChannel(aOther
.mPendingRedirectedChannel
),
188 mOriginalURIString(aOther
.mOriginalURIString
),
189 mCancelContentJSEpoch(aOther
.mCancelContentJSEpoch
),
190 mLoadIdentifier(aOther
.mLoadIdentifier
),
191 mChannelInitialized(aOther
.mChannelInitialized
),
192 mIsMetaRefresh(aOther
.mIsMetaRefresh
),
193 mWasCreatedRemotely(aOther
.mWasCreatedRemotely
),
194 mUnstrippedURI(aOther
.mUnstrippedURI
),
195 mRemoteTypeOverride(aOther
.mRemoteTypeOverride
),
196 mTriggeringRemoteType(aOther
.mTriggeringRemoteType
),
197 mWasSchemelessInput(aOther
.mWasSchemelessInput
) {
198 MOZ_DIAGNOSTIC_ASSERT(
199 XRE_IsParentProcess(),
200 "Cloning a nsDocShellLoadState with the same load identifier is only "
201 "allowed in the parent process, as it could break triggering remote type "
202 "tracking in content.");
203 if (aOther
.mLoadingSessionHistoryInfo
) {
204 mLoadingSessionHistoryInfo
= MakeUnique
<LoadingSessionHistoryInfo
>(
205 *aOther
.mLoadingSessionHistoryInfo
);
209 nsDocShellLoadState::nsDocShellLoadState(nsIURI
* aURI
, uint64_t aLoadIdentifier
)
211 mResultPrincipalURIIsSome(false),
212 mTriggeringSandboxFlags(0),
213 mTriggeringWindowId(0),
214 mTriggeringStorageAccess(false),
215 mKeepResultPrincipalURIIfSet(false),
217 mInheritPrincipal(false),
218 mPrincipalIsExplicit(false),
219 mNotifiedBeforeUnloadListeners(false),
220 mForceAllowDataURI(false),
221 mIsExemptFromHTTPSFirstMode(false),
222 mOriginalFrameSrc(false),
223 mIsFormSubmission(false),
224 mLoadType(LOAD_NORMAL
),
225 mSrcdocData(VoidString()),
227 mInternalLoadFlags(0),
229 mHasValidUserGestureActivation(false),
230 mAllowFocusMove(false),
231 mTypeHint(VoidCString()),
232 mFileName(VoidString()),
233 mIsFromProcessingFrameAttributes(false),
234 mLoadIdentifier(aLoadIdentifier
),
235 mChannelInitialized(false),
236 mIsMetaRefresh(false),
237 mWasCreatedRemotely(false),
238 mTriggeringRemoteType(XRE_IsContentProcess()
239 ? ContentChild::GetSingleton()->GetRemoteType()
241 mWasSchemelessInput(false) {
242 MOZ_ASSERT(aURI
, "Cannot create a LoadState with a null URI!");
245 nsDocShellLoadState::~nsDocShellLoadState() {
246 if (mWasCreatedRemotely
&& XRE_IsContentProcess()) {
247 ContentChild::GetSingleton()->SendCleanupPendingLoadState(mLoadIdentifier
);
251 nsresult
nsDocShellLoadState::CreateFromPendingChannel(
252 nsIChannel
* aPendingChannel
, uint64_t aLoadIdentifier
,
253 uint64_t aRegistrarId
, nsDocShellLoadState
** aResult
) {
254 // Create the nsDocShellLoadState object with default state pulled from the
255 // passed-in channel.
256 nsCOMPtr
<nsIURI
> uri
;
257 nsresult rv
= aPendingChannel
->GetURI(getter_AddRefs(uri
));
258 if (NS_WARN_IF(NS_FAILED(rv
))) {
262 RefPtr
<nsDocShellLoadState
> loadState
=
263 new nsDocShellLoadState(uri
, aLoadIdentifier
);
264 loadState
->mPendingRedirectedChannel
= aPendingChannel
;
265 loadState
->mChannelRegistrarId
= aRegistrarId
;
267 // Pull relevant state from the channel, and store it on the
268 // nsDocShellLoadState.
269 nsCOMPtr
<nsIURI
> originalUri
;
270 rv
= aPendingChannel
->GetOriginalURI(getter_AddRefs(originalUri
));
271 if (NS_WARN_IF(NS_FAILED(rv
))) {
274 loadState
->SetOriginalURI(originalUri
);
276 nsCOMPtr
<nsILoadInfo
> loadInfo
= aPendingChannel
->LoadInfo();
277 loadState
->SetTriggeringPrincipal(loadInfo
->TriggeringPrincipal());
279 // Return the newly created loadState.
280 loadState
.forget(aResult
);
284 static uint32_t WebNavigationFlagsToFixupFlags(nsIURI
* aURI
,
285 const nsACString
& aURIString
,
286 uint32_t aNavigationFlags
) {
288 aNavigationFlags
&= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
;
290 uint32_t fixupFlags
= nsIURIFixup::FIXUP_FLAG_NONE
;
291 if (aNavigationFlags
& nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
) {
292 fixupFlags
|= nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
;
294 if (aNavigationFlags
& nsIWebNavigation::LOAD_FLAGS_FIXUP_SCHEME_TYPOS
) {
295 fixupFlags
|= nsIURIFixup::FIXUP_FLAG_FIX_SCHEME_TYPOS
;
300 nsresult
nsDocShellLoadState::CreateFromLoadURIOptions(
301 BrowsingContext
* aBrowsingContext
, const nsAString
& aURI
,
302 const LoadURIOptions
& aLoadURIOptions
, nsDocShellLoadState
** aResult
) {
303 uint32_t loadFlags
= aLoadURIOptions
.mLoadFlags
;
306 (loadFlags
& nsDocShell::INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS
) == 0,
309 nsCOMPtr
<nsIURI
> uri
;
312 NS_ConvertUTF16toUTF8
uriString(aURI
);
313 // Cleanup the empty spaces that might be on each end.
315 // Eliminate embedded newlines, which single-line text fields now allow:
316 uriString
.StripCRLF();
317 NS_ENSURE_TRUE(!uriString
.IsEmpty(), NS_ERROR_FAILURE
);
319 // Just create a URI and see what happens...
320 rv
= NS_NewURI(getter_AddRefs(uri
), uriString
);
322 if (NS_SUCCEEDED(rv
) && uri
&&
323 (uri
->SchemeIs("about") || uri
->SchemeIs("chrome"))) {
324 // Avoid third party fixup as a performance optimization.
325 loadFlags
&= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
;
327 } else if (!sURIFixup
&& !XRE_IsContentProcess()) {
328 nsCOMPtr
<nsIURIFixup
> uriFixup
= components::URIFixup::Service();
330 sURIFixup
= uriFixup
;
331 ClearOnShutdown(&sURIFixup
);
337 nsAutoString searchProvider
, keyword
;
338 RefPtr
<nsIInputStream
> fixupStream
;
340 uint32_t fixupFlags
=
341 WebNavigationFlagsToFixupFlags(uri
, uriString
, loadFlags
);
343 // If we don't allow keyword lookups for this URL string, make sure to
344 // update loadFlags to indicate this as well.
345 if (!(fixupFlags
& nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
)) {
346 loadFlags
&= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
;
348 // Ensure URIFixup will use the right search engine in Private Browsing.
349 if (aBrowsingContext
->UsePrivateBrowsing()) {
350 fixupFlags
|= nsIURIFixup::FIXUP_FLAG_PRIVATE_CONTEXT
;
353 if (!XRE_IsContentProcess()) {
354 nsCOMPtr
<nsIURIFixupInfo
> fixupInfo
;
355 sURIFixup
->GetFixupURIInfo(uriString
, fixupFlags
,
356 getter_AddRefs(fixupInfo
));
358 // We could fix the uri, clear NS_ERROR_MALFORMED_URI.
360 fixupInfo
->GetPreferredURI(getter_AddRefs(uri
));
361 fixupInfo
->SetConsumer(aBrowsingContext
);
362 fixupInfo
->GetKeywordProviderName(searchProvider
);
363 fixupInfo
->GetKeywordAsSent(keyword
);
364 // GetFixupURIInfo only returns a post data stream if it succeeded
365 // and changed the URI, in which case we should override the
366 // passed-in post data by passing this as an override arg to
367 // our internal method.
368 fixupInfo
->GetPostData(getter_AddRefs(fixupStream
));
371 loadFlags
& nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
) {
372 nsCOMPtr
<nsIObserverService
> serv
= services::GetObserverService();
374 serv
->NotifyObservers(fixupInfo
, "keyword-uri-fixup",
375 PromiseFlatString(aURI
).get());
378 nsDocShell::MaybeNotifyKeywordSearchLoading(searchProvider
, keyword
);
383 if (rv
== NS_ERROR_MALFORMED_URI
) {
388 if (NS_FAILED(rv
) || !uri
) {
389 return NS_ERROR_FAILURE
;
392 RefPtr
<nsDocShellLoadState
> loadState
;
393 rv
= CreateFromLoadURIOptions(
394 aBrowsingContext
, uri
, aLoadURIOptions
, loadFlags
,
395 fixupStream
? fixupStream
: aLoadURIOptions
.mPostData
,
396 getter_AddRefs(loadState
));
397 NS_ENSURE_SUCCESS(rv
, rv
);
398 loadState
->SetOriginalURIString(uriString
);
399 loadState
.forget(aResult
);
403 nsresult
nsDocShellLoadState::CreateFromLoadURIOptions(
404 BrowsingContext
* aBrowsingContext
, nsIURI
* aURI
,
405 const LoadURIOptions
& aLoadURIOptions
, nsDocShellLoadState
** aResult
) {
406 return CreateFromLoadURIOptions(aBrowsingContext
, aURI
, aLoadURIOptions
,
407 aLoadURIOptions
.mLoadFlags
,
408 aLoadURIOptions
.mPostData
, aResult
);
411 nsresult
nsDocShellLoadState::CreateFromLoadURIOptions(
412 BrowsingContext
* aBrowsingContext
, nsIURI
* aURI
,
413 const LoadURIOptions
& aLoadURIOptions
, uint32_t aLoadFlagsOverride
,
414 nsIInputStream
* aPostDataOverride
, nsDocShellLoadState
** aResult
) {
416 uint32_t loadFlags
= aLoadFlagsOverride
;
417 RefPtr
<nsIInputStream
> postData
= aPostDataOverride
;
420 rv
= postData
->Available(&available
);
421 NS_ENSURE_SUCCESS(rv
, rv
);
422 if (available
== 0) {
423 return NS_ERROR_INVALID_ARG
;
427 if (aLoadURIOptions
.mHeaders
) {
428 rv
= aLoadURIOptions
.mHeaders
->Available(&available
);
429 NS_ENSURE_SUCCESS(rv
, rv
);
430 if (available
== 0) {
431 return NS_ERROR_INVALID_ARG
;
435 bool forceAllowDataURI
=
436 loadFlags
& nsIWebNavigation::LOAD_FLAGS_FORCE_ALLOW_DATA_URI
;
438 // Don't pass certain flags that aren't needed and end up confusing
439 // ConvertLoadTypeToDocShellInfoLoadType. We do need to ensure that they are
440 // passed to LoadURI though, since it uses them.
441 uint32_t extraFlags
= (loadFlags
& EXTRA_LOAD_FLAGS
);
442 loadFlags
&= ~EXTRA_LOAD_FLAGS
;
444 RefPtr
<nsDocShellLoadState
> loadState
= new nsDocShellLoadState(aURI
);
445 loadState
->SetReferrerInfo(aLoadURIOptions
.mReferrerInfo
);
447 loadState
->SetLoadType(MAKE_LOAD_TYPE(LOAD_NORMAL
, loadFlags
));
449 loadState
->SetLoadFlags(extraFlags
);
450 loadState
->SetFirstParty(true);
451 loadState
->SetHasValidUserGestureActivation(
452 aLoadURIOptions
.mHasValidUserGestureActivation
);
453 loadState
->SetTriggeringSandboxFlags(aLoadURIOptions
.mTriggeringSandboxFlags
);
454 loadState
->SetTriggeringWindowId(aLoadURIOptions
.mTriggeringWindowId
);
455 loadState
->SetTriggeringStorageAccess(
456 aLoadURIOptions
.mTriggeringStorageAccess
);
457 loadState
->SetPostDataStream(postData
);
458 loadState
->SetHeadersStream(aLoadURIOptions
.mHeaders
);
459 loadState
->SetBaseURI(aLoadURIOptions
.mBaseURI
);
460 loadState
->SetTriggeringPrincipal(aLoadURIOptions
.mTriggeringPrincipal
);
461 loadState
->SetCsp(aLoadURIOptions
.mCsp
);
462 loadState
->SetForceAllowDataURI(forceAllowDataURI
);
463 if (aLoadURIOptions
.mCancelContentJSEpoch
) {
464 loadState
->SetCancelContentJSEpoch(aLoadURIOptions
.mCancelContentJSEpoch
);
467 if (aLoadURIOptions
.mTriggeringRemoteType
.WasPassed()) {
468 if (XRE_IsParentProcess()) {
469 loadState
->SetTriggeringRemoteType(
470 aLoadURIOptions
.mTriggeringRemoteType
.Value());
471 } else if (ContentChild::GetSingleton()->GetRemoteType() !=
472 aLoadURIOptions
.mTriggeringRemoteType
.Value()) {
473 NS_WARNING("Invalid TriggeringRemoteType from LoadURIOptions in content");
474 return NS_ERROR_INVALID_ARG
;
478 if (aLoadURIOptions
.mRemoteTypeOverride
.WasPassed()) {
479 loadState
->SetRemoteTypeOverride(
480 aLoadURIOptions
.mRemoteTypeOverride
.Value());
483 loadState
->SetWasSchemelessInput(aLoadURIOptions
.mWasSchemelessInput
);
485 loadState
.forget(aResult
);
489 nsIReferrerInfo
* nsDocShellLoadState::GetReferrerInfo() const {
490 return mReferrerInfo
;
493 void nsDocShellLoadState::SetReferrerInfo(nsIReferrerInfo
* aReferrerInfo
) {
494 mReferrerInfo
= aReferrerInfo
;
497 nsIURI
* nsDocShellLoadState::URI() const { return mURI
; }
499 void nsDocShellLoadState::SetURI(nsIURI
* aURI
) { mURI
= aURI
; }
501 nsIURI
* nsDocShellLoadState::OriginalURI() const { return mOriginalURI
; }
503 void nsDocShellLoadState::SetOriginalURI(nsIURI
* aOriginalURI
) {
504 mOriginalURI
= aOriginalURI
;
507 nsIURI
* nsDocShellLoadState::ResultPrincipalURI() const {
508 return mResultPrincipalURI
;
511 void nsDocShellLoadState::SetResultPrincipalURI(nsIURI
* aResultPrincipalURI
) {
512 mResultPrincipalURI
= aResultPrincipalURI
;
515 bool nsDocShellLoadState::ResultPrincipalURIIsSome() const {
516 return mResultPrincipalURIIsSome
;
519 void nsDocShellLoadState::SetResultPrincipalURIIsSome(bool aIsSome
) {
520 mResultPrincipalURIIsSome
= aIsSome
;
523 bool nsDocShellLoadState::KeepResultPrincipalURIIfSet() const {
524 return mKeepResultPrincipalURIIfSet
;
527 void nsDocShellLoadState::SetKeepResultPrincipalURIIfSet(bool aKeep
) {
528 mKeepResultPrincipalURIIfSet
= aKeep
;
531 bool nsDocShellLoadState::LoadReplace() const { return mLoadReplace
; }
533 void nsDocShellLoadState::SetLoadReplace(bool aLoadReplace
) {
534 mLoadReplace
= aLoadReplace
;
537 nsIPrincipal
* nsDocShellLoadState::TriggeringPrincipal() const {
538 return mTriggeringPrincipal
;
541 void nsDocShellLoadState::SetTriggeringPrincipal(
542 nsIPrincipal
* aTriggeringPrincipal
) {
543 mTriggeringPrincipal
= aTriggeringPrincipal
;
546 nsIPrincipal
* nsDocShellLoadState::PrincipalToInherit() const {
547 return mPrincipalToInherit
;
550 void nsDocShellLoadState::SetPrincipalToInherit(
551 nsIPrincipal
* aPrincipalToInherit
) {
552 mPrincipalToInherit
= aPrincipalToInherit
;
555 nsIPrincipal
* nsDocShellLoadState::PartitionedPrincipalToInherit() const {
556 return mPartitionedPrincipalToInherit
;
559 void nsDocShellLoadState::SetPartitionedPrincipalToInherit(
560 nsIPrincipal
* aPartitionedPrincipalToInherit
) {
561 mPartitionedPrincipalToInherit
= aPartitionedPrincipalToInherit
;
564 void nsDocShellLoadState::SetCsp(nsIContentSecurityPolicy
* aCsp
) {
568 nsIContentSecurityPolicy
* nsDocShellLoadState::Csp() const { return mCsp
; }
570 void nsDocShellLoadState::SetTriggeringSandboxFlags(uint32_t flags
) {
571 mTriggeringSandboxFlags
= flags
;
574 uint32_t nsDocShellLoadState::TriggeringSandboxFlags() const {
575 return mTriggeringSandboxFlags
;
578 void nsDocShellLoadState::SetTriggeringWindowId(uint64_t aTriggeringWindowId
) {
579 mTriggeringWindowId
= aTriggeringWindowId
;
582 uint64_t nsDocShellLoadState::TriggeringWindowId() const {
583 return mTriggeringWindowId
;
586 void nsDocShellLoadState::SetTriggeringStorageAccess(
587 bool aTriggeringStorageAccess
) {
588 mTriggeringStorageAccess
= aTriggeringStorageAccess
;
591 bool nsDocShellLoadState::TriggeringStorageAccess() const {
592 return mTriggeringStorageAccess
;
595 bool nsDocShellLoadState::InheritPrincipal() const { return mInheritPrincipal
; }
597 void nsDocShellLoadState::SetInheritPrincipal(bool aInheritPrincipal
) {
598 mInheritPrincipal
= aInheritPrincipal
;
601 bool nsDocShellLoadState::PrincipalIsExplicit() const {
602 return mPrincipalIsExplicit
;
605 void nsDocShellLoadState::SetPrincipalIsExplicit(bool aPrincipalIsExplicit
) {
606 mPrincipalIsExplicit
= aPrincipalIsExplicit
;
609 bool nsDocShellLoadState::NotifiedBeforeUnloadListeners() const {
610 return mNotifiedBeforeUnloadListeners
;
613 void nsDocShellLoadState::SetNotifiedBeforeUnloadListeners(
614 bool aNotifiedBeforeUnloadListeners
) {
615 mNotifiedBeforeUnloadListeners
= aNotifiedBeforeUnloadListeners
;
618 bool nsDocShellLoadState::ForceAllowDataURI() const {
619 return mForceAllowDataURI
;
622 void nsDocShellLoadState::SetForceAllowDataURI(bool aForceAllowDataURI
) {
623 mForceAllowDataURI
= aForceAllowDataURI
;
626 bool nsDocShellLoadState::IsExemptFromHTTPSFirstMode() const {
627 return mIsExemptFromHTTPSFirstMode
;
630 void nsDocShellLoadState::SetIsExemptFromHTTPSFirstMode(
631 bool aIsExemptFromHTTPSFirstMode
) {
632 mIsExemptFromHTTPSFirstMode
= aIsExemptFromHTTPSFirstMode
;
635 bool nsDocShellLoadState::OriginalFrameSrc() const { return mOriginalFrameSrc
; }
637 void nsDocShellLoadState::SetOriginalFrameSrc(bool aOriginalFrameSrc
) {
638 mOriginalFrameSrc
= aOriginalFrameSrc
;
641 bool nsDocShellLoadState::IsFormSubmission() const { return mIsFormSubmission
; }
643 void nsDocShellLoadState::SetIsFormSubmission(bool aIsFormSubmission
) {
644 mIsFormSubmission
= aIsFormSubmission
;
647 uint32_t nsDocShellLoadState::LoadType() const { return mLoadType
; }
649 void nsDocShellLoadState::SetLoadType(uint32_t aLoadType
) {
650 mLoadType
= aLoadType
;
653 nsISHEntry
* nsDocShellLoadState::SHEntry() const { return mSHEntry
; }
655 void nsDocShellLoadState::SetSHEntry(nsISHEntry
* aSHEntry
) {
657 nsCOMPtr
<SessionHistoryEntry
> she
= do_QueryInterface(aSHEntry
);
659 mLoadingSessionHistoryInfo
= MakeUnique
<LoadingSessionHistoryInfo
>(she
);
661 mLoadingSessionHistoryInfo
= nullptr;
665 void nsDocShellLoadState::SetLoadingSessionHistoryInfo(
666 const mozilla::dom::LoadingSessionHistoryInfo
& aLoadingInfo
) {
667 SetLoadingSessionHistoryInfo(
668 MakeUnique
<mozilla::dom::LoadingSessionHistoryInfo
>(aLoadingInfo
));
671 void nsDocShellLoadState::SetLoadingSessionHistoryInfo(
672 mozilla::UniquePtr
<mozilla::dom::LoadingSessionHistoryInfo
> aLoadingInfo
) {
673 mLoadingSessionHistoryInfo
= std::move(aLoadingInfo
);
676 const mozilla::dom::LoadingSessionHistoryInfo
*
677 nsDocShellLoadState::GetLoadingSessionHistoryInfo() const {
678 return mLoadingSessionHistoryInfo
.get();
681 void nsDocShellLoadState::SetLoadIsFromSessionHistory(
682 int32_t aOffset
, bool aLoadingCurrentEntry
) {
683 if (mLoadingSessionHistoryInfo
) {
684 mLoadingSessionHistoryInfo
->mLoadIsFromSessionHistory
= true;
685 mLoadingSessionHistoryInfo
->mOffset
= aOffset
;
686 mLoadingSessionHistoryInfo
->mLoadingCurrentEntry
= aLoadingCurrentEntry
;
690 void nsDocShellLoadState::ClearLoadIsFromSessionHistory() {
691 if (mLoadingSessionHistoryInfo
) {
692 mLoadingSessionHistoryInfo
->mLoadIsFromSessionHistory
= false;
697 bool nsDocShellLoadState::LoadIsFromSessionHistory() const {
698 return mLoadingSessionHistoryInfo
699 ? mLoadingSessionHistoryInfo
->mLoadIsFromSessionHistory
703 void nsDocShellLoadState::MaybeStripTrackerQueryStrings(
704 BrowsingContext
* aContext
) {
705 MOZ_ASSERT(aContext
);
707 // Return early if the triggering principal doesn't exist. This could happen
708 // when loading a URL by using a browsing context in the Browser Toolbox.
709 if (!TriggeringPrincipal()) {
713 // We don't need to strip for sub frames because the query string has been
714 // stripped in the top-level content. Also, we don't apply stripping if it
715 // is triggered by addons.
717 // Note that we don't need to do the stripping if the channel has been
718 // initialized. This means that this has been loaded speculatively in the
719 // parent process before and the stripping was happening by then.
720 if (GetChannelInitialized() || !aContext
->IsTopContent() ||
721 BasePrincipal::Cast(TriggeringPrincipal())->AddonPolicy()) {
725 // We don't strip the URI if it's the same-site navigation. Note that we will
726 // consider the system principal triggered load as third-party in case the
727 // user copies and pastes a URL which has tracking query parameters or an
728 // loading from external applications, such as clicking a link in an email
730 bool isThirdPartyURI
= false;
731 if (!TriggeringPrincipal()->IsSystemPrincipal() &&
733 TriggeringPrincipal()->IsThirdPartyURI(URI(), &isThirdPartyURI
)) ||
738 Telemetry::AccumulateCategorical(
739 Telemetry::LABELS_QUERY_STRIPPING_COUNT::Navigation
);
741 nsCOMPtr
<nsIURI
> strippedURI
;
744 nsCOMPtr
<nsIURLQueryStringStripper
> queryStripper
=
745 components::URLQueryStringStripper::Service(&rv
);
746 NS_ENSURE_SUCCESS_VOID(rv
);
748 uint32_t numStripped
;
750 queryStripper
->Strip(URI(), aContext
->UsePrivateBrowsing(),
751 getter_AddRefs(strippedURI
), &numStripped
);
753 if (!mUnstrippedURI
) {
754 mUnstrippedURI
= URI();
758 Telemetry::AccumulateCategorical(
759 Telemetry::LABELS_QUERY_STRIPPING_COUNT::StripForNavigation
);
760 Telemetry::Accumulate(Telemetry::QUERY_STRIPPING_PARAM_COUNT
, numStripped
);
764 // Make sure that unstripped URI is the same as URI() but only the query
765 // string could be different.
766 if (mUnstrippedURI
) {
767 nsCOMPtr
<nsIURI
> uri
;
768 Unused
<< queryStripper
->Strip(mUnstrippedURI
,
769 aContext
->UsePrivateBrowsing(),
770 getter_AddRefs(uri
), &numStripped
);
772 Unused
<< URI()->Equals(uri
, &equals
);
778 const nsString
& nsDocShellLoadState::Target() const { return mTarget
; }
780 void nsDocShellLoadState::SetTarget(const nsAString
& aTarget
) {
784 nsIInputStream
* nsDocShellLoadState::PostDataStream() const {
785 return mPostDataStream
;
788 void nsDocShellLoadState::SetPostDataStream(nsIInputStream
* aStream
) {
789 mPostDataStream
= aStream
;
792 nsIInputStream
* nsDocShellLoadState::HeadersStream() const {
793 return mHeadersStream
;
796 void nsDocShellLoadState::SetHeadersStream(nsIInputStream
* aHeadersStream
) {
797 mHeadersStream
= aHeadersStream
;
800 const nsString
& nsDocShellLoadState::SrcdocData() const { return mSrcdocData
; }
802 void nsDocShellLoadState::SetSrcdocData(const nsAString
& aSrcdocData
) {
803 mSrcdocData
= aSrcdocData
;
806 void nsDocShellLoadState::SetSourceBrowsingContext(
807 BrowsingContext
* aSourceBrowsingContext
) {
808 mSourceBrowsingContext
= aSourceBrowsingContext
;
811 void nsDocShellLoadState::SetTargetBrowsingContext(
812 BrowsingContext
* aTargetBrowsingContext
) {
813 mTargetBrowsingContext
= aTargetBrowsingContext
;
816 nsIURI
* nsDocShellLoadState::BaseURI() const { return mBaseURI
; }
818 void nsDocShellLoadState::SetBaseURI(nsIURI
* aBaseURI
) { mBaseURI
= aBaseURI
; }
820 void nsDocShellLoadState::GetMaybeResultPrincipalURI(
821 mozilla::Maybe
<nsCOMPtr
<nsIURI
>>& aRPURI
) const {
822 bool isSome
= ResultPrincipalURIIsSome();
829 nsCOMPtr
<nsIURI
> uri
= ResultPrincipalURI();
830 aRPURI
.emplace(std::move(uri
));
833 void nsDocShellLoadState::SetMaybeResultPrincipalURI(
834 mozilla::Maybe
<nsCOMPtr
<nsIURI
>> const& aRPURI
) {
835 SetResultPrincipalURI(aRPURI
.refOr(nullptr));
836 SetResultPrincipalURIIsSome(aRPURI
.isSome());
839 uint32_t nsDocShellLoadState::LoadFlags() const { return mLoadFlags
; }
841 void nsDocShellLoadState::SetLoadFlags(uint32_t aLoadFlags
) {
842 mLoadFlags
= aLoadFlags
;
845 void nsDocShellLoadState::SetLoadFlag(uint32_t aFlag
) { mLoadFlags
|= aFlag
; }
847 void nsDocShellLoadState::UnsetLoadFlag(uint32_t aFlag
) {
848 mLoadFlags
&= ~aFlag
;
851 bool nsDocShellLoadState::HasLoadFlags(uint32_t aFlags
) {
852 return (mLoadFlags
& aFlags
) == aFlags
;
855 uint32_t nsDocShellLoadState::InternalLoadFlags() const {
856 return mInternalLoadFlags
;
859 void nsDocShellLoadState::SetInternalLoadFlags(uint32_t aLoadFlags
) {
860 mInternalLoadFlags
= aLoadFlags
;
863 void nsDocShellLoadState::SetInternalLoadFlag(uint32_t aFlag
) {
864 mInternalLoadFlags
|= aFlag
;
867 void nsDocShellLoadState::UnsetInternalLoadFlag(uint32_t aFlag
) {
868 mInternalLoadFlags
&= ~aFlag
;
871 bool nsDocShellLoadState::HasInternalLoadFlags(uint32_t aFlags
) {
872 return (mInternalLoadFlags
& aFlags
) == aFlags
;
875 bool nsDocShellLoadState::FirstParty() const { return mFirstParty
; }
877 void nsDocShellLoadState::SetFirstParty(bool aFirstParty
) {
878 mFirstParty
= aFirstParty
;
881 bool nsDocShellLoadState::HasValidUserGestureActivation() const {
882 return mHasValidUserGestureActivation
;
885 void nsDocShellLoadState::SetHasValidUserGestureActivation(
886 bool aHasValidUserGestureActivation
) {
887 mHasValidUserGestureActivation
= aHasValidUserGestureActivation
;
890 const nsCString
& nsDocShellLoadState::TypeHint() const { return mTypeHint
; }
892 void nsDocShellLoadState::SetTypeHint(const nsCString
& aTypeHint
) {
893 mTypeHint
= aTypeHint
;
896 const nsString
& nsDocShellLoadState::FileName() const { return mFileName
; }
898 void nsDocShellLoadState::SetFileName(const nsAString
& aFileName
) {
899 MOZ_DIAGNOSTIC_ASSERT(aFileName
.FindChar(char16_t(0)) == kNotFound
,
900 "The filename should never contain null characters");
901 mFileName
= aFileName
;
904 void nsDocShellLoadState::SetRemoteTypeOverride(
905 const nsCString
& aRemoteTypeOverride
) {
906 MOZ_DIAGNOSTIC_ASSERT(
907 NS_IsAboutBlank(mURI
),
908 "Should only have aRemoteTypeOverride for about:blank URIs");
909 mRemoteTypeOverride
= mozilla::Some(aRemoteTypeOverride
);
912 const nsCString
& nsDocShellLoadState::GetEffectiveTriggeringRemoteType() const {
913 // Consider non-errorpage loads from session history as being triggred by the
914 // parent process, as we'll validate them against the history entry.
916 // NOTE: Keep this check in-sync with the session-history validation check in
917 // `DocumentLoadListener::Open`!
918 if (LoadIsFromSessionHistory() && LoadType() != LOAD_ERROR_PAGE
) {
919 return NOT_REMOTE_TYPE
;
921 return mTriggeringRemoteType
;
924 void nsDocShellLoadState::SetTriggeringRemoteType(
925 const nsACString
& aTriggeringRemoteType
) {
926 MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "only settable in parent");
927 mTriggeringRemoteType
= aTriggeringRemoteType
;
930 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
931 void nsDocShellLoadState::AssertProcessCouldTriggerLoadIfSystem() {
932 // Early check to see if we're trying to start a file URI load with a system
933 // principal within a web content process.
934 // If this assertion fails, the load will fail later during
935 // nsContentSecurityManager checks, however this assertion should happen
936 // closer to whichever caller is triggering the system-principal load.
937 if (mozilla::SessionHistoryInParent() &&
938 TriggeringPrincipal()->IsSystemPrincipal() &&
939 mozilla::dom::IsWebRemoteType(GetEffectiveTriggeringRemoteType())) {
940 bool localFile
= false;
941 if (NS_SUCCEEDED(NS_URIChainHasFlags(
942 URI(), nsIProtocolHandler::URI_IS_LOCAL_FILE
, &localFile
)) &&
944 NS_WARNING(nsPrintfCString("Unexpected system load of file URI (%s) from "
945 "web content process",
946 URI()->GetSpecOrDefault().get())
948 MOZ_CRASH("Unexpected system load of file URI from web content process");
954 nsresult
nsDocShellLoadState::SetupInheritingPrincipal(
955 BrowsingContext::Type aType
,
956 const mozilla::OriginAttributes
& aOriginAttributes
) {
957 // We need a principalToInherit.
959 // If principalIsExplicit is not set there are 4 possibilities:
960 // (1) If the system principal or an expanded principal was passed
961 // in and we're a typeContent docshell, inherit the principal
962 // from the current document instead.
963 // (2) In all other cases when the principal passed in is not null,
964 // use that principal.
965 // (3) If the caller has allowed inheriting from the current document,
966 // or if we're being called from system code (eg chrome JS or pure
967 // C++) then inheritPrincipal should be true and InternalLoad will get
968 // a principal from the current document. If none of these things are
970 // (4) we don't pass a principal into the channel, and a principal will be
971 // created later from the channel's internal data.
973 // If principalIsExplicit *is* set, there are 4 possibilities
974 // (1) If the system principal or an expanded principal was passed in
975 // and we're a typeContent docshell, return an error.
976 // (2) In all other cases when the principal passed in is not null,
977 // use that principal.
978 // (3) If the caller has allowed inheriting from the current document,
979 // then inheritPrincipal should be true and InternalLoad will get
980 // a principal from the current document. If none of these things are
982 // (4) we dont' pass a principal into the channel, and a principal will be
983 // created later from the channel's internal data.
984 mPrincipalToInherit
= mTriggeringPrincipal
;
985 if (mPrincipalToInherit
&& aType
!= BrowsingContext::Type::Chrome
) {
986 if (mPrincipalToInherit
->IsSystemPrincipal()) {
987 if (mPrincipalIsExplicit
) {
988 return NS_ERROR_DOM_SECURITY_ERR
;
990 mPrincipalToInherit
= nullptr;
991 mInheritPrincipal
= true;
992 } else if (nsContentUtils::IsExpandedPrincipal(mPrincipalToInherit
)) {
993 if (mPrincipalIsExplicit
) {
994 return NS_ERROR_DOM_SECURITY_ERR
;
996 // Don't inherit from the current page. Just do the safe thing
997 // and pretend that we were loaded by a nullprincipal.
999 // We didn't inherit OriginAttributes here as ExpandedPrincipal doesn't
1000 // have origin attributes.
1001 mPrincipalToInherit
= NullPrincipal::Create(aOriginAttributes
);
1002 mInheritPrincipal
= false;
1006 if (!mPrincipalToInherit
&& !mInheritPrincipal
&& !mPrincipalIsExplicit
) {
1007 // See if there's system or chrome JS code running
1008 mInheritPrincipal
= nsContentUtils::LegacyIsCallerChromeOrNativeCode();
1011 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL
) {
1012 mInheritPrincipal
= false;
1013 // Create a new null principal URI based on our precursor principal.
1014 nsCOMPtr
<nsIURI
> nullPrincipalURI
=
1015 NullPrincipal::CreateURI(mPrincipalToInherit
);
1016 // If mFirstParty is true and the pref 'privacy.firstparty.isolate' is
1017 // enabled, we will set firstPartyDomain on the origin attributes.
1018 OriginAttributes
attrs(aOriginAttributes
);
1020 attrs
.SetFirstPartyDomain(true, nullPrincipalURI
);
1022 mPrincipalToInherit
= NullPrincipal::Create(attrs
, nullPrincipalURI
);
1028 nsresult
nsDocShellLoadState::SetupTriggeringPrincipal(
1029 const mozilla::OriginAttributes
& aOriginAttributes
) {
1030 // If the triggeringPrincipal is not set, we first try to create a principal
1031 // from the referrer, since the referrer URI reflects the web origin that
1032 // triggered the load. If there is no referrer URI, we fall back to using the
1033 // SystemPrincipal. It's safe to assume that no provided triggeringPrincipal
1034 // and no referrer simulate a load that was triggered by the system. It's
1035 // important to note that this block of code needs to appear *after* the block
1036 // where we munge the principalToInherit, because otherwise we would never
1037 // enter code blocks checking if the principalToInherit is null and we will
1038 // end up with a wrong inheritPrincipal flag.
1039 if (!mTriggeringPrincipal
) {
1040 if (mReferrerInfo
) {
1041 nsCOMPtr
<nsIURI
> referrer
= mReferrerInfo
->GetOriginalReferrer();
1042 mTriggeringPrincipal
=
1043 BasePrincipal::CreateContentPrincipal(referrer
, aOriginAttributes
);
1045 if (!mTriggeringPrincipal
) {
1046 return NS_ERROR_FAILURE
;
1049 mTriggeringPrincipal
= nsContentUtils::GetSystemPrincipal();
1055 void nsDocShellLoadState::CalculateLoadURIFlags() {
1056 if (mInheritPrincipal
) {
1058 !mPrincipalToInherit
|| !mPrincipalToInherit
->IsSystemPrincipal(),
1059 "Should not inherit SystemPrincipal");
1060 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL
;
1063 if (mReferrerInfo
&& !mReferrerInfo
->GetSendReferrer()) {
1064 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER
;
1066 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
) {
1067 mInternalLoadFlags
|=
1068 nsDocShell::INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
;
1071 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD
) {
1072 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_FIRST_LOAD
;
1075 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_BYPASS_CLASSIFIER
) {
1076 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER
;
1079 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_FORCE_ALLOW_COOKIES
) {
1080 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES
;
1083 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_BYPASS_LOAD_URI_DELEGATE
) {
1084 mInternalLoadFlags
|=
1085 nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_LOAD_URI_DELEGATE
;
1088 if (!mSrcdocData
.IsVoid()) {
1089 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_IS_SRCDOC
;
1092 if (mForceAllowDataURI
) {
1093 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI
;
1096 if (mOriginalFrameSrc
) {
1097 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC
;
1101 nsLoadFlags
nsDocShellLoadState::CalculateChannelLoadFlags(
1102 BrowsingContext
* aBrowsingContext
, Maybe
<bool> aUriModified
,
1103 Maybe
<bool> aIsEmbeddingBlockedError
) {
1104 MOZ_ASSERT(aBrowsingContext
);
1106 nsLoadFlags loadFlags
= aBrowsingContext
->GetDefaultLoadFlags();
1109 // tag first party URL loads
1110 loadFlags
|= nsIChannel::LOAD_INITIAL_DOCUMENT_URI
;
1113 const uint32_t loadType
= LoadType();
1115 // These values aren't available for loads initiated in the Parent process.
1116 MOZ_ASSERT_IF(loadType
== LOAD_HISTORY
, aUriModified
.isSome());
1117 MOZ_ASSERT_IF(loadType
== LOAD_ERROR_PAGE
, aIsEmbeddingBlockedError
.isSome());
1119 if (loadType
== LOAD_ERROR_PAGE
) {
1120 // Error pages are LOAD_BACKGROUND, unless it's an
1121 // XFO / frame-ancestors error for which we want an error page to load
1122 // but additionally want the onload() event to fire.
1123 if (!*aIsEmbeddingBlockedError
) {
1124 loadFlags
|= nsIChannel::LOAD_BACKGROUND
;
1128 // Mark the channel as being a document URI and allow content sniffing...
1130 nsIChannel::LOAD_DOCUMENT_URI
| nsIChannel::LOAD_CALL_CONTENT_SNIFFERS
;
1132 if (nsDocShell::SandboxFlagsImplyCookies(
1133 aBrowsingContext
->GetSandboxFlags())) {
1134 loadFlags
|= nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE
;
1137 // Load attributes depend on load type...
1139 case LOAD_HISTORY
: {
1140 // Only send VALIDATE_NEVER if mLSHE's URI was never changed via
1141 // push/replaceState (bug 669671).
1142 if (!*aUriModified
) {
1143 loadFlags
|= nsIRequest::VALIDATE_NEVER
;
1148 case LOAD_RELOAD_CHARSET_CHANGE_BYPASS_PROXY_AND_CACHE
:
1149 case LOAD_RELOAD_CHARSET_CHANGE_BYPASS_CACHE
:
1151 nsIRequest::LOAD_BYPASS_CACHE
| nsIRequest::LOAD_FRESH_CONNECTION
;
1155 loadFlags
|= nsIRequest::VALIDATE_ALWAYS
;
1158 case LOAD_NORMAL_BYPASS_CACHE
:
1159 case LOAD_NORMAL_BYPASS_PROXY
:
1160 case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE
:
1161 case LOAD_RELOAD_BYPASS_CACHE
:
1162 case LOAD_RELOAD_BYPASS_PROXY
:
1163 case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE
:
1164 case LOAD_REPLACE_BYPASS_CACHE
:
1166 nsIRequest::LOAD_BYPASS_CACHE
| nsIRequest::LOAD_FRESH_CONNECTION
;
1169 case LOAD_RELOAD_NORMAL
:
1171 browser_soft_reload_only_force_validate_top_level_document()) {
1172 loadFlags
|= nsIRequest::VALIDATE_ALWAYS
;
1178 // Set cache checking flags
1179 switch (StaticPrefs::browser_cache_check_doc_frequency()) {
1181 loadFlags
|= nsIRequest::VALIDATE_ONCE_PER_SESSION
;
1184 loadFlags
|= nsIRequest::VALIDATE_ALWAYS
;
1187 loadFlags
|= nsIRequest::VALIDATE_NEVER
;
1193 if (HasInternalLoadFlags(nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER
)) {
1194 loadFlags
|= nsIChannel::LOAD_BYPASS_URL_CLASSIFIER
;
1197 // If the user pressed shift-reload, then do not allow ServiceWorker
1198 // interception to occur. See step 12.1 of the SW HandleFetch algorithm.
1199 if (IsForceReloadType(loadType
)) {
1200 loadFlags
|= nsIChannel::LOAD_BYPASS_SERVICE_WORKER
;
1206 const char* nsDocShellLoadState::ValidateWithOriginalState(
1207 nsDocShellLoadState
* aOriginalState
) {
1208 MOZ_ASSERT(mLoadIdentifier
== aOriginalState
->mLoadIdentifier
);
1210 // Check that `aOriginalState` is sufficiently similar to this state that
1211 // they're performing the same load.
1212 auto uriEq
= [](nsIURI
* a
, nsIURI
* b
) -> bool {
1214 return a
== b
|| (a
&& b
&& NS_SUCCEEDED(a
->Equals(b
, &eq
)) && eq
);
1216 if (!uriEq(mURI
, aOriginalState
->mURI
)) {
1219 if (!uriEq(mUnstrippedURI
, aOriginalState
->mUnstrippedURI
)) {
1220 return "UnstrippedURI";
1222 if (!uriEq(mOriginalURI
, aOriginalState
->mOriginalURI
)) {
1223 return "OriginalURI";
1225 if (!uriEq(mBaseURI
, aOriginalState
->mBaseURI
)) {
1229 if (!mTriggeringPrincipal
->Equals(aOriginalState
->mTriggeringPrincipal
)) {
1230 return "TriggeringPrincipal";
1232 if (mTriggeringSandboxFlags
!= aOriginalState
->mTriggeringSandboxFlags
) {
1233 return "TriggeringSandboxFlags";
1235 if (mTriggeringRemoteType
!= aOriginalState
->mTriggeringRemoteType
) {
1236 return "TriggeringRemoteType";
1239 if (mOriginalURIString
!= aOriginalState
->mOriginalURIString
) {
1240 return "OriginalURIString";
1243 if (mRemoteTypeOverride
!= aOriginalState
->mRemoteTypeOverride
) {
1244 return "RemoteTypeOverride";
1247 if (mSourceBrowsingContext
.ContextId() !=
1248 aOriginalState
->mSourceBrowsingContext
.ContextId()) {
1249 return "SourceBrowsingContext";
1252 // FIXME: Consider calculating less information in the target process so that
1253 // we can validate more properties more easily.
1254 // FIXME: Identify what other flags will not change when sent through a
1260 DocShellLoadStateInit
nsDocShellLoadState::Serialize(
1261 mozilla::ipc::IProtocol
* aActor
) {
1263 DocShellLoadStateInit loadState
;
1264 loadState
.ResultPrincipalURI() = mResultPrincipalURI
;
1265 loadState
.ResultPrincipalURIIsSome() = mResultPrincipalURIIsSome
;
1266 loadState
.KeepResultPrincipalURIIfSet() = mKeepResultPrincipalURIIfSet
;
1267 loadState
.LoadReplace() = mLoadReplace
;
1268 loadState
.InheritPrincipal() = mInheritPrincipal
;
1269 loadState
.PrincipalIsExplicit() = mPrincipalIsExplicit
;
1270 loadState
.ForceAllowDataURI() = mForceAllowDataURI
;
1271 loadState
.IsExemptFromHTTPSFirstMode() = mIsExemptFromHTTPSFirstMode
;
1272 loadState
.OriginalFrameSrc() = mOriginalFrameSrc
;
1273 loadState
.IsFormSubmission() = mIsFormSubmission
;
1274 loadState
.LoadType() = mLoadType
;
1275 loadState
.Target() = mTarget
;
1276 loadState
.TargetBrowsingContext() = mTargetBrowsingContext
;
1277 loadState
.LoadFlags() = mLoadFlags
;
1278 loadState
.InternalLoadFlags() = mInternalLoadFlags
;
1279 loadState
.FirstParty() = mFirstParty
;
1280 loadState
.HasValidUserGestureActivation() = mHasValidUserGestureActivation
;
1281 loadState
.AllowFocusMove() = mAllowFocusMove
;
1282 loadState
.TypeHint() = mTypeHint
;
1283 loadState
.FileName() = mFileName
;
1284 loadState
.IsFromProcessingFrameAttributes() =
1285 mIsFromProcessingFrameAttributes
;
1286 loadState
.URI() = mURI
;
1287 loadState
.OriginalURI() = mOriginalURI
;
1288 loadState
.SourceBrowsingContext() = mSourceBrowsingContext
;
1289 loadState
.BaseURI() = mBaseURI
;
1290 loadState
.TriggeringPrincipal() = mTriggeringPrincipal
;
1291 loadState
.PrincipalToInherit() = mPrincipalToInherit
;
1292 loadState
.PartitionedPrincipalToInherit() = mPartitionedPrincipalToInherit
;
1293 loadState
.TriggeringSandboxFlags() = mTriggeringSandboxFlags
;
1294 loadState
.TriggeringWindowId() = mTriggeringWindowId
;
1295 loadState
.TriggeringStorageAccess() = mTriggeringStorageAccess
;
1296 loadState
.TriggeringRemoteType() = mTriggeringRemoteType
;
1297 loadState
.WasSchemelessInput() = mWasSchemelessInput
;
1298 loadState
.Csp() = mCsp
;
1299 loadState
.OriginalURIString() = mOriginalURIString
;
1300 loadState
.CancelContentJSEpoch() = mCancelContentJSEpoch
;
1301 loadState
.ReferrerInfo() = mReferrerInfo
;
1302 loadState
.PostDataStream() = mPostDataStream
;
1303 loadState
.HeadersStream() = mHeadersStream
;
1304 loadState
.SrcdocData() = mSrcdocData
;
1305 loadState
.ResultPrincipalURI() = mResultPrincipalURI
;
1306 loadState
.LoadIdentifier() = mLoadIdentifier
;
1307 loadState
.ChannelInitialized() = mChannelInitialized
;
1308 loadState
.IsMetaRefresh() = mIsMetaRefresh
;
1309 if (mLoadingSessionHistoryInfo
) {
1310 loadState
.loadingSessionHistoryInfo().emplace(*mLoadingSessionHistoryInfo
);
1312 loadState
.UnstrippedURI() = mUnstrippedURI
;
1313 loadState
.RemoteTypeOverride() = mRemoteTypeOverride
;
1315 if (XRE_IsParentProcess()) {
1316 mozilla::ipc::IToplevelProtocol
* top
= aActor
->ToplevelProtocol();
1317 MOZ_RELEASE_ASSERT(top
&&
1318 top
->GetProtocolId() ==
1319 mozilla::ipc::ProtocolId::PContentMsgStart
&&
1320 top
->GetSide() == mozilla::ipc::ParentSide
,
1321 "nsDocShellLoadState must be sent over PContent");
1322 ContentParent
* cp
= static_cast<ContentParent
*>(top
);
1323 cp
->StorePendingLoadState(this);
1329 nsIURI
* nsDocShellLoadState::GetUnstrippedURI() const { return mUnstrippedURI
; }
1331 void nsDocShellLoadState::SetUnstrippedURI(nsIURI
* aUnstrippedURI
) {
1332 mUnstrippedURI
= aUnstrippedURI
;