Bug 1492648 - Move from nsDocShellLoadInfo to nsDocShellLoadState r=bzbarsky,nika

Creates the nsDocShellLoadState object, which is basically
nsDocShellLoadInfo plus a few extra fields to make it usable as a
single argument to nsDocShell::LoadURI (and eventually
nsDocShell::InternalLoad).

Subframe history handling is a huge logic block in
nsDocShell::LoadURI, which is only used on history loads. This patch
also extracts the logic out into its own function to make the body of
LoadURI clearer.

Differential Revision: https://phabricator.services.mozilla.com/D6944
This commit is contained in:
Kyle Machulis
2018-10-26 03:50:37 +00:00
parent d173510ad3
commit 8416fded30
27 changed files with 1022 additions and 823 deletions

View File

@@ -169,7 +169,7 @@
#include "nsDocShellCID.h"
#include "nsDocShellEditorData.h"
#include "nsDocShellEnumerator.h"
#include "nsDocShellLoadInfo.h"
#include "nsDocShellLoadState.h"
#include "nsDocShellLoadTypes.h"
#include "nsDOMCID.h"
#include "nsDOMNavigationTiming.h"
@@ -643,14 +643,12 @@ nsDocShell::GetInterface(const nsIID& aIID, void** aSink)
}
NS_IMETHODIMP
nsDocShell::LoadURI(nsIURI* aURI,
nsDocShellLoadInfo* aLoadInfo,
uint32_t aLoadFlags,
bool aFirstParty)
nsDocShell::LoadURI(nsDocShellLoadState* aLoadState)
{
MOZ_ASSERT(aLoadInfo || (aLoadFlags & EXTRA_LOAD_FLAGS) == 0,
"Unexpected flags");
MOZ_ASSERT((aLoadFlags & 0xf) == 0, "Should not have these flags set");
MOZ_ASSERT(aLoadState, "Must have a valid load state!");
MOZ_ASSERT((aLoadState->LoadFlags() & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0,
"Should not have these flags set");
MOZ_ASSERT(aLoadState->URI(), "Should have a valid URI to load");
// Note: we allow loads to get through here even if mFiredUnloadEvent is
// true; that case will get handled in LoadInternal or LoadHistoryEntry,
@@ -662,86 +660,121 @@ nsDocShell::LoadURI(nsIURI* aURI,
return NS_OK; // JS may not handle returning of an error code
}
nsCOMPtr<nsIURI> referrer;
nsCOMPtr<nsIURI> originalURI;
Maybe<nsCOMPtr<nsIURI>> resultPrincipalURI;
bool keepResultPrincipalURIIfSet = false;
bool loadReplace = false;
nsCOMPtr<nsIInputStream> postStream;
nsCOMPtr<nsIInputStream> headersStream;
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
bool inheritPrincipal = false;
bool principalIsExplicit = false;
bool sendReferrer = true;
uint32_t referrerPolicy = RP_Unset;
bool isSrcdoc = false;
nsCOMPtr<nsISHEntry> shEntry;
nsString target;
nsAutoString srcdoc;
bool forceAllowDataURI = false;
bool originalFrameSrc = false;
nsCOMPtr<nsIDocShell> sourceDocShell;
nsCOMPtr<nsIURI> baseURI;
uint32_t loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags);
NS_ENSURE_ARG(aURI);
if (!StartupTimeline::HasRecord(StartupTimeline::FIRST_LOAD_URI) &&
mItemType == typeContent && !NS_IsAboutBlank(aURI)) {
mItemType == typeContent && !NS_IsAboutBlank(aLoadState->URI())) {
StartupTimeline::RecordOnce(StartupTimeline::FIRST_LOAD_URI);
}
// Extract the info from the DocShellLoadInfo struct...
if (aLoadInfo) {
referrer = aLoadInfo->Referrer();
originalURI = aLoadInfo->OriginalURI();
aLoadInfo->GetMaybeResultPrincipalURI(resultPrincipalURI);
keepResultPrincipalURIIfSet = aLoadInfo->KeepResultPrincipalURIIfSet();
loadReplace = aLoadInfo->LoadReplace();
// Get the appropriate loadType from nsIDocShellLoadInfo type
loadType = aLoadInfo->LoadType();
triggeringPrincipal = aLoadInfo->TriggeringPrincipal();
inheritPrincipal = aLoadInfo->InheritPrincipal();
principalIsExplicit = aLoadInfo->PrincipalIsExplicit();
shEntry = aLoadInfo->SHEntry();
aLoadInfo->GetTarget(target);
postStream = aLoadInfo->PostDataStream();
headersStream = aLoadInfo->HeadersStream();
sendReferrer = aLoadInfo->SendReferrer();
referrerPolicy = aLoadInfo->ReferrerPolicy();
isSrcdoc = aLoadInfo->IsSrcdocLoad();
aLoadInfo->GetSrcdocData(srcdoc);
sourceDocShell = aLoadInfo->SourceDocShell();
baseURI = aLoadInfo->BaseURI();
forceAllowDataURI = aLoadInfo->ForceAllowDataURI();
originalFrameSrc = aLoadInfo->OriginalFrameSrc();
}
MOZ_LOG(gDocShellLeakLog, LogLevel::Debug,
("nsDocShell[%p]: loading %s with flags 0x%08x",
this, aURI->GetSpecOrDefault().get(), aLoadFlags));
this, aLoadState->URI()->GetSpecOrDefault().get(),
aLoadState->LoadFlags()));
if (!shEntry &&
!LOAD_TYPE_HAS_FLAGS(loadType, LOAD_FLAGS_REPLACE_HISTORY)) {
// First verify if this is a subframe.
if (!aLoadState->SHEntry() &&
!LOAD_TYPE_HAS_FLAGS(aLoadState->LoadType(),
LOAD_FLAGS_REPLACE_HISTORY)) {
// This is possibly a subframe, so handle it accordingly.
//
// If history exists, it will be loaded into the aLoadState object, and the
// LoadType will be changed.
MaybeHandleSubframeHistory(aLoadState);
}
if (aLoadState->SHEntry()) {
#ifdef DEBUG
MOZ_LOG(gDocShellLog, LogLevel::Debug,
("nsDocShell[%p]: loading from session history", this));
#endif
return LoadHistoryEntry(aLoadState->SHEntry(), aLoadState->LoadType());
}
// On history navigation via Back/Forward buttons, don't execute
// automatic JavaScript redirection such as |location.href = ...| or
// |window.open()|
//
// LOAD_NORMAL: window.open(...) etc.
// LOAD_STOP_CONTENT: location.href = ..., location.assign(...)
if ((aLoadState->LoadType() == LOAD_NORMAL ||
aLoadState->LoadType() == LOAD_STOP_CONTENT) &&
ShouldBlockLoadingForBackButton()) {
return NS_OK;
}
// Set up the inheriting principal in LoadState.
nsresult rv = aLoadState->SetupInheritingPrincipal(mItemType, mOriginAttributes);
NS_ENSURE_SUCCESS(rv, rv);
rv = aLoadState->SetupTriggeringPrincipal(mOriginAttributes);
NS_ENSURE_SUCCESS(rv, rv);
aLoadState->CalculateDocShellInternalLoadFlags();
mozilla::Maybe<nsCOMPtr<nsIURI>> resultPrincipalURI;
aLoadState->GetMaybeResultPrincipalURI(resultPrincipalURI);
MOZ_ASSERT(aLoadState->TypeHint().IsVoid(),
"Typehint should be null when calling InternalLoad from LoadURI");
MOZ_ASSERT(aLoadState->FileName().IsVoid(),
"FileName should be null when calling InternalLoad from LoadURI");
MOZ_ASSERT(aLoadState->SHEntry() == nullptr,
"SHEntry should be null when calling InternalLoad from LoadURI");
return InternalLoad(aLoadState->URI(),
aLoadState->OriginalURI(),
resultPrincipalURI,
aLoadState->KeepResultPrincipalURIIfSet(),
aLoadState->LoadReplace(),
aLoadState->Referrer(),
aLoadState->ReferrerPolicy(),
aLoadState->TriggeringPrincipal(),
aLoadState->PrincipalToInherit(),
aLoadState->DocShellInternalLoadFlags(),
aLoadState->Target(),
aLoadState->TypeHint(),
aLoadState->FileName(),
aLoadState->PostDataStream(),
aLoadState->HeadersStream(),
aLoadState->LoadType(),
aLoadState->SHEntry(),
aLoadState->FirstParty(),
aLoadState->SrcdocData(),
aLoadState->SourceDocShell(),
aLoadState->BaseURI(),
nullptr, // no nsIDocShell
nullptr); // no nsIRequest
}
void
nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState)
{
// First, verify if this is a subframe.
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
GetSameTypeParent(getter_AddRefs(parentAsItem));
nsCOMPtr<nsIDocShell> parentDS(do_QueryInterface(parentAsItem));
uint32_t parentLoadType;
if (parentDS && parentDS != static_cast<nsIDocShell*>(this)) {
/* OK. It is a subframe. Checkout the
* parent's loadtype. If the parent was loaded thro' a history
* mechanism, then get the SH entry for the child from the parent.
* This is done to restore frameset navigation while going back/forward.
* If the parent was loaded through any other loadType, set the
* child's loadType too accordingly, so that session history does not
* get confused.
if (!parentDS || parentDS == static_cast<nsIDocShell*>(this)) {
// This is the root docshell. If we got here while
// executing an onLoad Handler,this load will not go
// into session history.
bool inOnLoadHandler = false;
GetIsExecutingOnLoadHandler(&inOnLoadHandler);
if (inOnLoadHandler) {
aLoadState->SetLoadType(LOAD_NORMAL_REPLACE);
}
return;
}
/* OK. It is a subframe. Checkout the parent's loadtype. If the parent was
* loaded through a history mechanism, then get the SH entry for the child from
* the parent. This is done to restore frameset navigation while going
* back/forward. If the parent was loaded through any other loadType, set the
* child's loadType too accordingly, so that session history does not get
* confused.
*/
// Get the parent's load type
uint32_t parentLoadType;
parentDS->GetLoadType(&parentLoadType);
// Get the ShEntry for the child from the parent
@@ -749,13 +782,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
bool oshe = false;
parentDS->GetCurrentSHEntry(getter_AddRefs(currentSH), &oshe);
bool dynamicallyAddedChild = mDynamicallyCreated;
if (!dynamicallyAddedChild && !oshe && currentSH) {
currentSH->HasDynamicallyAddedChild(&dynamicallyAddedChild);
}
if (!dynamicallyAddedChild) {
// Only use the old SHEntry, if we're sure enough that
// it wasn't originally for some other frame.
nsCOMPtr<nsISHEntry> shEntry;
parentDS->GetChildSHEntry(mChildOffset, getter_AddRefs(shEntry));
aLoadState->SetSHEntry(shEntry);
}
// Make some decisions on the child frame's loadType based on the
@@ -768,58 +805,13 @@ nsDocShell::LoadURI(nsIURI* aURI,
// currentSHEntry is null.
nsCOMPtr<nsISHEntry> currentChildEntry;
GetCurrentSHEntry(getter_AddRefs(currentChildEntry), &oshe);
if (!mCurrentURI || (NS_IsAboutBlank(mCurrentURI) && !currentChildEntry)) {
// This is a newly created frame. Check for exception cases first.
// By default the subframe will inherit the parent's loadType.
if (shEntry && (parentLoadType == LOAD_NORMAL ||
parentLoadType == LOAD_LINK ||
parentLoadType == LOAD_NORMAL_EXTERNAL)) {
// The parent was loaded normally. In this case, this *brand new*
// child really shouldn't have a SHEntry. If it does, it could be
// because the parent is replacing an existing frame with a new frame,
// in the onLoadHandler. We don't want this url to get into session
// history. Clear off shEntry, and set load type to
// LOAD_BYPASS_HISTORY.
bool inOnLoadHandler = false;
parentDS->GetIsExecutingOnLoadHandler(&inOnLoadHandler);
if (inOnLoadHandler) {
loadType = LOAD_NORMAL_REPLACE;
shEntry = nullptr;
}
} else if (parentLoadType == LOAD_REFRESH) {
// Clear shEntry. For refresh loads, we have to load
// what comes thro' the pipe, not what's in history.
shEntry = nullptr;
} else if ((parentLoadType == LOAD_BYPASS_HISTORY) ||
(shEntry &&
((parentLoadType & LOAD_CMD_HISTORY) ||
(parentLoadType == LOAD_RELOAD_NORMAL) ||
(parentLoadType == LOAD_RELOAD_CHARSET_CHANGE) ||
(parentLoadType == LOAD_RELOAD_CHARSET_CHANGE_BYPASS_CACHE) ||
(parentLoadType == LOAD_RELOAD_CHARSET_CHANGE_BYPASS_PROXY_AND_CACHE)))) {
// If the parent url, bypassed history or was loaded from
// history, pass on the parent's loadType to the new child
// frame too, so that the child frame will also
// avoid getting into history.
loadType = parentLoadType;
} else if (parentLoadType == LOAD_ERROR_PAGE) {
// If the parent document is an error page, we don't
// want to update global/session history. However,
// this child frame is not an error page.
loadType = LOAD_BYPASS_HISTORY;
} else if ((parentLoadType == LOAD_RELOAD_BYPASS_CACHE) ||
(parentLoadType == LOAD_RELOAD_BYPASS_PROXY) ||
(parentLoadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE)) {
// the new frame should inherit the parent's load type so that it also
// bypasses the cache and/or proxy
loadType = parentLoadType;
}
} else {
if (mCurrentURI && (!NS_IsAboutBlank(mCurrentURI) || currentChildEntry)) {
// This is a pre-existing subframe. If
// 1. The load of this frame was not originally initiated by session
// history directly (i.e. (!shEntry) condition succeeded, but it can
// still be a history load on parent which causes this frame being
// loaded), and
// loaded), which we checked with the above assert, and
// 2. mCurrentURI is not null, nor the initial about:blank,
// it is possible that a parent's onLoadHandler or even self's
// onLoadHandler is loading a new page in this child. Check parent's and
@@ -831,187 +823,57 @@ nsDocShell::LoadURI(nsIURI* aURI,
GetBusyFlags(&selfBusy);
if (parentBusy & BUSY_FLAGS_BUSY ||
selfBusy & BUSY_FLAGS_BUSY) {
loadType = LOAD_NORMAL_REPLACE;
shEntry = nullptr;
}
}
} // parentDS
else {
// This is the root docshell. If we got here while
// executing an onLoad Handler,this load will not go
// into session history.
aLoadState->SetLoadType(LOAD_NORMAL_REPLACE);
aLoadState->SetSHEntry(nullptr);
}
return;
}
// This is a newly created frame. Check for exception cases first.
// By default the subframe will inherit the parent's loadType.
if (aLoadState->SHEntry() && (parentLoadType == LOAD_NORMAL ||
parentLoadType == LOAD_LINK ||
parentLoadType == LOAD_NORMAL_EXTERNAL)) {
// The parent was loaded normally. In this case, this *brand new*
// child really shouldn't have a SHEntry. If it does, it could be
// because the parent is replacing an existing frame with a new frame,
// in the onLoadHandler. We don't want this url to get into session
// history. Clear off shEntry, and set load type to
// LOAD_BYPASS_HISTORY.
bool inOnLoadHandler = false;
GetIsExecutingOnLoadHandler(&inOnLoadHandler);
parentDS->GetIsExecutingOnLoadHandler(&inOnLoadHandler);
if (inOnLoadHandler) {
loadType = LOAD_NORMAL_REPLACE;
}
aLoadState->SetLoadType(LOAD_NORMAL_REPLACE);
aLoadState->SetSHEntry(nullptr);
}
} // !shEntry
if (shEntry) {
#ifdef DEBUG
MOZ_LOG(gDocShellLog, LogLevel::Debug,
("nsDocShell[%p]: loading from session history", this));
#endif
return LoadHistoryEntry(shEntry, loadType);
} else if (parentLoadType == LOAD_REFRESH) {
// Clear shEntry. For refresh loads, we have to load
// what comes through the pipe, not what's in history.
aLoadState->SetSHEntry(nullptr);
} else if ((parentLoadType == LOAD_BYPASS_HISTORY) ||
(aLoadState->SHEntry() &&
((parentLoadType & LOAD_CMD_HISTORY) ||
(parentLoadType == LOAD_RELOAD_NORMAL) ||
(parentLoadType == LOAD_RELOAD_CHARSET_CHANGE) ||
(parentLoadType == LOAD_RELOAD_CHARSET_CHANGE_BYPASS_CACHE) ||
(parentLoadType == LOAD_RELOAD_CHARSET_CHANGE_BYPASS_PROXY_AND_CACHE)))) {
// If the parent url, bypassed history or was loaded from
// history, pass on the parent's loadType to the new child
// frame too, so that the child frame will also
// avoid getting into history.
aLoadState->SetLoadType(parentLoadType);
} else if (parentLoadType == LOAD_ERROR_PAGE) {
// If the parent document is an error page, we don't
// want to update global/session history. However,
// this child frame is not an error page.
aLoadState->SetLoadType(LOAD_BYPASS_HISTORY);
} else if ((parentLoadType == LOAD_RELOAD_BYPASS_CACHE) ||
(parentLoadType == LOAD_RELOAD_BYPASS_PROXY) ||
(parentLoadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE)) {
// the new frame should inherit the parent's load type so that it also
// bypasses the cache and/or proxy
aLoadState->SetLoadType(parentLoadType);
}
// On history navigation via Back/Forward buttons, don't execute
// automatic JavaScript redirection such as |location.href = ...| or
// |window.open()|
//
// LOAD_NORMAL: window.open(...) etc.
// LOAD_STOP_CONTENT: location.href = ..., location.assign(...)
if ((loadType == LOAD_NORMAL || loadType == LOAD_STOP_CONTENT) &&
ShouldBlockLoadingForBackButton()) {
return NS_OK;
}
// Perform the load...
// We need a principalToInherit.
//
// If principalIsExplicit is not set there are 4 possibilities:
// (1) If the system principal or an expanded principal was passed
// in and we're a typeContent docshell, inherit the principal
// from the current document instead.
// (2) In all other cases when the principal passed in is not null,
// use that principal.
// (3) If the caller has allowed inheriting from the current document,
// or if we're being called from system code (eg chrome JS or pure
// C++) then inheritPrincipal should be true and InternalLoad will get
// a principal from the current document. If none of these things are
// true, then
// (4) we don't pass a principal into the channel, and a principal will be
// created later from the channel's internal data.
//
// If principalIsExplicit *is* set, there are 4 possibilities
// (1) If the system principal or an expanded principal was passed in
// and we're a typeContent docshell, return an error.
// (2) In all other cases when the principal passed in is not null,
// use that principal.
// (3) If the caller has allowed inheriting from the current document,
// then inheritPrincipal should be true and InternalLoad will get
// a principal from the current document. If none of these things are
// true, then
// (4) we dont' pass a principal into the channel, and a principal will be
// created later from the channel's internal data.
nsCOMPtr<nsIPrincipal> principalToInherit = triggeringPrincipal;
if (principalToInherit && mItemType != typeChrome) {
if (nsContentUtils::IsSystemPrincipal(principalToInherit)) {
if (principalIsExplicit) {
return NS_ERROR_DOM_SECURITY_ERR;
}
principalToInherit = nullptr;
inheritPrincipal = true;
} else if (nsContentUtils::IsExpandedPrincipal(principalToInherit)) {
if (principalIsExplicit) {
return NS_ERROR_DOM_SECURITY_ERR;
}
// Don't inherit from the current page. Just do the safe thing
// and pretend that we were loaded by a nullprincipal.
//
// We didn't inherit OriginAttributes here as ExpandedPrincipal doesn't
// have origin attributes.
principalToInherit = NullPrincipal::CreateWithInheritedAttributes(this);
inheritPrincipal = false;
}
}
if (!principalToInherit && !inheritPrincipal && !principalIsExplicit) {
// See if there's system or chrome JS code running
inheritPrincipal = nsContentUtils::LegacyIsCallerChromeOrNativeCode();
}
if (aLoadFlags & LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL) {
inheritPrincipal = false;
// If aFirstParty is true and the pref 'privacy.firstparty.isolate' is
// enabled, we will set firstPartyDomain on the origin attributes.
principalToInherit = NullPrincipal::CreateWithInheritedAttributes(this, aFirstParty);
}
// If the triggeringPrincipal is not passed explicitly, we first try to create
// a principal from the referrer, since the referrer URI reflects the web origin
// that triggered the load. If there is no referrer URI, we fall back to using
// the SystemPrincipal. It's safe to assume that no provided triggeringPrincipal
// and no referrer simulate a load that was triggered by the system.
// It's important to note that this block of code needs to appear *after* the block
// where we munge the principalToInherit, because otherwise we would never enter
// code blocks checking if the principalToInherit is null and we will end up with
// a wrong inheritPrincipal flag.
if (!triggeringPrincipal) {
if (referrer) {
nsresult rv = CreatePrincipalFromReferrer(referrer,
getter_AddRefs(triggeringPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
}
else {
triggeringPrincipal = nsContentUtils::GetSystemPrincipal();
}
}
uint32_t flags = 0;
if (inheritPrincipal) {
MOZ_ASSERT(!nsContentUtils::IsSystemPrincipal(principalToInherit), "Should not inherit SystemPrincipal");
flags |= INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL;
}
if (!sendReferrer) {
flags |= INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER;
}
if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
flags |= INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
}
if (aLoadFlags & LOAD_FLAGS_FIRST_LOAD) {
flags |= INTERNAL_LOAD_FLAGS_FIRST_LOAD;
}
if (aLoadFlags & LOAD_FLAGS_BYPASS_CLASSIFIER) {
flags |= INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER;
}
if (aLoadFlags & LOAD_FLAGS_FORCE_ALLOW_COOKIES) {
flags |= INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES;
}
if (isSrcdoc) {
flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
}
if (forceAllowDataURI) {
flags |= INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
}
if (originalFrameSrc) {
flags |= INTERNAL_LOAD_FLAGS_ORIGINAL_FRAME_SRC;
}
return InternalLoad(aURI,
originalURI,
resultPrincipalURI,
keepResultPrincipalURIIfSet,
loadReplace,
referrer,
referrerPolicy,
triggeringPrincipal,
principalToInherit,
flags,
target,
nullptr, // No type hint
VoidString(), // No forced download
postStream,
headersStream,
loadType,
nullptr, // No SHEntry
aFirstParty,
srcdoc,
sourceDocShell,
baseURI,
nullptr, // No nsIDocShell
nullptr); // No nsIRequest
}
/*
@@ -4226,7 +4088,7 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI,
nsIURI* aBaseURI,
nsIPrincipal* aTriggeringPrincipal)
{
NS_ASSERTION((aLoadFlags & 0xf) == 0, "Unexpected flags");
NS_ASSERTION((aLoadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0, "Unexpected flags");
if (!IsNavigationAllowed()) {
return NS_OK; // JS may not handle returning of an error code
@@ -4321,27 +4183,28 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI,
uint32_t extraFlags = (aLoadFlags & EXTRA_LOAD_FLAGS);
aLoadFlags &= ~EXTRA_LOAD_FLAGS;
RefPtr<nsDocShellLoadInfo> loadInfo = new nsDocShellLoadInfo();
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState();
/*
* If the user "Disables Protection on This Page", we have to make sure to
* remember the users decision when opening links in child tabs [Bug 906190]
*/
uint32_t loadType;
if (aLoadFlags & LOAD_FLAGS_ALLOW_MIXED_CONTENT) {
loadType = MAKE_LOAD_TYPE(LOAD_NORMAL_ALLOW_MIXED_CONTENT, aLoadFlags);
loadState->SetLoadType(MAKE_LOAD_TYPE(LOAD_NORMAL_ALLOW_MIXED_CONTENT, aLoadFlags));
} else {
loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags);
loadState->SetLoadType(MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags));
}
loadInfo->SetLoadType(loadType);
loadInfo->SetPostDataStream(postStream);
loadInfo->SetReferrer(aReferringURI);
loadInfo->SetReferrerPolicy((mozilla::net::ReferrerPolicy)aReferrerPolicy);
loadInfo->SetHeadersStream(aHeaderStream);
loadInfo->SetBaseURI(aBaseURI);
loadInfo->SetTriggeringPrincipal(aTriggeringPrincipal);
loadInfo->SetForceAllowDataURI(forceAllowDataURI);
loadState->SetURI(uri);
loadState->SetLoadFlags(extraFlags);
loadState->SetFirstParty(true);
loadState->SetPostDataStream(postStream);
loadState->SetReferrer(aReferringURI);
loadState->SetReferrerPolicy((mozilla::net::ReferrerPolicy)aReferrerPolicy);
loadState->SetHeadersStream(aHeaderStream);
loadState->SetBaseURI(aBaseURI);
loadState->SetTriggeringPrincipal(aTriggeringPrincipal);
loadState->SetForceAllowDataURI(forceAllowDataURI);
if (fixupInfo) {
nsAutoString searchProvider, keyword;
@@ -4350,7 +4213,7 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI,
MaybeNotifyKeywordSearchLoading(searchProvider, keyword);
}
rv = LoadURI(uri, loadInfo, extraFlags, true);
rv = LoadURI(loadState);
// Save URI string in case it's needed later when
// sending to search engine service in EndPageLoad()
@@ -4922,7 +4785,7 @@ nsDocShell::LoadErrorPage(nsIURI* aErrorURI, nsIURI* aFailedURI, nsIChannel* aFa
return InternalLoad(aErrorURI, nullptr, Nothing(), false, false, nullptr, RP_Unset,
nsContentUtils::GetSystemPrincipal(), nullptr,
INTERNAL_LOAD_FLAGS_NONE, EmptyString(),
nullptr, VoidString(), nullptr, nullptr,
VoidCString(), VoidString(), nullptr, nullptr,
LOAD_ERROR_PAGE, nullptr, true, VoidString(), this,
nullptr, nullptr, nullptr);
}
@@ -4934,7 +4797,7 @@ nsDocShell::Reload(uint32_t aReloadFlags)
return NS_OK; // JS may not handle returning of an error code
}
nsresult rv;
NS_ASSERTION(((aReloadFlags & 0xf) == 0),
NS_ASSERTION(((aReloadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0),
"Reload command not updated to use load flags!");
NS_ASSERTION((aReloadFlags & EXTRA_LOAD_FLAGS) == 0,
"Don't pass these flags to Reload");
@@ -5022,7 +4885,7 @@ nsDocShell::Reload(uint32_t aReloadFlags)
triggeringPrincipal,
flags,
EmptyString(), // No window target
NS_LossyConvertUTF16toASCII(contentTypeHint).get(),
NS_LossyConvertUTF16toASCII(contentTypeHint),
VoidString(), // No forced download
nullptr, // No post data
nullptr, // No headers data
@@ -6274,22 +6137,22 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal, int32_t aDel
{
NS_ENSURE_ARG(aURI);
RefPtr<nsDocShellLoadInfo> loadInfo = new nsDocShellLoadInfo();
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState();
/* We do need to pass in a referrer, but we don't want it to
* be sent to the server.
*/
loadInfo->SetSendReferrer(false);
loadState->SetSendReferrer(false);
/* for most refreshes the current URI is an appropriate
* internal referrer
*/
loadInfo->SetReferrer(mCurrentURI);
loadState->SetReferrer(mCurrentURI);
loadInfo->SetOriginalURI(mCurrentURI);
loadInfo->SetResultPrincipalURI(aURI);
loadInfo->SetResultPrincipalURIIsSome(true);
loadInfo->SetKeepResultPrincipalURIIfSet(true);
loadState->SetOriginalURI(mCurrentURI);
loadState->SetResultPrincipalURI(aURI);
loadState->SetResultPrincipalURIIsSome(true);
loadState->SetKeepResultPrincipalURIIfSet(true);
// Set the triggering pricipal to aPrincipal if available, or current
// document's principal otherwise.
@@ -6301,8 +6164,8 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal, int32_t aDel
}
principal = doc->NodePrincipal();
}
loadInfo->SetTriggeringPrincipal(principal);
loadInfo->SetPrincipalIsExplicit(true);
loadState->SetTriggeringPrincipal(principal);
loadState->SetPrincipalIsExplicit(true);
/* Check if this META refresh causes a redirection
* to another site.
@@ -6315,7 +6178,7 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal, int32_t aDel
* we have in mind (15000 ms as defined by REFRESH_REDIRECT_TIMER).
* Pass a REPLACE flag to LoadURI().
*/
loadInfo->SetLoadType(LOAD_NORMAL_REPLACE);
loadState->SetLoadType(LOAD_NORMAL_REPLACE);
/* for redirects we mimic HTTP, which passes the
* original referrer
@@ -6323,17 +6186,21 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal, int32_t aDel
nsCOMPtr<nsIURI> internalReferrer;
GetReferringURI(getter_AddRefs(internalReferrer));
if (internalReferrer) {
loadInfo->SetReferrer(internalReferrer);
loadState->SetReferrer(internalReferrer);
}
} else {
loadInfo->SetLoadType(LOAD_REFRESH);
loadState->SetLoadType(LOAD_REFRESH);
}
loadState->SetURI(aURI);
loadState->SetLoadFlags(nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL);
loadState->SetFirstParty(true);
/*
* LoadURI(...) will cancel all refresh timers... This causes the
* Timer and its refreshData instance to be released...
*/
LoadURI(aURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL, true);
LoadURI(loadState);
return NS_OK;
}
@@ -9100,7 +8967,7 @@ public:
nsIPrincipal* aTriggeringPrincipal,
nsIPrincipal* aPrincipalToInherit,
uint32_t aFlags,
const char* aTypeHint,
const nsACString& aTypeHint,
nsIInputStream* aPostData,
nsIInputStream* aHeadersData,
uint32_t aLoadType,
@@ -9110,6 +8977,7 @@ public:
nsIDocShell* aSourceDocShell,
nsIURI* aBaseURI)
: mozilla::Runnable("InternalLoadEvent")
, mTypeHint(aTypeHint)
, mSrcdoc(aSrcdoc)
, mDocShell(aDocShell)
, mURI(aURI)
@@ -9130,12 +8998,6 @@ public:
, mSourceDocShell(aSourceDocShell)
, mBaseURI(aBaseURI)
{
// Make sure to keep null things null as needed
if (aTypeHint) {
mTypeHint = aTypeHint;
} else {
mTypeHint.SetIsVoid(true);
}
}
NS_IMETHOD
@@ -9148,8 +9010,7 @@ public:
mReferrerPolicy,
mTriggeringPrincipal, mPrincipalToInherit,
mFlags, EmptyString(),
mTypeHint.IsVoid() ? nullptr
: mTypeHint.get(),
mTypeHint,
VoidString(), mPostData,
mHeadersData, mLoadType, mSHEntry,
mFirstParty, mSrcdoc, mSourceDocShell,
@@ -9220,7 +9081,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
nsIPrincipal* aPrincipalToInherit,
uint32_t aFlags,
const nsAString& aWindowTarget,
const char* aTypeHint,
const nsACString& aTypeHint,
const nsAString& aFileName,
nsIInputStream* aPostData,
nsIInputStream* aHeadersData,
@@ -9501,31 +9362,31 @@ nsDocShell::InternalLoad(nsIURI* aURI,
MOZ_ASSERT(!aSHEntry);
MOZ_ASSERT(aFirstParty); // Windowwatcher will assume this.
RefPtr<nsDocShellLoadInfo> loadInfo = new nsDocShellLoadInfo();
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState();
// Set up our loadinfo so it will do the load as much like we would have
// as possible.
loadInfo->SetReferrer(aReferrer);
loadInfo->SetReferrerPolicy((mozilla::net::ReferrerPolicy)aReferrerPolicy);
loadInfo->SetSendReferrer(!(aFlags &
loadState->SetReferrer(aReferrer);
loadState->SetReferrerPolicy((mozilla::net::ReferrerPolicy)aReferrerPolicy);
loadState->SetSendReferrer(!(aFlags &
INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER));
loadInfo->SetOriginalURI(aOriginalURI);
loadInfo->SetMaybeResultPrincipalURI(aResultPrincipalURI);
loadInfo->SetKeepResultPrincipalURIIfSet(aKeepResultPrincipalURIIfSet);
loadInfo->SetLoadReplace(aLoadReplace);
loadInfo->SetTriggeringPrincipal(aTriggeringPrincipal);
loadInfo->SetInheritPrincipal(
loadState->SetOriginalURI(aOriginalURI);
loadState->SetMaybeResultPrincipalURI(aResultPrincipalURI);
loadState->SetKeepResultPrincipalURIIfSet(aKeepResultPrincipalURIIfSet);
loadState->SetLoadReplace(aLoadReplace);
loadState->SetTriggeringPrincipal(aTriggeringPrincipal);
loadState->SetInheritPrincipal(
aFlags & INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL);
// Explicit principal because we do not want any guesses as to what the
// principal to inherit is: it should be aTriggeringPrincipal.
loadInfo->SetPrincipalIsExplicit(true);
loadInfo->SetLoadType(LOAD_LINK);
loadInfo->SetForceAllowDataURI(aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI);
loadState->SetPrincipalIsExplicit(true);
loadState->SetLoadType(LOAD_LINK);
loadState->SetForceAllowDataURI(aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI);
rv = win->Open(NS_ConvertUTF8toUTF16(spec),
aWindowTarget, // window name
EmptyString(), // Features
loadInfo,
loadState,
true, // aForceNoOpener
getter_AddRefs(newWin));
MOZ_ASSERT(!newWin);
@@ -10336,7 +10197,7 @@ nsDocShell::DoURILoad(nsIURI* aURI,
uint32_t aReferrerPolicy,
nsIPrincipal* aTriggeringPrincipal,
nsIPrincipal* aPrincipalToInherit,
const char* aTypeHint,
const nsACString& aTypeHint,
const nsAString& aFileName,
nsIInputStream* aPostData,
nsIInputStream* aHeadersData,
@@ -10685,8 +10546,8 @@ nsDocShell::DoURILoad(nsIURI* aURI,
loadInfo->SetResultPrincipalURI(aResultPrincipalURI.ref());
}
if (aTypeHint && *aTypeHint) {
channel->SetContentType(nsDependentCString(aTypeHint));
if (!aTypeHint.IsVoid()) {
channel->SetContentType(aTypeHint);
mContentTypeHint = aTypeHint;
} else {
mContentTypeHint.Truncate();
@@ -12240,7 +12101,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType)
principalToInherit,
flags,
EmptyString(), // No window target
contentType.get(), // Type hint
contentType, // Type hint
VoidString(), // No forced file download
postData, // Post data stream
nullptr, // No headers stream
@@ -13428,7 +13289,7 @@ nsDocShell::OnLinkClickSync(nsIContent* aContent,
aContent->NodePrincipal(),
flags,
target, // Window target
NS_LossyConvertUTF16toASCII(typeHint).get(),
NS_LossyConvertUTF16toASCII(typeHint),
aFileName, // Download as file
aPostDataStream, // Post data stream
aHeadersDataStream, // Headers stream