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 const nsCString
& nsDocShellLoadState::GetEffectiveTriggeringRemoteType() const {
905 // Consider non-errorpage loads from session history as being triggred by the
906 // parent process, as we'll validate them against the history entry.
908 // NOTE: Keep this check in-sync with the session-history validation check in
909 // `DocumentLoadListener::Open`!
910 if (LoadIsFromSessionHistory() && LoadType() != LOAD_ERROR_PAGE
) {
911 return NOT_REMOTE_TYPE
;
913 return mTriggeringRemoteType
;
916 void nsDocShellLoadState::SetTriggeringRemoteType(
917 const nsACString
& aTriggeringRemoteType
) {
918 MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "only settable in parent");
919 mTriggeringRemoteType
= aTriggeringRemoteType
;
922 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
923 void nsDocShellLoadState::AssertProcessCouldTriggerLoadIfSystem() {
924 // Early check to see if we're trying to start a file URI load with a system
925 // principal within a web content process.
926 // If this assertion fails, the load will fail later during
927 // nsContentSecurityManager checks, however this assertion should happen
928 // closer to whichever caller is triggering the system-principal load.
929 if (mozilla::SessionHistoryInParent() &&
930 TriggeringPrincipal()->IsSystemPrincipal() &&
931 mozilla::dom::IsWebRemoteType(GetEffectiveTriggeringRemoteType())) {
932 bool localFile
= false;
933 if (NS_SUCCEEDED(NS_URIChainHasFlags(
934 URI(), nsIProtocolHandler::URI_IS_LOCAL_FILE
, &localFile
)) &&
936 NS_WARNING(nsPrintfCString("Unexpected system load of file URI (%s) from "
937 "web content process",
938 URI()->GetSpecOrDefault().get())
940 MOZ_CRASH("Unexpected system load of file URI from web content process");
946 nsresult
nsDocShellLoadState::SetupInheritingPrincipal(
947 BrowsingContext::Type aType
,
948 const mozilla::OriginAttributes
& aOriginAttributes
) {
949 // We need a principalToInherit.
951 // If principalIsExplicit is not set there are 4 possibilities:
952 // (1) If the system principal or an expanded principal was passed
953 // in and we're a typeContent docshell, inherit the principal
954 // from the current document instead.
955 // (2) In all other cases when the principal passed in is not null,
956 // use that principal.
957 // (3) If the caller has allowed inheriting from the current document,
958 // or if we're being called from system code (eg chrome JS or pure
959 // C++) then inheritPrincipal should be true and InternalLoad will get
960 // a principal from the current document. If none of these things are
962 // (4) we don't pass a principal into the channel, and a principal will be
963 // created later from the channel's internal data.
965 // If principalIsExplicit *is* set, there are 4 possibilities
966 // (1) If the system principal or an expanded principal was passed in
967 // and we're a typeContent docshell, return an error.
968 // (2) In all other cases when the principal passed in is not null,
969 // use that principal.
970 // (3) If the caller has allowed inheriting from the current document,
971 // then inheritPrincipal should be true and InternalLoad will get
972 // a principal from the current document. If none of these things are
974 // (4) we dont' pass a principal into the channel, and a principal will be
975 // created later from the channel's internal data.
976 mPrincipalToInherit
= mTriggeringPrincipal
;
977 if (mPrincipalToInherit
&& aType
!= BrowsingContext::Type::Chrome
) {
978 if (mPrincipalToInherit
->IsSystemPrincipal()) {
979 if (mPrincipalIsExplicit
) {
980 return NS_ERROR_DOM_SECURITY_ERR
;
982 mPrincipalToInherit
= nullptr;
983 mInheritPrincipal
= true;
984 } else if (nsContentUtils::IsExpandedPrincipal(mPrincipalToInherit
)) {
985 if (mPrincipalIsExplicit
) {
986 return NS_ERROR_DOM_SECURITY_ERR
;
988 // Don't inherit from the current page. Just do the safe thing
989 // and pretend that we were loaded by a nullprincipal.
991 // We didn't inherit OriginAttributes here as ExpandedPrincipal doesn't
992 // have origin attributes.
993 mPrincipalToInherit
= NullPrincipal::Create(aOriginAttributes
);
994 mInheritPrincipal
= false;
998 if (!mPrincipalToInherit
&& !mInheritPrincipal
&& !mPrincipalIsExplicit
) {
999 // See if there's system or chrome JS code running
1000 mInheritPrincipal
= nsContentUtils::LegacyIsCallerChromeOrNativeCode();
1003 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL
) {
1004 mInheritPrincipal
= false;
1005 // Create a new null principal URI based on our precursor principal.
1006 nsCOMPtr
<nsIURI
> nullPrincipalURI
=
1007 NullPrincipal::CreateURI(mPrincipalToInherit
);
1008 // If mFirstParty is true and the pref 'privacy.firstparty.isolate' is
1009 // enabled, we will set firstPartyDomain on the origin attributes.
1010 OriginAttributes
attrs(aOriginAttributes
);
1012 attrs
.SetFirstPartyDomain(true, nullPrincipalURI
);
1014 mPrincipalToInherit
= NullPrincipal::Create(attrs
, nullPrincipalURI
);
1020 nsresult
nsDocShellLoadState::SetupTriggeringPrincipal(
1021 const mozilla::OriginAttributes
& aOriginAttributes
) {
1022 // If the triggeringPrincipal is not set, we first try to create a principal
1023 // from the referrer, since the referrer URI reflects the web origin that
1024 // triggered the load. If there is no referrer URI, we fall back to using the
1025 // SystemPrincipal. It's safe to assume that no provided triggeringPrincipal
1026 // and no referrer simulate a load that was triggered by the system. It's
1027 // important to note that this block of code needs to appear *after* the block
1028 // where we munge the principalToInherit, because otherwise we would never
1029 // enter code blocks checking if the principalToInherit is null and we will
1030 // end up with a wrong inheritPrincipal flag.
1031 if (!mTriggeringPrincipal
) {
1032 if (mReferrerInfo
) {
1033 nsCOMPtr
<nsIURI
> referrer
= mReferrerInfo
->GetOriginalReferrer();
1034 mTriggeringPrincipal
=
1035 BasePrincipal::CreateContentPrincipal(referrer
, aOriginAttributes
);
1037 if (!mTriggeringPrincipal
) {
1038 return NS_ERROR_FAILURE
;
1041 mTriggeringPrincipal
= nsContentUtils::GetSystemPrincipal();
1047 void nsDocShellLoadState::CalculateLoadURIFlags() {
1048 if (mInheritPrincipal
) {
1050 !mPrincipalToInherit
|| !mPrincipalToInherit
->IsSystemPrincipal(),
1051 "Should not inherit SystemPrincipal");
1052 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL
;
1055 if (mReferrerInfo
&& !mReferrerInfo
->GetSendReferrer()) {
1056 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER
;
1058 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
) {
1059 mInternalLoadFlags
|=
1060 nsDocShell::INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
;
1063 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD
) {
1064 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_FIRST_LOAD
;
1067 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_BYPASS_CLASSIFIER
) {
1068 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER
;
1071 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_FORCE_ALLOW_COOKIES
) {
1072 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES
;
1075 if (mLoadFlags
& nsIWebNavigation::LOAD_FLAGS_BYPASS_LOAD_URI_DELEGATE
) {
1076 mInternalLoadFlags
|=
1077 nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_LOAD_URI_DELEGATE
;
1080 if (!mSrcdocData
.IsVoid()) {
1081 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_IS_SRCDOC
;
1084 if (mForceAllowDataURI
) {
1085 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI
;
1088 if (mOriginalFrameSrc
) {
1089 mInternalLoadFlags
|= nsDocShell::INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC
;
1093 nsLoadFlags
nsDocShellLoadState::CalculateChannelLoadFlags(
1094 BrowsingContext
* aBrowsingContext
, Maybe
<bool> aUriModified
,
1095 Maybe
<bool> aIsXFOError
) {
1096 MOZ_ASSERT(aBrowsingContext
);
1098 nsLoadFlags loadFlags
= aBrowsingContext
->GetDefaultLoadFlags();
1101 // tag first party URL loads
1102 loadFlags
|= nsIChannel::LOAD_INITIAL_DOCUMENT_URI
;
1105 const uint32_t loadType
= LoadType();
1107 // These values aren't available for loads initiated in the Parent process.
1108 MOZ_ASSERT_IF(loadType
== LOAD_HISTORY
, aUriModified
.isSome());
1109 MOZ_ASSERT_IF(loadType
== LOAD_ERROR_PAGE
, aIsXFOError
.isSome());
1111 if (loadType
== LOAD_ERROR_PAGE
) {
1112 // Error pages are LOAD_BACKGROUND, unless it's an
1113 // XFO error for which we want an error page to load
1114 // but additionally want the onload() event to fire.
1115 if (!*aIsXFOError
) {
1116 loadFlags
|= nsIChannel::LOAD_BACKGROUND
;
1120 // Mark the channel as being a document URI and allow content sniffing...
1122 nsIChannel::LOAD_DOCUMENT_URI
| nsIChannel::LOAD_CALL_CONTENT_SNIFFERS
;
1124 if (nsDocShell::SandboxFlagsImplyCookies(
1125 aBrowsingContext
->GetSandboxFlags())) {
1126 loadFlags
|= nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE
;
1129 // Load attributes depend on load type...
1131 case LOAD_HISTORY
: {
1132 // Only send VALIDATE_NEVER if mLSHE's URI was never changed via
1133 // push/replaceState (bug 669671).
1134 if (!*aUriModified
) {
1135 loadFlags
|= nsIRequest::VALIDATE_NEVER
;
1140 case LOAD_RELOAD_CHARSET_CHANGE_BYPASS_PROXY_AND_CACHE
:
1141 case LOAD_RELOAD_CHARSET_CHANGE_BYPASS_CACHE
:
1143 nsIRequest::LOAD_BYPASS_CACHE
| nsIRequest::LOAD_FRESH_CONNECTION
;
1147 loadFlags
|= nsIRequest::VALIDATE_ALWAYS
;
1150 case LOAD_NORMAL_BYPASS_CACHE
:
1151 case LOAD_NORMAL_BYPASS_PROXY
:
1152 case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE
:
1153 case LOAD_RELOAD_BYPASS_CACHE
:
1154 case LOAD_RELOAD_BYPASS_PROXY
:
1155 case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE
:
1156 case LOAD_REPLACE_BYPASS_CACHE
:
1158 nsIRequest::LOAD_BYPASS_CACHE
| nsIRequest::LOAD_FRESH_CONNECTION
;
1161 case LOAD_RELOAD_NORMAL
:
1163 browser_soft_reload_only_force_validate_top_level_document()) {
1164 loadFlags
|= nsIRequest::VALIDATE_ALWAYS
;
1170 // Set cache checking flags
1171 switch (StaticPrefs::browser_cache_check_doc_frequency()) {
1173 loadFlags
|= nsIRequest::VALIDATE_ONCE_PER_SESSION
;
1176 loadFlags
|= nsIRequest::VALIDATE_ALWAYS
;
1179 loadFlags
|= nsIRequest::VALIDATE_NEVER
;
1185 if (HasInternalLoadFlags(nsDocShell::INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER
)) {
1186 loadFlags
|= nsIChannel::LOAD_BYPASS_URL_CLASSIFIER
;
1189 // If the user pressed shift-reload, then do not allow ServiceWorker
1190 // interception to occur. See step 12.1 of the SW HandleFetch algorithm.
1191 if (IsForceReloadType(loadType
)) {
1192 loadFlags
|= nsIChannel::LOAD_BYPASS_SERVICE_WORKER
;
1198 const char* nsDocShellLoadState::ValidateWithOriginalState(
1199 nsDocShellLoadState
* aOriginalState
) {
1200 MOZ_ASSERT(mLoadIdentifier
== aOriginalState
->mLoadIdentifier
);
1202 // Check that `aOriginalState` is sufficiently similar to this state that
1203 // they're performing the same load.
1204 auto uriEq
= [](nsIURI
* a
, nsIURI
* b
) -> bool {
1206 return a
== b
|| (a
&& b
&& NS_SUCCEEDED(a
->Equals(b
, &eq
)) && eq
);
1208 if (!uriEq(mURI
, aOriginalState
->mURI
)) {
1211 if (!uriEq(mUnstrippedURI
, aOriginalState
->mUnstrippedURI
)) {
1212 return "UnstrippedURI";
1214 if (!uriEq(mOriginalURI
, aOriginalState
->mOriginalURI
)) {
1215 return "OriginalURI";
1217 if (!uriEq(mBaseURI
, aOriginalState
->mBaseURI
)) {
1221 if (!mTriggeringPrincipal
->Equals(aOriginalState
->mTriggeringPrincipal
)) {
1222 return "TriggeringPrincipal";
1224 if (mTriggeringSandboxFlags
!= aOriginalState
->mTriggeringSandboxFlags
) {
1225 return "TriggeringSandboxFlags";
1227 if (mTriggeringRemoteType
!= aOriginalState
->mTriggeringRemoteType
) {
1228 return "TriggeringRemoteType";
1231 if (mOriginalURIString
!= aOriginalState
->mOriginalURIString
) {
1232 return "OriginalURIString";
1235 if (mRemoteTypeOverride
!= aOriginalState
->mRemoteTypeOverride
) {
1236 return "RemoteTypeOverride";
1239 if (mSourceBrowsingContext
.ContextId() !=
1240 aOriginalState
->mSourceBrowsingContext
.ContextId()) {
1241 return "SourceBrowsingContext";
1244 // FIXME: Consider calculating less information in the target process so that
1245 // we can validate more properties more easily.
1246 // FIXME: Identify what other flags will not change when sent through a
1252 DocShellLoadStateInit
nsDocShellLoadState::Serialize(
1253 mozilla::ipc::IProtocol
* aActor
) {
1255 DocShellLoadStateInit loadState
;
1256 loadState
.ResultPrincipalURI() = mResultPrincipalURI
;
1257 loadState
.ResultPrincipalURIIsSome() = mResultPrincipalURIIsSome
;
1258 loadState
.KeepResultPrincipalURIIfSet() = mKeepResultPrincipalURIIfSet
;
1259 loadState
.LoadReplace() = mLoadReplace
;
1260 loadState
.InheritPrincipal() = mInheritPrincipal
;
1261 loadState
.PrincipalIsExplicit() = mPrincipalIsExplicit
;
1262 loadState
.ForceAllowDataURI() = mForceAllowDataURI
;
1263 loadState
.IsExemptFromHTTPSFirstMode() = mIsExemptFromHTTPSFirstMode
;
1264 loadState
.OriginalFrameSrc() = mOriginalFrameSrc
;
1265 loadState
.IsFormSubmission() = mIsFormSubmission
;
1266 loadState
.LoadType() = mLoadType
;
1267 loadState
.Target() = mTarget
;
1268 loadState
.TargetBrowsingContext() = mTargetBrowsingContext
;
1269 loadState
.LoadFlags() = mLoadFlags
;
1270 loadState
.InternalLoadFlags() = mInternalLoadFlags
;
1271 loadState
.FirstParty() = mFirstParty
;
1272 loadState
.HasValidUserGestureActivation() = mHasValidUserGestureActivation
;
1273 loadState
.AllowFocusMove() = mAllowFocusMove
;
1274 loadState
.TypeHint() = mTypeHint
;
1275 loadState
.FileName() = mFileName
;
1276 loadState
.IsFromProcessingFrameAttributes() =
1277 mIsFromProcessingFrameAttributes
;
1278 loadState
.URI() = mURI
;
1279 loadState
.OriginalURI() = mOriginalURI
;
1280 loadState
.SourceBrowsingContext() = mSourceBrowsingContext
;
1281 loadState
.BaseURI() = mBaseURI
;
1282 loadState
.TriggeringPrincipal() = mTriggeringPrincipal
;
1283 loadState
.PrincipalToInherit() = mPrincipalToInherit
;
1284 loadState
.PartitionedPrincipalToInherit() = mPartitionedPrincipalToInherit
;
1285 loadState
.TriggeringSandboxFlags() = mTriggeringSandboxFlags
;
1286 loadState
.TriggeringWindowId() = mTriggeringWindowId
;
1287 loadState
.TriggeringStorageAccess() = mTriggeringStorageAccess
;
1288 loadState
.TriggeringRemoteType() = mTriggeringRemoteType
;
1289 loadState
.WasSchemelessInput() = mWasSchemelessInput
;
1290 loadState
.Csp() = mCsp
;
1291 loadState
.OriginalURIString() = mOriginalURIString
;
1292 loadState
.CancelContentJSEpoch() = mCancelContentJSEpoch
;
1293 loadState
.ReferrerInfo() = mReferrerInfo
;
1294 loadState
.PostDataStream() = mPostDataStream
;
1295 loadState
.HeadersStream() = mHeadersStream
;
1296 loadState
.SrcdocData() = mSrcdocData
;
1297 loadState
.ResultPrincipalURI() = mResultPrincipalURI
;
1298 loadState
.LoadIdentifier() = mLoadIdentifier
;
1299 loadState
.ChannelInitialized() = mChannelInitialized
;
1300 loadState
.IsMetaRefresh() = mIsMetaRefresh
;
1301 if (mLoadingSessionHistoryInfo
) {
1302 loadState
.loadingSessionHistoryInfo().emplace(*mLoadingSessionHistoryInfo
);
1304 loadState
.UnstrippedURI() = mUnstrippedURI
;
1305 loadState
.RemoteTypeOverride() = mRemoteTypeOverride
;
1307 if (XRE_IsParentProcess()) {
1308 mozilla::ipc::IToplevelProtocol
* top
= aActor
->ToplevelProtocol();
1309 MOZ_RELEASE_ASSERT(top
&&
1310 top
->GetProtocolId() ==
1311 mozilla::ipc::ProtocolId::PContentMsgStart
&&
1312 top
->GetSide() == mozilla::ipc::ParentSide
,
1313 "nsDocShellLoadState must be sent over PContent");
1314 ContentParent
* cp
= static_cast<ContentParent
*>(top
);
1315 cp
->StorePendingLoadState(this);
1321 nsIURI
* nsDocShellLoadState::GetUnstrippedURI() const { return mUnstrippedURI
; }
1323 void nsDocShellLoadState::SetUnstrippedURI(nsIURI
* aUnstrippedURI
) {
1324 mUnstrippedURI
= aUnstrippedURI
;