Bug 1396856: Part 2 - Add top outer window ID to LoadInfo. r?ehsan
The WebRequest API needs to know if a given window ID is at the top level, for
various reasons. It currently figures this out by mapping a channel's load
context to a <browser> element, which tracks its current top outer window ID.
But this is inefficient, and not friendly to C++ callers.
Adding the top window ID to the load info simplifies things considerably.
MozReview-Commit-ID: Fy0gxTqQZMZ
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -382,16 +382,17 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa
static_cast<uint32_t>(aLoadInfo->GetTainting()),
aLoadInfo->GetUpgradeInsecureRequests(),
aLoadInfo->GetVerifySignedContent(),
aLoadInfo->GetEnforceSRI(),
aLoadInfo->GetForceInheritPrincipalDropped(),
aLoadInfo->GetInnerWindowID(),
aLoadInfo->GetOuterWindowID(),
aLoadInfo->GetParentOuterWindowID(),
+ aLoadInfo->GetTopOuterWindowID(),
aLoadInfo->GetFrameOuterWindowID(),
aLoadInfo->GetEnforceSecurity(),
aLoadInfo->GetInitialSecurityCheckDone(),
aLoadInfo->GetIsInThirdPartyContext(),
aLoadInfo->GetOriginAttributes(),
redirectChainIncludingInternalRedirects,
redirectChain,
aLoadInfo->CorsUnsafeHeaders(),
@@ -477,16 +478,17 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
static_cast<LoadTainting>(loadInfoArgs.tainting()),
loadInfoArgs.upgradeInsecureRequests(),
loadInfoArgs.verifySignedContent(),
loadInfoArgs.enforceSRI(),
loadInfoArgs.forceInheritPrincipalDropped(),
loadInfoArgs.innerWindowID(),
loadInfoArgs.outerWindowID(),
loadInfoArgs.parentOuterWindowID(),
+ loadInfoArgs.topOuterWindowID(),
loadInfoArgs.frameOuterWindowID(),
loadInfoArgs.enforceSecurity(),
loadInfoArgs.initialSecurityCheckDone(),
loadInfoArgs.isInThirdPartyContext(),
loadInfoArgs.originAttributes(),
redirectChainIncludingInternalRedirects,
redirectChain,
loadInfoArgs.corsUnsafeHeaders(),
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -24,16 +24,26 @@
#include "NullPrincipal.h"
#include "nsRedirectHistoryEntry.h"
using namespace mozilla::dom;
namespace mozilla {
namespace net {
+uint64_t
+FindTopOuterWindowID(nsPIDOMWindowOuter* aOuter)
+{
+ nsCOMPtr<nsPIDOMWindowOuter> outer = aOuter;
+ while (nsCOMPtr<nsPIDOMWindowOuter> parent = outer->GetScriptableParentOrNull()) {
+ outer = parent;
+ }
+ return outer->WindowID();
+}
+
LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
nsIPrincipal* aTriggeringPrincipal,
nsINode* aLoadingContext,
nsSecurityFlags aSecurityFlags,
nsContentPolicyType aContentPolicyType)
: mLoadingPrincipal(aLoadingContext ?
aLoadingContext->NodePrincipal() : aLoadingPrincipal)
, mTriggeringPrincipal(aTriggeringPrincipal ?
@@ -45,16 +55,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
, mTainting(LoadTainting::Basic)
, mUpgradeInsecureRequests(false)
, mVerifySignedContent(false)
, mEnforceSRI(false)
, mForceInheritPrincipalDropped(false)
, mInnerWindowID(0)
, mOuterWindowID(0)
, mParentOuterWindowID(0)
+ , mTopOuterWindowID(0)
, mFrameOuterWindowID(0)
, mEnforceSecurity(false)
, mInitialSecurityCheckDone(false)
, mIsThirdPartyContext(false)
, mForcePreflight(false)
, mIsPreflight(false)
, mForceHSTSPriming(false)
, mMixedContentWouldBlock(false)
@@ -97,16 +108,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
if (aLoadingContext) {
nsCOMPtr<nsPIDOMWindowOuter> contextOuter = aLoadingContext->OwnerDoc()->GetWindow();
if (contextOuter) {
ComputeIsThirdPartyContext(contextOuter);
mOuterWindowID = contextOuter->WindowID();
nsCOMPtr<nsPIDOMWindowOuter> parent = contextOuter->GetScriptableParent();
mParentOuterWindowID = parent ? parent->WindowID() : mOuterWindowID;
+ mTopOuterWindowID = FindTopOuterWindowID(contextOuter);
}
mInnerWindowID = aLoadingContext->OwnerDoc()->InnerWindowID();
// When the element being loaded is a frame, we choose the frame's window
// for the window ID and the frame element's window as the parent
// window. This is the behavior that Chrome exposes to add-ons.
// NB: If the frameLoaderOwner doesn't have a frame loader, then the load
@@ -220,16 +232,17 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* a
, mTainting(LoadTainting::Basic)
, mUpgradeInsecureRequests(false)
, mVerifySignedContent(false)
, mEnforceSRI(false)
, mForceInheritPrincipalDropped(false)
, mInnerWindowID(0)
, mOuterWindowID(0)
, mParentOuterWindowID(0)
+ , mTopOuterWindowID(0)
, mFrameOuterWindowID(0)
, mEnforceSecurity(false)
, mInitialSecurityCheckDone(false)
, mIsThirdPartyContext(false) // NB: TYPE_DOCUMENT implies not third-party.
, mForcePreflight(false)
, mIsPreflight(false)
, mForceHSTSPriming(false)
, mMixedContentWouldBlock(false)
@@ -250,16 +263,17 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* a
// NB: Ignore the current inner window since we're navigating away from it.
mOuterWindowID = aOuterWindow->WindowID();
// TODO We can have a parent without a frame element in some cases dealing
// with the hidden window.
nsCOMPtr<nsPIDOMWindowOuter> parent = aOuterWindow->GetScriptableParent();
mParentOuterWindowID = parent ? parent->WindowID() : 0;
+ mTopOuterWindowID = FindTopOuterWindowID(aOuterWindow);
// get the docshell from the outerwindow, and then get the originattributes
nsCOMPtr<nsIDocShell> docShell = aOuterWindow->GetDocShell();
MOZ_ASSERT(docShell);
mOriginAttributes = nsDocShell::Cast(docShell)->GetOriginAttributes();
#ifdef DEBUG
if (docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
@@ -281,16 +295,17 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
, mTainting(rhs.mTainting)
, mUpgradeInsecureRequests(rhs.mUpgradeInsecureRequests)
, mVerifySignedContent(rhs.mVerifySignedContent)
, mEnforceSRI(rhs.mEnforceSRI)
, mForceInheritPrincipalDropped(rhs.mForceInheritPrincipalDropped)
, mInnerWindowID(rhs.mInnerWindowID)
, mOuterWindowID(rhs.mOuterWindowID)
, mParentOuterWindowID(rhs.mParentOuterWindowID)
+ , mTopOuterWindowID(rhs.mTopOuterWindowID)
, mFrameOuterWindowID(rhs.mFrameOuterWindowID)
, mEnforceSecurity(rhs.mEnforceSecurity)
, mInitialSecurityCheckDone(rhs.mInitialSecurityCheckDone)
, mIsThirdPartyContext(rhs.mIsThirdPartyContext)
, mOriginAttributes(rhs.mOriginAttributes)
, mRedirectChainIncludingInternalRedirects(
rhs.mRedirectChainIncludingInternalRedirects)
, mRedirectChain(rhs.mRedirectChain)
@@ -314,16 +329,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
LoadTainting aTainting,
bool aUpgradeInsecureRequests,
bool aVerifySignedContent,
bool aEnforceSRI,
bool aForceInheritPrincipalDropped,
uint64_t aInnerWindowID,
uint64_t aOuterWindowID,
uint64_t aParentOuterWindowID,
+ uint64_t aTopOuterWindowID,
uint64_t aFrameOuterWindowID,
bool aEnforceSecurity,
bool aInitialSecurityCheckDone,
bool aIsThirdPartyContext,
const OriginAttributes& aOriginAttributes,
RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
RedirectHistoryArray& aRedirectChain,
const nsTArray<nsCString>& aCorsUnsafeHeaders,
@@ -342,16 +358,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
, mTainting(aTainting)
, mUpgradeInsecureRequests(aUpgradeInsecureRequests)
, mVerifySignedContent(aVerifySignedContent)
, mEnforceSRI(aEnforceSRI)
, mForceInheritPrincipalDropped(aForceInheritPrincipalDropped)
, mInnerWindowID(aInnerWindowID)
, mOuterWindowID(aOuterWindowID)
, mParentOuterWindowID(aParentOuterWindowID)
+ , mTopOuterWindowID(aTopOuterWindowID)
, mFrameOuterWindowID(aFrameOuterWindowID)
, mEnforceSecurity(aEnforceSecurity)
, mInitialSecurityCheckDone(aInitialSecurityCheckDone)
, mIsThirdPartyContext(aIsThirdPartyContext)
, mOriginAttributes(aOriginAttributes)
, mCorsUnsafeHeaders(aCorsUnsafeHeaders)
, mForcePreflight(aForcePreflight)
, mIsPreflight(aIsPreflight)
@@ -705,16 +722,23 @@ LoadInfo::GetOuterWindowID(uint64_t* aRe
NS_IMETHODIMP
LoadInfo::GetParentOuterWindowID(uint64_t* aResult)
{
*aResult = mParentOuterWindowID;
return NS_OK;
}
NS_IMETHODIMP
+LoadInfo::GetTopOuterWindowID(uint64_t* aResult)
+{
+ *aResult = mTopOuterWindowID;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
LoadInfo::GetFrameOuterWindowID(uint64_t* aResult)
{
*aResult = mFrameOuterWindowID;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetScriptableOriginAttributes(JSContext* aCx,
--- a/netwerk/base/LoadInfo.h
+++ b/netwerk/base/LoadInfo.h
@@ -100,16 +100,17 @@ private:
LoadTainting aTainting,
bool aUpgradeInsecureRequests,
bool aVerifySignedContent,
bool aEnforceSRI,
bool aForceInheritPrincipalDropped,
uint64_t aInnerWindowID,
uint64_t aOuterWindowID,
uint64_t aParentOuterWindowID,
+ uint64_t aTopOuterWindowID,
uint64_t aFrameOuterWindowID,
bool aEnforceSecurity,
bool aInitialSecurityCheckDone,
bool aIsThirdPartyRequest,
const OriginAttributes& aOriginAttributes,
RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
RedirectHistoryArray& aRedirectChain,
const nsTArray<nsCString>& aUnsafeHeaders,
@@ -151,16 +152,17 @@ private:
LoadTainting mTainting;
bool mUpgradeInsecureRequests;
bool mVerifySignedContent;
bool mEnforceSRI;
bool mForceInheritPrincipalDropped;
uint64_t mInnerWindowID;
uint64_t mOuterWindowID;
uint64_t mParentOuterWindowID;
+ uint64_t mTopOuterWindowID;
uint64_t mFrameOuterWindowID;
bool mEnforceSecurity;
bool mInitialSecurityCheckDone;
bool mIsThirdPartyContext;
OriginAttributes mOriginAttributes;
RedirectHistoryArray mRedirectChainIncludingInternalRedirects;
RedirectHistoryArray mRedirectChain;
nsTArray<nsCString> mCorsUnsafeHeaders;
--- a/netwerk/base/nsILoadInfo.idl
+++ b/netwerk/base/nsILoadInfo.idl
@@ -501,16 +501,17 @@ interface nsILoadInfo : nsISupports
*
* Note that these window IDs can be 0 if the window is not
* available. parentOuterWindowID will be the same as outerWindowID if the
* window has no parent.
*/
[infallible] readonly attribute unsigned long long innerWindowID;
[infallible] readonly attribute unsigned long long outerWindowID;
[infallible] readonly attribute unsigned long long parentOuterWindowID;
+ [infallible] readonly attribute unsigned long long topOuterWindowID;
/**
* Only when the element being loaded is <frame src="foo.html">
* (or, more generally, if the element QIs to nsIFrameLoaderOwner),
* the frameOuterWindowID is the outer window containing the
* foo.html document.
*
* Note: For other cases, frameOuterWindowID is 0.
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -46,16 +46,17 @@ struct LoadInfoArgs
uint32_t tainting;
bool upgradeInsecureRequests;
bool verifySignedContent;
bool enforceSRI;
bool forceInheritPrincipalDropped;
uint64_t innerWindowID;
uint64_t outerWindowID;
uint64_t parentOuterWindowID;
+ uint64_t topOuterWindowID;
uint64_t frameOuterWindowID;
bool enforceSecurity;
bool initialSecurityCheckDone;
bool isInThirdPartyContext;
OriginAttributes originAttributes;
RedirectHistoryEntryInfo[] redirectChainIncludingInternalRedirects;
RedirectHistoryEntryInfo[] redirectChain;
nsCString[] corsUnsafeHeaders;