Bug 1271516 - Introducing nsIWebNavigation.setOriginAttributesBeforeLoading, r=smaug

This commit is contained in:
Andrea Marchesini 2016-06-07 00:47:13 +02:00
Родитель 8524414783
Коммит 943c6e667c
14 изменённых файлов: 151 добавлений и 32 удалений

Просмотреть файл

@ -831,6 +831,10 @@ function _loadURIWithFlags(browser, uri, params) {
}
try {
if (!mustChangeProcess) {
if (params.userContextId) {
browser.webNavigation.setOriginAttributesBeforeLoading({ userContextId: params.userContextId });
}
browser.webNavigation.loadURIWithOptions(uri, flags,
referrer, referrerPolicy,
postData, null, null);
@ -839,13 +843,19 @@ function _loadURIWithFlags(browser, uri, params) {
postData = NetUtil.readInputStreamToString(postData, postData.available());
}
LoadInOtherProcess(browser, {
let loadParams = {
uri: uri,
flags: flags,
referrer: referrer ? referrer.spec : null,
referrerPolicy: referrerPolicy,
postData: postData,
});
postData: postData
}
if (params.userContextId) {
loadParams.userContextId = params.userContextId;
}
LoadInOtherProcess(browser, loadParams);
}
} catch (e) {
// If anything goes wrong when switching remoteness, just switch remoteness
@ -856,6 +866,11 @@ function _loadURIWithFlags(browser, uri, params) {
if (mustChangeProcess) {
Cu.reportError(e);
gBrowser.updateBrowserRemotenessByURL(browser, uri);
if (params.userContextId) {
browser.webNavigation.setOriginAttributesBeforeLoading({ userContextId: params.userContextId });
}
browser.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy,
postData, null, null);
} else {
@ -1126,6 +1141,7 @@ var gBrowserInit = {
// [3]: postData (nsIInputStream)
// [4]: allowThirdPartyFixup (bool)
// [5]: referrerPolicy (int)
// [6]: userContextId (int)
else if (window.arguments.length >= 3) {
let referrerURI = window.arguments[2];
if (typeof(referrerURI) == "string") {
@ -1137,8 +1153,10 @@ var gBrowserInit = {
}
let referrerPolicy = (window.arguments[5] != undefined ?
window.arguments[5] : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
let userContextId = (window.arguments[6] != undefined ?
window.arguments[6] : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID);
loadURI(uriToLoad, referrerURI, window.arguments[3] || null,
window.arguments[4] || false, referrerPolicy);
window.arguments[4] || false, referrerPolicy, userContextId);
window.focus();
}
// Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3.
@ -1999,13 +2017,15 @@ function BrowserTryToCloseWindow()
window.close(); // WindowIsClosing does all the necessary checks
}
function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy) {
function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy,
userContextId) {
try {
openLinkIn(uri, "current",
{ referrerURI: referrer,
referrerPolicy: referrerPolicy,
postData: postData,
allowThirdPartyFixup: allowThirdPartyFixup });
allowThirdPartyFixup: allowThirdPartyFixup,
userContextId: userContextId });
} catch (e) {}
}

Просмотреть файл

@ -887,7 +887,12 @@ var UserContextIdNotifier = {
// Just because we cannot change the userContextId from an active docShell,
// we don't need to check DOMContentLoaded again.
this.uninit();
let userContextId = content.document.nodePrincipal.originAttributes.userContextId;
// We use the docShell because content.document can have been loaded before
// setting the originAttributes.
let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
let userContextId = loadContext.originAttributes.userContextId;
sendAsyncMessage("Browser:WindowCreated", { userContextId });
}
};

Просмотреть файл

@ -274,12 +274,17 @@ function openLinkIn(url, where, params) {
createInstance(Ci.nsISupportsPRUint32);
referrerPolicySupports.data = aReferrerPolicy;
var userContextIdSupports = Cc["@mozilla.org/supports-PRUint32;1"].
createInstance(Ci.nsISupportsPRUint32);
userContextIdSupports.data = aUserContextId;
sa.AppendElement(wuri);
sa.AppendElement(charset);
sa.AppendElement(referrerURISupports);
sa.AppendElement(aPostData);
sa.AppendElement(allowThirdPartyFixupSupports);
sa.AppendElement(referrerPolicySupports);
sa.AppendElement(userContextIdSupports);
let features = "chrome,dialog=no,all";
if (aIsPrivate) {
@ -352,6 +357,7 @@ function openLinkIn(url, where, params) {
referrerURI: aNoReferrer ? null : aReferrerURI,
referrerPolicy: aReferrerPolicy,
postData: aPostData,
userContextId: aUserContextId
});
break;
case "tabshifted":

Просмотреть файл

@ -204,6 +204,11 @@ ContentRestoreInternal.prototype = {
: Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
let postData = loadArguments.postData ?
Utils.makeInputStream(loadArguments.postData) : null;
if (loadArguments.userContextId) {
webNavigation.setOriginAttributesBeforeLoading({ userContextId: loadArguments.userContextId });
}
webNavigation.loadURIWithOptions(loadArguments.uri, loadArguments.flags,
referrer, referrerPolicy, postData,
null, null);

Просмотреть файл

@ -14,6 +14,7 @@
#include "mozilla/BasePrincipal.h"
#include "mozilla/Casting.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ChromeUtils.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
@ -3664,7 +3665,7 @@ nsDocShell::FindItemWithName(const char16_t* aName,
}
void
nsDocShell::AssertOriginAttributesMatchPrivateBrowsing(){
nsDocShell::AssertOriginAttributesMatchPrivateBrowsing() {
MOZ_ASSERT((mOriginAttributes.mPrivateBrowsingId != 0) == mInPrivateBrowsing);
}
@ -7935,6 +7936,13 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
// mContentViewer->PermitUnload may release |this| docshell.
nsCOMPtr<nsIDocShell> kungFuDeathGrip(this);
if (aPrincipal && !nsContentUtils::IsSystemPrincipal(aPrincipal) &&
mItemType != typeChrome) {
MOZ_ASSERT(ChromeUtils::IsOriginAttributesEqual(
BasePrincipal::Cast(aPrincipal)->OriginAttributesRef(),
mOriginAttributes));
}
// Make sure timing is created. But first record whether we had it
// already, so we don't clobber the timing for an in-progress load.
bool hadTiming = mTiming;
@ -10752,7 +10760,10 @@ nsDocShell::DoURILoad(nsIURI* aURI,
// parent document.
NeckoOriginAttributes neckoAttrs;
neckoAttrs.InheritFromDocShellToNecko(GetOriginAttributes());
loadInfo->SetOriginAttributes(neckoAttrs);
rv = loadInfo->SetOriginAttributes(neckoAttrs);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!isSrcdoc) {
rv = NS_NewChannelInternal(getter_AddRefs(channel),
@ -14126,10 +14137,13 @@ nsDocShell::GetOriginAttributes(JSContext* aCx,
return NS_OK;
}
void
nsresult
nsDocShell::SetOriginAttributes(const DocShellOriginAttributes& aAttrs)
{
MOZ_ASSERT(mChildList.Length() == 0);
MOZ_ASSERT(mChildList.IsEmpty());
if (!mChildList.IsEmpty()) {
return NS_ERROR_FAILURE;
}
// TODO: Bug 1273058 - mContentViewer should be null when setting origin
// attributes.
@ -14138,15 +14152,43 @@ nsDocShell::SetOriginAttributes(const DocShellOriginAttributes& aAttrs)
if (doc) {
nsIURI* uri = doc->GetDocumentURI();
MOZ_ASSERT(uri);
if (uri) {
nsAutoCString uriSpec;
uri->GetSpec(uriSpec);
MOZ_ASSERT(uriSpec.EqualsLiteral("about:blank"));
if (!uri) {
return NS_ERROR_FAILURE;
}
nsAutoCString uriSpec;
uri->GetSpec(uriSpec);
MOZ_ASSERT(uriSpec.EqualsLiteral("about:blank"));
if (!uriSpec.EqualsLiteral("about:blank")) {
return NS_ERROR_FAILURE;
}
}
}
mOriginAttributes = aAttrs;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetOriginAttributesBeforeLoading(JS::Handle<JS::Value> aOriginAttributes)
{
if (!aOriginAttributes.isObject()) {
return NS_ERROR_INVALID_ARG;
}
AutoJSAPI jsapi;
jsapi.Init(&aOriginAttributes.toObject());
JSContext* cx = jsapi.cx();
if (NS_WARN_IF(!cx)) {
return NS_ERROR_FAILURE;
}
DocShellOriginAttributes attrs;
if (!aOriginAttributes.isObject() || !attrs.Init(cx, aOriginAttributes)) {
return NS_ERROR_INVALID_ARG;
}
return SetOriginAttributes(attrs);
}
NS_IMETHODIMP
@ -14158,8 +14200,7 @@ nsDocShell::SetOriginAttributes(JS::Handle<JS::Value> aOriginAttributes,
return NS_ERROR_INVALID_ARG;
}
SetOriginAttributes(attrs);
return NS_OK;
return SetOriginAttributes(attrs);
}
NS_IMETHODIMP

Просмотреть файл

@ -277,7 +277,7 @@ public:
return mOriginAttributes;
}
void SetOriginAttributes(const mozilla::DocShellOriginAttributes& aAttrs);
nsresult SetOriginAttributes(const mozilla::DocShellOriginAttributes& aAttrs);
void GetInterceptedDocumentId(nsAString& aId)
{

Просмотреть файл

@ -355,4 +355,10 @@ interface nsIWebNavigation : nsISupports
* The session history object used by this web navigation instance.
*/
attribute nsISHistory sessionHistory;
/**
* Set an OriginAttributes dictionary in the docShell. This can be done only
* before loading any content.
*/
void setOriginAttributesBeforeLoading(in jsval originAttributes);
};

Просмотреть файл

@ -1496,6 +1496,12 @@ nsSHistory::LoadURIWithOptions(const char16_t* aURI,
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::SetOriginAttributesBeforeLoading(JS::HandleValue aOriginAttributes)
{
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::LoadURI(const char16_t* aURI,
uint32_t aLoadFlags,

Просмотреть файл

@ -174,6 +174,13 @@ ChromeUtils::FillNonDefaultOriginAttributes(dom::GlobalObject& aGlobal,
ChromeUtils::IsOriginAttributesEqual(dom::GlobalObject& aGlobal,
const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB)
{
return IsOriginAttributesEqual(aA, aB);
}
/* static */ bool
ChromeUtils::IsOriginAttributesEqual(const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB)
{
return aA.mAddonId == aB.mAddonId &&
aA.mAppId == aB.mAppId &&

Просмотреть файл

@ -87,6 +87,10 @@ public:
IsOriginAttributesEqual(dom::GlobalObject& aGlobal,
const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB);
static bool
IsOriginAttributesEqual(const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB);
};
} // namespace dom

Просмотреть файл

@ -657,6 +657,12 @@ nsWebBrowser::LoadURIWithOptions(const char16_t* aURI, uint32_t aLoadFlags,
aExtraHeaderStream, aBaseURI);
}
NS_IMETHODIMP
nsWebBrowser::SetOriginAttributesBeforeLoading(JS::Handle<JS::Value> aOriginAttributes)
{
return mDocShellAsNav->SetOriginAttributesBeforeLoading(aOriginAttributes);
}
NS_IMETHODIMP
nsWebBrowser::LoadURI(const char16_t* aURI, uint32_t aLoadFlags,
nsIURI* aReferringURI,

Просмотреть файл

@ -942,6 +942,18 @@ nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy* aParent,
nullptr;
if (windowIsNew) {
auto* docShell = static_cast<nsDocShell*>(newDocShell.get());
// If this is not a chrome docShell, we apply originAttributes from the
// subjectPrincipal.
if (subjectPrincipal &&
docShell->ItemType() != nsIDocShellTreeItem::typeChrome) {
DocShellOriginAttributes attrs;
attrs.InheritFromDocToChildDocShell(BasePrincipal::Cast(subjectPrincipal)->OriginAttributesRef());
docShell->SetOriginAttributes(attrs);
}
// Now set the opener principal on the new window. Note that we need to do
// this no matter whether we were opened from JS; if there is nothing on
// the JS stack, just use the principal of our parent window. In those
@ -1026,20 +1038,6 @@ nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy* aParent,
}
}
// If this is a new window, we must set the userContextId from the
// subjectPrincipal.
if (windowIsNew && subjectPrincipal) {
uint32_t userContextId;
rv = subjectPrincipal->GetUserContextId(&userContextId);
NS_ENSURE_SUCCESS(rv, rv);
auto* docShell = static_cast<nsDocShell*>(newDocShell.get());
DocShellOriginAttributes attr = docShell->GetOriginAttributes();
attr.mUserContextId = userContextId;
docShell->SetOriginAttributes(attr);
}
if (isNewToplevelWindow) {
// Notify observers that the window is open and ready.
// The window has not yet started to load a document.

Просмотреть файл

@ -87,6 +87,11 @@ RemoteWebNavigation.prototype = {
baseURI: aBaseURI ? aBaseURI.spec : null,
});
},
setOriginAttributesBeforeLoading: function(aOriginAttributes) {
this._sendMessage("WebNavigation:SetOriginAttributes", {
originAttributes: aOriginAttributes,
});
},
reload: function(aReloadFlags) {
this._sendMessage("WebNavigation:Reload", {flags: aReloadFlags});
},

Просмотреть файл

@ -238,6 +238,7 @@ var WebNavigation = {
addMessageListener("WebNavigation:GoForward", this);
addMessageListener("WebNavigation:GotoIndex", this);
addMessageListener("WebNavigation:LoadURI", this);
addMessageListener("WebNavigation:SetOriginAttributes", this);
addMessageListener("WebNavigation:Reload", this);
addMessageListener("WebNavigation:Stop", this);
},
@ -269,6 +270,9 @@ var WebNavigation = {
message.data.postData, message.data.headers,
message.data.baseURI);
break;
case "WebNavigation:SetOriginAttributes":
this.setOriginAttributes(message.data.originAttributes);
break;
case "WebNavigation:Reload":
this.reload(message.data.flags);
break;
@ -330,6 +334,12 @@ var WebNavigation = {
});
},
setOriginAttributes: function(originAttributes) {
if (originAttributes) {
this.webNavigation.setOriginAttributesBeforeLoading(originAttributes);
}
},
reload: function(flags) {
this.webNavigation.reload(flags);
},