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 #ifndef nsDocShellLoadState_h__
8 #define nsDocShellLoadState_h__
10 #include "mozilla/dom/BrowsingContext.h"
11 #include "mozilla/dom/SessionHistoryEntry.h"
14 #include "mozilla/Maybe.h"
17 #include "nsDocShellLoadTypes.h"
18 #include "nsTArrayForwardDeclare.h"
20 class nsIContentSecurityPolicy
;
26 class nsIReferrerInfo
;
28 class OriginAttributes
;
29 template <typename
, class>
32 class DocShellLoadStateInit
;
34 } // namespace mozilla
37 * nsDocShellLoadState contains setup information used in a nsIDocShell::loadURI
40 class nsDocShellLoadState final
{
41 using BrowsingContext
= mozilla::dom::BrowsingContext
;
43 using MaybeDiscarded
= mozilla::dom::MaybeDiscarded
<T
>;
46 NS_INLINE_DECL_REFCOUNTING(nsDocShellLoadState
);
48 explicit nsDocShellLoadState(nsIURI
* aURI
);
49 explicit nsDocShellLoadState(
50 const mozilla::dom::DocShellLoadStateInit
& aLoadState
,
51 mozilla::ipc::IProtocol
* aActor
, bool* aReadSuccess
);
52 explicit nsDocShellLoadState(const nsDocShellLoadState
& aOther
);
53 nsDocShellLoadState(nsIURI
* aURI
, uint64_t aLoadIdentifier
);
55 static nsresult
CreateFromPendingChannel(nsIChannel
* aPendingChannel
,
56 uint64_t aLoadIdentifier
,
58 nsDocShellLoadState
** aResult
);
60 static nsresult
CreateFromLoadURIOptions(
61 BrowsingContext
* aBrowsingContext
, const nsAString
& aURI
,
62 const mozilla::dom::LoadURIOptions
& aLoadURIOptions
,
63 nsDocShellLoadState
** aResult
);
64 static nsresult
CreateFromLoadURIOptions(
65 BrowsingContext
* aBrowsingContext
, nsIURI
* aURI
,
66 const mozilla::dom::LoadURIOptions
& aLoadURIOptions
,
67 nsDocShellLoadState
** aResult
);
69 // Getters and Setters
71 nsIReferrerInfo
* GetReferrerInfo() const;
73 void SetReferrerInfo(nsIReferrerInfo
* aReferrerInfo
);
77 void SetURI(nsIURI
* aURI
);
79 nsIURI
* OriginalURI() const;
81 void SetOriginalURI(nsIURI
* aOriginalURI
);
83 nsIURI
* ResultPrincipalURI() const;
85 void SetResultPrincipalURI(nsIURI
* aResultPrincipalURI
);
87 bool ResultPrincipalURIIsSome() const;
89 void SetResultPrincipalURIIsSome(bool aIsSome
);
91 bool KeepResultPrincipalURIIfSet() const;
93 void SetKeepResultPrincipalURIIfSet(bool aKeep
);
95 nsIPrincipal
* PrincipalToInherit() const;
97 void SetPrincipalToInherit(nsIPrincipal
* aPrincipalToInherit
);
99 nsIPrincipal
* PartitionedPrincipalToInherit() const;
101 void SetPartitionedPrincipalToInherit(
102 nsIPrincipal
* aPartitionedPrincipalToInherit
);
104 bool LoadReplace() const;
106 void SetLoadReplace(bool aLoadReplace
);
108 nsIPrincipal
* TriggeringPrincipal() const;
110 void SetTriggeringPrincipal(nsIPrincipal
* aTriggeringPrincipal
);
112 uint32_t TriggeringSandboxFlags() const;
114 void SetTriggeringSandboxFlags(uint32_t aTriggeringSandboxFlags
);
116 uint64_t TriggeringWindowId() const;
118 void SetTriggeringWindowId(uint64_t aTriggeringWindowId
);
120 bool TriggeringStorageAccess() const;
122 void SetTriggeringStorageAccess(bool aTriggeringStorageAccess
);
124 nsIContentSecurityPolicy
* Csp() const;
126 void SetCsp(nsIContentSecurityPolicy
* aCsp
);
128 bool InheritPrincipal() const;
130 void SetInheritPrincipal(bool aInheritPrincipal
);
132 bool PrincipalIsExplicit() const;
134 void SetPrincipalIsExplicit(bool aPrincipalIsExplicit
);
136 // If true, "beforeunload" event listeners were notified by the creater of the
137 // LoadState and given the chance to abort the navigation, and should not be
139 bool NotifiedBeforeUnloadListeners() const;
141 void SetNotifiedBeforeUnloadListeners(bool aNotifiedBeforeUnloadListeners
);
143 bool ForceAllowDataURI() const;
145 void SetForceAllowDataURI(bool aForceAllowDataURI
);
147 bool IsExemptFromHTTPSFirstMode() const;
149 void SetIsExemptFromHTTPSFirstMode(bool aIsExemptFromHTTPSFirstMode
);
151 bool OriginalFrameSrc() const;
153 void SetOriginalFrameSrc(bool aOriginalFrameSrc
);
155 bool IsFormSubmission() const;
157 void SetIsFormSubmission(bool aIsFormSubmission
);
159 uint32_t LoadType() const;
161 void SetLoadType(uint32_t aLoadType
);
163 nsISHEntry
* SHEntry() const;
165 void SetSHEntry(nsISHEntry
* aSHEntry
);
167 const mozilla::dom::LoadingSessionHistoryInfo
* GetLoadingSessionHistoryInfo()
170 // Copies aLoadingInfo and stores the copy in this nsDocShellLoadState.
171 void SetLoadingSessionHistoryInfo(
172 const mozilla::dom::LoadingSessionHistoryInfo
& aLoadingInfo
);
174 // Stores aLoadingInfo in this nsDocShellLoadState.
175 void SetLoadingSessionHistoryInfo(
176 mozilla::UniquePtr
<mozilla::dom::LoadingSessionHistoryInfo
> aLoadingInfo
);
178 bool LoadIsFromSessionHistory() const;
180 const nsString
& Target() const;
182 void SetTarget(const nsAString
& aTarget
);
184 nsIInputStream
* PostDataStream() const;
186 void SetPostDataStream(nsIInputStream
* aStream
);
188 nsIInputStream
* HeadersStream() const;
190 void SetHeadersStream(nsIInputStream
* aHeadersStream
);
192 bool IsSrcdocLoad() const;
194 const nsString
& SrcdocData() const;
196 void SetSrcdocData(const nsAString
& aSrcdocData
);
198 const MaybeDiscarded
<BrowsingContext
>& SourceBrowsingContext() const {
199 return mSourceBrowsingContext
;
202 void SetSourceBrowsingContext(BrowsingContext
*);
204 void SetAllowFocusMove(bool aAllow
) { mAllowFocusMove
= aAllow
; }
206 bool AllowFocusMove() const { return mAllowFocusMove
; }
208 const MaybeDiscarded
<BrowsingContext
>& TargetBrowsingContext() const {
209 return mTargetBrowsingContext
;
212 void SetTargetBrowsingContext(BrowsingContext
* aTargetBrowsingContext
);
214 nsIURI
* BaseURI() const;
216 void SetBaseURI(nsIURI
* aBaseURI
);
218 // Helper function allowing convenient work with mozilla::Maybe in C++, hiding
219 // resultPrincipalURI and resultPrincipalURIIsSome attributes from the
221 void GetMaybeResultPrincipalURI(
222 mozilla::Maybe
<nsCOMPtr
<nsIURI
>>& aRPURI
) const;
224 void SetMaybeResultPrincipalURI(
225 mozilla::Maybe
<nsCOMPtr
<nsIURI
>> const& aRPURI
);
227 uint32_t LoadFlags() const;
229 void SetLoadFlags(uint32_t aFlags
);
231 void SetLoadFlag(uint32_t aFlag
);
233 void UnsetLoadFlag(uint32_t aFlag
);
235 bool HasLoadFlags(uint32_t aFlag
);
237 uint32_t InternalLoadFlags() const;
239 void SetInternalLoadFlags(uint32_t aFlags
);
241 void SetInternalLoadFlag(uint32_t aFlag
);
243 void UnsetInternalLoadFlag(uint32_t aFlag
);
245 bool HasInternalLoadFlags(uint32_t aFlag
);
247 bool FirstParty() const;
249 void SetFirstParty(bool aFirstParty
);
251 bool HasValidUserGestureActivation() const;
253 void SetHasValidUserGestureActivation(bool HasValidUserGestureActivation
);
255 const nsCString
& TypeHint() const;
257 void SetTypeHint(const nsCString
& aTypeHint
);
259 const nsString
& FileName() const;
261 void SetFileName(const nsAString
& aFileName
);
263 nsIURI
* GetUnstrippedURI() const;
265 void SetUnstrippedURI(nsIURI
* aUnstrippedURI
);
267 // Give the type of DocShell we're loading into (chrome/content/etc) and
268 // origin attributes for the URI we're loading, figure out if we should
269 // inherit our principal from the document the load was requested from, or
270 // else if the principal should be set up later in the process (after loads).
271 // See comments in function for more info on principal selection algorithm
272 nsresult
SetupInheritingPrincipal(
273 mozilla::dom::BrowsingContext::Type aType
,
274 const mozilla::OriginAttributes
& aOriginAttributes
);
276 // If no triggering principal exists at the moment, create one using referrer
277 // information and origin attributes.
278 nsresult
SetupTriggeringPrincipal(
279 const mozilla::OriginAttributes
& aOriginAttributes
);
281 void SetIsFromProcessingFrameAttributes() {
282 mIsFromProcessingFrameAttributes
= true;
284 bool GetIsFromProcessingFrameAttributes() const {
285 return mIsFromProcessingFrameAttributes
;
288 nsIChannel
* GetPendingRedirectedChannel() {
289 return mPendingRedirectedChannel
;
292 uint64_t GetPendingRedirectChannelRegistrarId() const {
293 return mChannelRegistrarId
;
296 void SetOriginalURIString(const nsCString
& aOriginalURI
) {
297 mOriginalURIString
.emplace(aOriginalURI
);
299 const mozilla::Maybe
<nsCString
>& GetOriginalURIString() const {
300 return mOriginalURIString
;
303 void SetCancelContentJSEpoch(int32_t aCancelEpoch
) {
304 mCancelContentJSEpoch
.emplace(aCancelEpoch
);
306 const mozilla::Maybe
<int32_t>& GetCancelContentJSEpoch() const {
307 return mCancelContentJSEpoch
;
310 uint64_t GetLoadIdentifier() const { return mLoadIdentifier
; }
312 void SetChannelInitialized(bool aInitilized
) {
313 mChannelInitialized
= aInitilized
;
316 bool GetChannelInitialized() const { return mChannelInitialized
; }
318 void SetIsMetaRefresh(bool aMetaRefresh
) { mIsMetaRefresh
= aMetaRefresh
; }
320 bool IsMetaRefresh() const { return mIsMetaRefresh
; }
322 const mozilla::Maybe
<nsCString
>& GetRemoteTypeOverride() const {
323 return mRemoteTypeOverride
;
326 void SetRemoteTypeOverride(const nsCString
& aRemoteTypeOverride
);
328 void SetWasSchemelessInput(bool aWasSchemelessInput
) {
329 mWasSchemelessInput
= aWasSchemelessInput
;
332 bool GetWasSchemelessInput() { return mWasSchemelessInput
; }
334 // Determine the remote type of the process which should be considered
335 // responsible for this load for the purposes of security checks.
337 // This will generally be the process which created the nsDocShellLoadState
338 // originally, however non-errorpage history loads are always considered to be
339 // triggered by the parent process, as we can validate them against the
341 const nsCString
& GetEffectiveTriggeringRemoteType() const;
343 void SetTriggeringRemoteType(const nsACString
& aTriggeringRemoteType
);
345 // Diagnostic assert if this is a system-principal triggered load, and it is
346 // trivial to determine that the effective triggering remote type would not be
347 // allowed to perform this load.
349 // This is called early during the load to crash as close to the cause as
350 // possible. See bug 1838686 for details.
351 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
352 void AssertProcessCouldTriggerLoadIfSystem();
354 void AssertProcessCouldTriggerLoadIfSystem() {}
357 // When loading a document through nsDocShell::LoadURI(), a special set of
358 // flags needs to be set based on other values in nsDocShellLoadState. This
359 // function calculates those flags, before the LoadState is passed to
360 // nsDocShell::InternalLoad.
361 void CalculateLoadURIFlags();
363 // Compute the load flags to be used by creating channel. aUriModified and
364 // aIsEmbeddingBlockedError are expected to be Nothing when called from parent
366 nsLoadFlags
CalculateChannelLoadFlags(
367 mozilla::dom::BrowsingContext
* aBrowsingContext
,
368 mozilla::Maybe
<bool> aUriModified
,
369 mozilla::Maybe
<bool> aIsEmbeddingBlockedError
);
371 mozilla::dom::DocShellLoadStateInit
Serialize(
372 mozilla::ipc::IProtocol
* aActor
);
374 void SetLoadIsFromSessionHistory(int32_t aOffset
, bool aLoadingCurrentEntry
);
375 void ClearLoadIsFromSessionHistory();
377 void MaybeStripTrackerQueryStrings(mozilla::dom::BrowsingContext
* aContext
);
380 // Destructor can't be defaulted or inlined, as header doesn't have all type
381 // includes it needs to do so.
382 ~nsDocShellLoadState();
384 // Given the original `nsDocShellLoadState` which was sent to a content
385 // process, validate that they corespond to the same load.
386 // Returns a static (telemetry-safe) string naming what did not match, or
387 // nullptr if it succeeds.
388 const char* ValidateWithOriginalState(nsDocShellLoadState
* aOriginalState
);
390 static nsresult
CreateFromLoadURIOptions(
391 BrowsingContext
* aBrowsingContext
, nsIURI
* aURI
,
392 const mozilla::dom::LoadURIOptions
& aLoadURIOptions
,
393 uint32_t aLoadFlagsOverride
, nsIInputStream
* aPostDataOverride
,
394 nsDocShellLoadState
** aResult
);
396 // This is the referrer for the load.
397 nsCOMPtr
<nsIReferrerInfo
> mReferrerInfo
;
399 // The URI we are navigating to. Will not be null once set.
400 nsCOMPtr
<nsIURI
> mURI
;
402 // The URI to set as the originalURI on the channel that does the load. If
403 // null, aURI will be set as the originalURI.
404 nsCOMPtr
<nsIURI
> mOriginalURI
;
406 // The URI to be set to loadInfo.resultPrincipalURI
407 // - When Nothing, there will be no change
408 // - When Some, the principal URI will overwrite even
409 // with a null value.
411 // Valid only if mResultPrincipalURIIsSome is true (has the same meaning as
412 // isSome() on mozilla::Maybe.)
413 nsCOMPtr
<nsIURI
> mResultPrincipalURI
;
414 bool mResultPrincipalURIIsSome
;
416 // The principal of the load, that is, the entity responsible for causing the
417 // load to occur. In most cases the referrer and the triggeringPrincipal's URI
418 // will be identical.
420 // Please note that this is the principal that is used for security checks. If
421 // the argument aURI is provided by the web, then please do not pass a
422 // SystemPrincipal as the triggeringPrincipal.
423 nsCOMPtr
<nsIPrincipal
> mTriggeringPrincipal
;
425 // The SandboxFlags of the load, that are, the SandboxFlags of the entity
426 // responsible for causing the load to occur. Most likely this are the
427 // SandboxFlags of the document that started the load.
428 uint32_t mTriggeringSandboxFlags
;
430 // The window ID and current "has storage access" value of the entity
431 // triggering the load. This allows the identification of self-initiated
432 // same-origin navigations that should propogate unpartitioned storage access.
433 uint64_t mTriggeringWindowId
;
434 bool mTriggeringStorageAccess
;
436 // The CSP of the load, that is, the CSP of the entity responsible for causing
437 // the load to occur. Most likely this is the CSP of the document that started
438 // the load. In case the entity starting the load did not use a CSP, then mCsp
439 // can be null. Please note that this is also the CSP that will be applied to
440 // the load in case the load encounters a server side redirect.
441 nsCOMPtr
<nsIContentSecurityPolicy
> mCsp
;
443 // If a refresh is caused by http-equiv="refresh" we want to set
444 // aResultPrincipalURI, but we do not want to overwrite the channel's
445 // ResultPrincipalURI, if it has already been set on the channel by a protocol
447 bool mKeepResultPrincipalURIIfSet
;
449 // If set LOAD_REPLACE flag will be set on the channel. If aOriginalURI is
450 // null, this argument is ignored.
453 // If this attribute is true and no triggeringPrincipal is specified,
454 // copy the principal from the referring document.
455 bool mInheritPrincipal
;
457 // If this attribute is true only ever use the principal specified
458 // by the triggeringPrincipal and inheritPrincipal attributes.
459 // If there are security reasons for why this is unsafe, such
460 // as trying to use a systemprincipal as the triggeringPrincipal
461 // for a content docshell the load fails.
462 bool mPrincipalIsExplicit
;
464 bool mNotifiedBeforeUnloadListeners
;
466 // Principal we're inheriting. If null, this means the principal should be
467 // inherited from the current document. If set to NullPrincipal, the channel
468 // will fill in principal information later in the load. See internal comments
469 // of SetupInheritingPrincipal for more info.
471 // When passed to InternalLoad, If this argument is null then
472 // principalToInherit is computed differently. See nsDocShell::InternalLoad
473 // for more comments.
475 nsCOMPtr
<nsIPrincipal
> mPrincipalToInherit
;
477 nsCOMPtr
<nsIPrincipal
> mPartitionedPrincipalToInherit
;
479 // If this attribute is true, then a top-level navigation
480 // to a data URI will be allowed.
481 bool mForceAllowDataURI
;
483 // If this attribute is true, then the top-level navigaion
484 // will be exempt from HTTPS-Only-Mode upgrades.
485 bool mIsExemptFromHTTPSFirstMode
;
487 // If this attribute is true, this load corresponds to a frame
488 // element loading its original src (or srcdoc) attribute.
489 bool mOriginalFrameSrc
;
491 // If this attribute is true, then the load was initiated by a
493 bool mIsFormSubmission
;
495 // Contains a load type as specified by the nsDocShellLoadTypes::load*
499 // Active Session History entry (if loading from SH)
500 nsCOMPtr
<nsISHEntry
> mSHEntry
;
502 // Loading session history info for the load
503 mozilla::UniquePtr
<mozilla::dom::LoadingSessionHistoryInfo
>
504 mLoadingSessionHistoryInfo
;
506 // Target for load, like _content, _blank etc.
509 // When set, this is the Target Browsing Context for the navigation
510 // after retargeting.
511 MaybeDiscarded
<BrowsingContext
> mTargetBrowsingContext
;
513 // Post data stream (if POSTing)
514 nsCOMPtr
<nsIInputStream
> mPostDataStream
;
516 // Additional Headers
517 nsCOMPtr
<nsIInputStream
> mHeadersStream
;
519 // When set, the load will be interpreted as a srcdoc load, where contents of
520 // this string will be loaded instead of the URI. Setting srcdocData sets
521 // isSrcdocLoad to true
522 nsString mSrcdocData
;
524 // When set, this is the Source Browsing Context for the navigation.
525 MaybeDiscarded
<BrowsingContext
> mSourceBrowsingContext
;
527 // Used for srcdoc loads to give view-source knowledge of the load's base URI
528 // as this information isn't embedded in the load's URI.
529 nsCOMPtr
<nsIURI
> mBaseURI
;
531 // Set of Load Flags, taken from nsDocShellLoadTypes.h and nsIWebNavigation
534 // Set of internal load flags
535 uint32_t mInternalLoadFlags
;
537 // Is this a First Party Load?
540 // Is this load triggered by a user gesture?
541 bool mHasValidUserGestureActivation
;
543 // Whether this load can steal the focus from the source browsing context.
544 bool mAllowFocusMove
;
546 // A hint as to the content-type of the resulting data. If no hint, IsVoid()
547 // should return true.
550 // Non-void when the link should be downloaded as the given filename.
551 // mFileName being non-void but empty means that no filename hint was
552 // specified, but link should still trigger a download. If not a download,
553 // mFileName.IsVoid() should return true.
556 // This will be true if this load is triggered by attribute changes.
557 // See nsILoadInfo.isFromProcessingFrameAttributes
558 bool mIsFromProcessingFrameAttributes
;
560 // If set, a pending cross-process redirected channel should be used to
561 // perform the load. The channel will be stored in this value.
562 nsCOMPtr
<nsIChannel
> mPendingRedirectedChannel
;
564 // An optional string representation of mURI, before any
565 // fixups were applied, so that we can send it to a search
566 // engine service if needed.
567 mozilla::Maybe
<nsCString
> mOriginalURIString
;
569 // An optional value to pass to nsIDocShell::setCancelJSEpoch
570 // when initiating the load.
571 mozilla::Maybe
<int32_t> mCancelContentJSEpoch
;
573 // If mPendingRedirectChannel is set, then this is the identifier
574 // that the parent-process equivalent channel has been registered
575 // with using RedirectChannelRegistrar.
576 uint64_t mChannelRegistrarId
;
578 // An identifier to make it possible to examine if two loads are
579 // equal, and which browsing context they belong to (see
580 // BrowsingContext::{Get, Set}CurrentLoadIdentifier)
581 const uint64_t mLoadIdentifier
;
583 // Optional value to indicate that a channel has been
584 // pre-initialized in the parent process.
585 bool mChannelInitialized
;
587 // True if the load was triggered by a meta refresh.
590 // True if the nsDocShellLoadState was received over IPC.
591 bool mWasCreatedRemotely
= false;
593 // The original URI before query stripping happened. If it's present, it shows
594 // the query stripping happened. Otherwise, it will be a nullptr.
595 nsCOMPtr
<nsIURI
> mUnstrippedURI
;
597 // If set, the remote type which the load should be completed within.
598 mozilla::Maybe
<nsCString
> mRemoteTypeOverride
;
600 // Remote type of the process which originally requested the load.
601 nsCString mTriggeringRemoteType
;
603 // if the to-be-loaded address had it protocol added through a fixup
604 bool mWasSchemelessInput
= false;
607 #endif /* nsDocShellLoadState_h__ */