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/. */ 6 7 #ifndef nsDocShellLoadState_h__ 8 #define nsDocShellLoadState_h__ 9 10 #include "mozilla/dom/BrowsingContext.h" 11 #include "mozilla/dom/SessionHistoryEntry.h" 12 13 // Helper Classes 14 #include "mozilla/Maybe.h" 15 #include "nsCOMPtr.h" 16 #include "nsString.h" 17 #include "nsDocShellLoadTypes.h" 18 #include "nsTArrayForwardDeclare.h" 19 20 class nsIContentSecurityPolicy; 21 class nsIInputStream; 22 class nsISHEntry; 23 class nsIURI; 24 class nsIDocShell; 25 class nsIChannel; 26 class nsIReferrerInfo; 27 class OriginAttibutes; 28 namespace mozilla { 29 template <typename, class> 30 class UniquePtr; 31 namespace dom { 32 class DocShellLoadStateInit; 33 } // namespace dom 34 } // namespace mozilla 35 36 /** 37 * nsDocShellLoadState contains setup information used in a nsIDocShell::loadURI 38 * call. 39 */ 40 class nsDocShellLoadState final { 41 using BrowsingContext = mozilla::dom::BrowsingContext; 42 template <typename T> 43 using MaybeDiscarded = mozilla::dom::MaybeDiscarded<T>; 44 45 public: 46 NS_INLINE_DECL_REFCOUNTING(nsDocShellLoadState); 47 48 explicit nsDocShellLoadState(nsIURI* aURI); 49 explicit nsDocShellLoadState( 50 const mozilla::dom::DocShellLoadStateInit& aLoadState); 51 explicit nsDocShellLoadState(const nsDocShellLoadState& aOther); 52 nsDocShellLoadState(nsIURI* aURI, uint64_t aLoadIdentifier); 53 54 static nsresult CreateFromPendingChannel(nsIChannel* aPendingChannel, 55 uint64_t aLoadIdentifier, 56 uint64_t aRegistarId, 57 nsDocShellLoadState** aResult); 58 59 static nsresult CreateFromLoadURIOptions( 60 BrowsingContext* aBrowsingContext, const nsAString& aURI, 61 const mozilla::dom::LoadURIOptions& aLoadURIOptions, 62 nsDocShellLoadState** aResult); 63 64 // Getters and Setters 65 66 nsIReferrerInfo* GetReferrerInfo() const; 67 68 void SetReferrerInfo(nsIReferrerInfo* aReferrerInfo); 69 70 nsIURI* URI() const; 71 72 void SetURI(nsIURI* aURI); 73 74 nsIURI* OriginalURI() const; 75 76 void SetOriginalURI(nsIURI* aOriginalURI); 77 78 nsIURI* ResultPrincipalURI() const; 79 80 void SetResultPrincipalURI(nsIURI* aResultPrincipalURI); 81 82 bool ResultPrincipalURIIsSome() const; 83 84 void SetResultPrincipalURIIsSome(bool aIsSome); 85 86 bool KeepResultPrincipalURIIfSet() const; 87 88 void SetKeepResultPrincipalURIIfSet(bool aKeep); 89 90 nsIPrincipal* PrincipalToInherit() const; 91 92 void SetPrincipalToInherit(nsIPrincipal* aPrincipalToInherit); 93 94 nsIPrincipal* PartitionedPrincipalToInherit() const; 95 96 void SetPartitionedPrincipalToInherit( 97 nsIPrincipal* aPartitionedPrincipalToInherit); 98 99 bool LoadReplace() const; 100 101 void SetLoadReplace(bool aLoadReplace); 102 103 nsIPrincipal* TriggeringPrincipal() const; 104 105 void SetTriggeringPrincipal(nsIPrincipal* aTriggeringPrincipal); 106 107 uint32_t TriggeringSandboxFlags() const; 108 109 void SetTriggeringSandboxFlags(uint32_t aTriggeringSandboxFlags); 110 111 nsIContentSecurityPolicy* Csp() const; 112 113 void SetCsp(nsIContentSecurityPolicy* aCsp); 114 115 bool InheritPrincipal() const; 116 117 void SetInheritPrincipal(bool aInheritPrincipal); 118 119 bool PrincipalIsExplicit() const; 120 121 void SetPrincipalIsExplicit(bool aPrincipalIsExplicit); 122 123 // If true, "beforeunload" event listeners were notified by the creater of the 124 // LoadState and given the chance to abort the navigation, and should not be 125 // notified again. 126 bool NotifiedBeforeUnloadListeners() const; 127 128 void SetNotifiedBeforeUnloadListeners(bool aNotifiedBeforeUnloadListeners); 129 130 bool ForceAllowDataURI() const; 131 132 void SetForceAllowDataURI(bool aForceAllowDataURI); 133 134 bool IsExemptFromHTTPSOnlyMode() const; 135 136 void SetIsExemptFromHTTPSOnlyMode(bool aIsExemptFromHTTPSOnlyMode); 137 138 bool OriginalFrameSrc() const; 139 140 void SetOriginalFrameSrc(bool aOriginalFrameSrc); 141 142 bool IsFormSubmission() const; 143 144 void SetIsFormSubmission(bool aIsFormSubmission); 145 146 uint32_t LoadType() const; 147 148 void SetLoadType(uint32_t aLoadType); 149 150 nsISHEntry* SHEntry() const; 151 152 void SetSHEntry(nsISHEntry* aSHEntry); 153 154 const mozilla::dom::LoadingSessionHistoryInfo* GetLoadingSessionHistoryInfo() 155 const; 156 157 // Copies aLoadingInfo and stores the copy in this nsDocShellLoadState. 158 void SetLoadingSessionHistoryInfo( 159 const mozilla::dom::LoadingSessionHistoryInfo& aLoadingInfo); 160 161 // Stores aLoadingInfo in this nsDocShellLoadState. 162 void SetLoadingSessionHistoryInfo( 163 mozilla::UniquePtr<mozilla::dom::LoadingSessionHistoryInfo> aLoadingInfo); 164 165 bool LoadIsFromSessionHistory() const; 166 167 const nsString& Target() const; 168 169 void SetTarget(const nsAString& aTarget); 170 171 nsIInputStream* PostDataStream() const; 172 173 void SetPostDataStream(nsIInputStream* aStream); 174 175 nsIInputStream* HeadersStream() const; 176 177 void SetHeadersStream(nsIInputStream* aHeadersStream); 178 179 bool IsSrcdocLoad() const; 180 181 const nsString& SrcdocData() const; 182 183 void SetSrcdocData(const nsAString& aSrcdocData); 184 SourceBrowsingContext()185 const MaybeDiscarded<BrowsingContext>& SourceBrowsingContext() const { 186 return mSourceBrowsingContext; 187 } 188 189 void SetSourceBrowsingContext(BrowsingContext*); 190 SetAllowFocusMove(bool aAllow)191 void SetAllowFocusMove(bool aAllow) { mAllowFocusMove = aAllow; } 192 AllowFocusMove()193 bool AllowFocusMove() const { return mAllowFocusMove; } 194 TargetBrowsingContext()195 const MaybeDiscarded<BrowsingContext>& TargetBrowsingContext() const { 196 return mTargetBrowsingContext; 197 } 198 199 void SetTargetBrowsingContext(BrowsingContext* aTargetBrowsingContext); 200 201 nsIURI* BaseURI() const; 202 203 void SetBaseURI(nsIURI* aBaseURI); 204 205 // Helper function allowing convenient work with mozilla::Maybe in C++, hiding 206 // resultPrincipalURI and resultPrincipalURIIsSome attributes from the 207 // consumer. 208 void GetMaybeResultPrincipalURI( 209 mozilla::Maybe<nsCOMPtr<nsIURI>>& aRPURI) const; 210 211 void SetMaybeResultPrincipalURI( 212 mozilla::Maybe<nsCOMPtr<nsIURI>> const& aRPURI); 213 214 uint32_t LoadFlags() const; 215 216 void SetLoadFlags(uint32_t aFlags); 217 218 void SetLoadFlag(uint32_t aFlag); 219 220 void UnsetLoadFlag(uint32_t aFlag); 221 222 bool HasLoadFlags(uint32_t aFlag); 223 224 uint32_t InternalLoadFlags() const; 225 226 void SetInternalLoadFlags(uint32_t aFlags); 227 228 void SetInternalLoadFlag(uint32_t aFlag); 229 230 void UnsetInternalLoadFlag(uint32_t aFlag); 231 232 bool HasInternalLoadFlags(uint32_t aFlag); 233 234 bool FirstParty() const; 235 236 void SetFirstParty(bool aFirstParty); 237 238 bool HasValidUserGestureActivation() const; 239 240 void SetHasValidUserGestureActivation(bool HasValidUserGestureActivation); 241 242 const nsCString& TypeHint() const; 243 244 void SetTypeHint(const nsCString& aTypeHint); 245 246 const nsString& FileName() const; 247 248 void SetFileName(const nsAString& aFileName); 249 250 nsIURI* GetUnstrippedURI() const; 251 252 // Give the type of DocShell we're loading into (chrome/content/etc) and 253 // origin attributes for the URI we're loading, figure out if we should 254 // inherit our principal from the document the load was requested from, or 255 // else if the principal should be set up later in the process (after loads). 256 // See comments in function for more info on principal selection algorithm 257 nsresult SetupInheritingPrincipal( 258 mozilla::dom::BrowsingContext::Type aType, 259 const mozilla::OriginAttributes& aOriginAttributes); 260 261 // If no triggering principal exists at the moment, create one using referrer 262 // information and origin attributes. 263 nsresult SetupTriggeringPrincipal( 264 const mozilla::OriginAttributes& aOriginAttributes); 265 SetIsFromProcessingFrameAttributes()266 void SetIsFromProcessingFrameAttributes() { 267 mIsFromProcessingFrameAttributes = true; 268 } GetIsFromProcessingFrameAttributes()269 bool GetIsFromProcessingFrameAttributes() const { 270 return mIsFromProcessingFrameAttributes; 271 } 272 GetPendingRedirectedChannel()273 nsIChannel* GetPendingRedirectedChannel() { 274 return mPendingRedirectedChannel; 275 } 276 GetPendingRedirectChannelRegistrarId()277 uint64_t GetPendingRedirectChannelRegistrarId() const { 278 return mChannelRegistrarId; 279 } 280 SetOriginalURIString(const nsCString & aOriginalURI)281 void SetOriginalURIString(const nsCString& aOriginalURI) { 282 mOriginalURIString.emplace(aOriginalURI); 283 } GetOriginalURIString()284 const mozilla::Maybe<nsCString>& GetOriginalURIString() const { 285 return mOriginalURIString; 286 } 287 SetCancelContentJSEpoch(int32_t aCancelEpoch)288 void SetCancelContentJSEpoch(int32_t aCancelEpoch) { 289 mCancelContentJSEpoch.emplace(aCancelEpoch); 290 } GetCancelContentJSEpoch()291 const mozilla::Maybe<int32_t>& GetCancelContentJSEpoch() const { 292 return mCancelContentJSEpoch; 293 } 294 GetLoadIdentifier()295 uint64_t GetLoadIdentifier() const { return mLoadIdentifier; } 296 SetChannelInitialized(bool aInitilized)297 void SetChannelInitialized(bool aInitilized) { 298 mChannelInitialized = aInitilized; 299 } 300 GetChannelInitialized()301 bool GetChannelInitialized() const { return mChannelInitialized; } 302 SetIsMetaRefresh(bool aMetaRefresh)303 void SetIsMetaRefresh(bool aMetaRefresh) { mIsMetaRefresh = aMetaRefresh; } 304 IsMetaRefresh()305 bool IsMetaRefresh() const { return mIsMetaRefresh; } 306 GetRemoteTypeOverride()307 const mozilla::Maybe<nsCString>& GetRemoteTypeOverride() const { 308 return mRemoteTypeOverride; 309 } 310 SetRemoteTypeOverride(const nsCString & aRemoteTypeOverride)311 void SetRemoteTypeOverride(const nsCString& aRemoteTypeOverride) { 312 mRemoteTypeOverride = mozilla::Some(aRemoteTypeOverride); 313 } 314 315 // When loading a document through nsDocShell::LoadURI(), a special set of 316 // flags needs to be set based on other values in nsDocShellLoadState. This 317 // function calculates those flags, before the LoadState is passed to 318 // nsDocShell::InternalLoad. 319 void CalculateLoadURIFlags(); 320 321 // Compute the load flags to be used by creating channel. aUriModified and 322 // aIsXFOError are expected to be Nothing when called from Parent process. 323 nsLoadFlags CalculateChannelLoadFlags( 324 mozilla::dom::BrowsingContext* aBrowsingContext, 325 mozilla::Maybe<bool> aUriModified, mozilla::Maybe<bool> aIsXFOError); 326 327 mozilla::dom::DocShellLoadStateInit Serialize(); 328 329 void SetLoadIsFromSessionHistory(int32_t aOffset, bool aLoadingCurrentEntry); 330 void ClearLoadIsFromSessionHistory(); 331 332 void MaybeStripTrackerQueryStrings(mozilla::dom::BrowsingContext* aContext, 333 nsIURI* aCurrentUnstrippedURI = nullptr); 334 335 protected: 336 // Destructor can't be defaulted or inlined, as header doesn't have all type 337 // includes it needs to do so. 338 ~nsDocShellLoadState(); 339 340 protected: 341 // This is the referrer for the load. 342 nsCOMPtr<nsIReferrerInfo> mReferrerInfo; 343 344 // The URI we are navigating to. Will not be null once set. 345 nsCOMPtr<nsIURI> mURI; 346 347 // The URI to set as the originalURI on the channel that does the load. If 348 // null, aURI will be set as the originalURI. 349 nsCOMPtr<nsIURI> mOriginalURI; 350 351 // The URI to be set to loadInfo.resultPrincipalURI 352 // - When Nothing, there will be no change 353 // - When Some, the principal URI will overwrite even 354 // with a null value. 355 // 356 // Valid only if mResultPrincipalURIIsSome is true (has the same meaning as 357 // isSome() on mozilla::Maybe.) 358 nsCOMPtr<nsIURI> mResultPrincipalURI; 359 bool mResultPrincipalURIIsSome; 360 361 // The principal of the load, that is, the entity responsible for causing the 362 // load to occur. In most cases the referrer and the triggeringPrincipal's URI 363 // will be identical. 364 // 365 // Please note that this is the principal that is used for security checks. If 366 // the argument aURI is provided by the web, then please do not pass a 367 // SystemPrincipal as the triggeringPrincipal. 368 nsCOMPtr<nsIPrincipal> mTriggeringPrincipal; 369 370 // The SandboxFlags of the load, that are, the SandboxFlags of the entity 371 // responsible for causing the load to occur. Most likely this are the 372 // SandboxFlags of the document that started the load. 373 uint32_t mTriggeringSandboxFlags; 374 375 // The CSP of the load, that is, the CSP of the entity responsible for causing 376 // the load to occur. Most likely this is the CSP of the document that started 377 // the load. In case the entity starting the load did not use a CSP, then mCsp 378 // can be null. Please note that this is also the CSP that will be applied to 379 // the load in case the load encounters a server side redirect. 380 nsCOMPtr<nsIContentSecurityPolicy> mCsp; 381 382 // If a refresh is caused by http-equiv="refresh" we want to set 383 // aResultPrincipalURI, but we do not want to overwrite the channel's 384 // ResultPrincipalURI, if it has already been set on the channel by a protocol 385 // handler. 386 bool mKeepResultPrincipalURIIfSet; 387 388 // If set LOAD_REPLACE flag will be set on the channel. If aOriginalURI is 389 // null, this argument is ignored. 390 bool mLoadReplace; 391 392 // If this attribute is true and no triggeringPrincipal is specified, 393 // copy the principal from the referring document. 394 bool mInheritPrincipal; 395 396 // If this attribute is true only ever use the principal specified 397 // by the triggeringPrincipal and inheritPrincipal attributes. 398 // If there are security reasons for why this is unsafe, such 399 // as trying to use a systemprincipal as the triggeringPrincipal 400 // for a content docshell the load fails. 401 bool mPrincipalIsExplicit; 402 403 bool mNotifiedBeforeUnloadListeners; 404 405 // Principal we're inheriting. If null, this means the principal should be 406 // inherited from the current document. If set to NullPrincipal, the channel 407 // will fill in principal information later in the load. See internal comments 408 // of SetupInheritingPrincipal for more info. 409 // 410 // When passed to InternalLoad, If this argument is null then 411 // principalToInherit is computed differently. See nsDocShell::InternalLoad 412 // for more comments. 413 414 nsCOMPtr<nsIPrincipal> mPrincipalToInherit; 415 416 nsCOMPtr<nsIPrincipal> mPartitionedPrincipalToInherit; 417 418 // If this attribute is true, then a top-level navigation 419 // to a data URI will be allowed. 420 bool mForceAllowDataURI; 421 422 // If this attribute is true, then the top-level navigaion 423 // will be exempt from HTTPS-Only-Mode upgrades. 424 bool mIsExemptFromHTTPSOnlyMode; 425 426 // If this attribute is true, this load corresponds to a frame 427 // element loading its original src (or srcdoc) attribute. 428 bool mOriginalFrameSrc; 429 430 // If this attribute is true, then the load was initiated by a 431 // form submission. This is important to know for the CSP directive 432 // navigate-to. 433 bool mIsFormSubmission; 434 435 // Contains a load type as specified by the nsDocShellLoadTypes::load* 436 // constants 437 uint32_t mLoadType; 438 439 // Active Session History entry (if loading from SH) 440 nsCOMPtr<nsISHEntry> mSHEntry; 441 442 // Loading session history info for the load 443 mozilla::UniquePtr<mozilla::dom::LoadingSessionHistoryInfo> 444 mLoadingSessionHistoryInfo; 445 446 // Target for load, like _content, _blank etc. 447 nsString mTarget; 448 449 // When set, this is the Target Browsing Context for the navigation 450 // after retargeting. 451 MaybeDiscarded<BrowsingContext> mTargetBrowsingContext; 452 453 // Post data stream (if POSTing) 454 nsCOMPtr<nsIInputStream> mPostDataStream; 455 456 // Additional Headers 457 nsCOMPtr<nsIInputStream> mHeadersStream; 458 459 // When set, the load will be interpreted as a srcdoc load, where contents of 460 // this string will be loaded instead of the URI. Setting srcdocData sets 461 // isSrcdocLoad to true 462 nsString mSrcdocData; 463 464 // When set, this is the Source Browsing Context for the navigation. 465 MaybeDiscarded<BrowsingContext> mSourceBrowsingContext; 466 467 // Used for srcdoc loads to give view-source knowledge of the load's base URI 468 // as this information isn't embedded in the load's URI. 469 nsCOMPtr<nsIURI> mBaseURI; 470 471 // Set of Load Flags, taken from nsDocShellLoadTypes.h and nsIWebNavigation 472 uint32_t mLoadFlags; 473 474 // Set of internal load flags 475 uint32_t mInternalLoadFlags; 476 477 // Is this a First Party Load? 478 bool mFirstParty; 479 480 // Is this load triggered by a user gesture? 481 bool mHasValidUserGestureActivation; 482 483 // Whether this load can steal the focus from the source browsing context. 484 bool mAllowFocusMove; 485 486 // A hint as to the content-type of the resulting data. If no hint, IsVoid() 487 // should return true. 488 nsCString mTypeHint; 489 490 // Non-void when the link should be downloaded as the given filename. 491 // mFileName being non-void but empty means that no filename hint was 492 // specified, but link should still trigger a download. If not a download, 493 // mFileName.IsVoid() should return true. 494 nsString mFileName; 495 496 // This will be true if this load is triggered by attribute changes. 497 // See nsILoadInfo.isFromProcessingFrameAttributes 498 bool mIsFromProcessingFrameAttributes; 499 500 // If set, a pending cross-process redirected channel should be used to 501 // perform the load. The channel will be stored in this value. 502 nsCOMPtr<nsIChannel> mPendingRedirectedChannel; 503 504 // An optional string representation of mURI, before any 505 // fixups were applied, so that we can send it to a search 506 // engine service if needed. 507 mozilla::Maybe<nsCString> mOriginalURIString; 508 509 // An optional value to pass to nsIDocShell::setCancelJSEpoch 510 // when initiating the load. 511 mozilla::Maybe<int32_t> mCancelContentJSEpoch; 512 513 // If mPendingRedirectChannel is set, then this is the identifier 514 // that the parent-process equivalent channel has been registered 515 // with using RedirectChannelRegistrar. 516 uint64_t mChannelRegistrarId; 517 518 // An identifier to make it possible to examine if two loads are 519 // equal, and which browsing context they belong to (see 520 // BrowsingContext::{Get, Set}CurrentLoadIdentifier) 521 const uint64_t mLoadIdentifier; 522 523 // Optional value to indicate that a channel has been 524 // pre-initialized in the parent process. 525 bool mChannelInitialized; 526 527 // True if the load was triggered by a meta refresh. 528 bool mIsMetaRefresh; 529 530 // The original URI before query stripping happened. If it's present, it shows 531 // the query stripping happened. Otherwise, it will be a nullptr. 532 nsCOMPtr<nsIURI> mUnstrippedURI; 533 534 // If set, the remote type which the load should be completed within. 535 mozilla::Maybe<nsCString> mRemoteTypeOverride; 536 }; 537 538 #endif /* nsDocShellLoadState_h__ */ 539