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