Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - ioservice/ changes (r=sicking,sworkman)

This commit is contained in:
Christoph Kerschbaumer 2014-12-12 09:05:21 -08:00
parent d1614ac429
commit 09b44e1b01
3 changed files with 181 additions and 10 deletions

View File

@ -67,8 +67,61 @@ interface nsIIOService : nsISupports
/**
* Creates a channel for a given URI.
*
* @param aURI nsIURI from which to make a channel
* Please note, if you provide both a loadingNode and a loadingPrincipal,
* then loadingPrincipal must be equal to loadingNode->NodePrincipal().
* But less error prone is to just supply a loadingNode.
*
* @param aURI
* nsIURI from which to make a channel
* @param aLoadingNode
* The loadingDocument of the channel.
* The element or document where the result of this request will be
* used. This is the document/element that will get access to the
* result of this request. For example for an image load, it's the
* document in which the image will be loaded. And for a CSS
* stylesheet it's the document whose rendering will be affected by
* the stylesheet.
* If possible, pass in the element which is performing the load. But
* if the load is coming from a JS API (such as XMLHttpRequest) or if
* the load might be coalesced across multiple elements (such as
* for <img>) then pass in the Document node instead.
* For loads that are not related to any document, such as loads coming
* from addons or internal browser features, use null here.
* @param aLoadingPrincipal
* The loadingPrincipal of the channel.
* The principal of the document where the result of this request will
* be used.
* This is generally the principal of the aLoadingNode. However for
* loads where aLoadingNode is null this argument still needs to be
* passed. For example for loads from a WebWorker, pass the principal
* of that worker. For loads from an addon or from internal browser
* features, pass the system principal.
* This principal should almost always be the system principal if
* aLoadingNode is null. The only exception to this is for loads
* from WebWorkers since they don't have any nodes to be passed as
* aLoadingNode.
* Please note, aLoadingPrincipal is *not* the principal of the
* resource being loaded. But rather the principal of the context
* where the resource will be used.
* @param aTriggeringPrincipal
* The triggeringPrincipal of the load.
* The triggeringPrincipal is the principal of the resource that caused
* this particular URL to be loaded.
* Most likely the triggeringPrincipal and the loadingPrincipal are
* identical, in which case the triggeringPrincipal can be left out.
* In some cases the loadingPrincipal and the triggeringPrincipal are
* different however, e.g. a stylesheet may import a subresource. In
* that case the principal of the stylesheet which contains the
* import command is the triggeringPrincipal, and the principal of
* the document whose rendering is affected is the loadingPrincipal.
* @param aSecurityFlags
* The securityFlags of the channel.
* Any of the securityflags defined in nsILoadInfo.idl
* @param aContentPolicyType
* The contentPolicyType of the channel.
* Any of the content types defined in nsIContentPolicy.idl
* @return reference to the new nsIChannel object
*
*/
nsIChannel newChannelFromURI2(in nsIURI aURI,
in nsIDOMNode aLoadingNode,
@ -86,7 +139,7 @@ interface nsIIOService : nsISupports
nsIChannel newChannelFromURI(in nsIURI aURI);
/**
* Equivalent to newChannelFromURI(newURI(...))
* Equivalent to newChannelFromURI2(newURI(...))
*/
nsIChannel newChannel2(in AUTF8String aSpec,
in string aOriginCharset,

View File

@ -33,12 +33,66 @@ interface nsIIOService2 : nsIIOService
/**
* Creates a channel for a given URI.
*
* @param aURI nsIURI from which to make a channel
* @param aProxyURI nsIURI to use for proxy resolution. Can be null in which
* Please note, if you provide both a loadingNode and a loadingPrincipal,
* then loadingPrincipal must be equal to loadingNode->NodePrincipal().
* But less error prone is to just supply a loadingNode.
*
* @param aURI
* nsIURI from which to make a channel
* @param aProxyURI
* nsIURI to use for proxy resolution. Can be null in which
* case aURI is used
* @param aProxyFlags flags from nsIProtocolProxyService to use
* when resolving proxies for this new channel
* @param aLoadingNode
* The loadingDocument of the channel.
* The element or document where the result of this request will be
* used. This is the document/element that will get access to the
* result of this request. For example for an image load, it's the
* document in which the image will be loaded. And for a CSS
* stylesheet it's the document whose rendering will be affected by
* the stylesheet.
* If possible, pass in the element which is performing the load. But
* if the load is coming from a JS API (such as XMLHttpRequest) or if
* the load might be coalesced across multiple elements (such as
* for <img>) then pass in the Document node instead.
* For loads that are not related to any document, such as loads coming
* from addons or internal browser features, use null here.
* @param aLoadingPrincipal
* The loadingPrincipal of the channel.
* The principal of the document where the result of this request will
* be used.
* This is generally the principal of the aLoadingNode. However for
* loads where aLoadingNode is null this argument still needs to be
* passed. For example for loads from a WebWorker, pass the principal
* of that worker. For loads from an addon or from internal browser
* features, pass the system principal.
* This principal should almost always be the system principal if
* aLoadingNode is null. The only exception to this is for loads
* from WebWorkers since they don't have any nodes to be passed as
* aLoadingNode.
* Please note, aLoadingPrincipal is *not* the principal of the
* resource being loaded. But rather the principal of the context
* where the resource will be used.
* @param aTriggeringPrincipal
* The triggeringPrincipal of the load.
* The triggeringPrincipal is the principal of the resource that caused
* this particular URL to be loaded.
* Most likely the triggeringPrincipal and the loadingPrincipal are
* identical, in which case the triggeringPrincipal can be left out.
* In some cases the loadingPrincipal and the triggeringPrincipal are
* different however, e.g. a stylesheet may import a subresource. In
* that case the principal of the stylesheet which contains the
* import command is the triggeringPrincipal, and the principal of
* the document whose rendering is affected is the loadingPrincipal.
* @param aSecurityFlags
* The securityFlags of the channel.
* Any of the securityflags defined in nsILoadInfo.idl
* @param aContentPolicyType
* The contentPolicyType of the channel.
* Any of the content types defined in nsIContentPolicy.idl
* @return reference to the new nsIChannel object
*
*/
nsIChannel newChannelFromURIWithProxyFlags2(in nsIURI aURI,
in nsIURI aProxyURI,

View File

@ -40,6 +40,7 @@
#include "MainThreadUtils.h"
#include "nsIWidget.h"
#include "nsThreadUtils.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/net/NeckoCommon.h"
#ifdef MOZ_WIDGET_GONK
@ -634,13 +635,76 @@ nsIOService::NewChannelFromURIWithProxyFlags2(nsIURI* aURI,
if (NS_FAILED(rv))
return rv;
// Ideally we are creating new channels by calling NewChannel2 (NewProxiedChannel2).
// Keep in mind that Addons can implement their own Protocolhandlers, hence
// NewChannel2() might *not* be implemented.
// We do not want to break those addons, therefore we first try to create a channel
// calling NewChannel2(); if that fails we fall back to creating a channel by calling
// NewChannel();
nsCOMPtr<nsILoadInfo> loadInfo;
// Unfortunately not all callsites (see Bug 1087720, and 1099296) have been updated
// yet to call NewChannel2() instead of NewChannel(), hence those callsites do not
// provide the necessary loadinfo arguments yet.
// Since creating a new loadInfo requires 'aLoadingPrincipal' or 'aLoadingNode' we
// can branch on those arguments as an interim solution.
//
// BUG 1087720: Once that bug lands, we should have a loadInfo for all callers of
// NewChannelFromURIWithProxyFlags2() and should remove the *if* before creating a
// a new loadinfo.
if (aLoadingNode || aLoadingPrincipal) {
nsCOMPtr<nsINode> loadingNode(do_QueryInterface(aLoadingNode));
loadInfo = new mozilla::LoadInfo(aLoadingPrincipal,
aTriggeringPrincipal,
loadingNode,
aSecurityFlags,
aContentPolicyType);
if (!loadInfo) {
return NS_ERROR_UNEXPECTED;
}
}
bool newChannel2Succeeded = true;
nsCOMPtr<nsIProxiedProtocolHandler> pph = do_QueryInterface(handler);
if (pph)
rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI, result);
else
rv = handler->NewChannel(aURI, result);
if (NS_FAILED(rv))
return rv;
if (pph) {
rv = pph->NewProxiedChannel2(aURI, nullptr, aProxyFlags, aProxyURI,
loadInfo, result);
// if calling NewProxiedChannel2() fails we try to fall back to
// creating a new proxied channel by calling NewProxiedChannel().
if (NS_FAILED(rv)) {
newChannel2Succeeded = false;
rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI,
result);
}
}
else {
rv = handler->NewChannel2(aURI, loadInfo, result);
// if calling newChannel2() fails we try to fall back to
// creating a new channel by calling NewChannel().
if (NS_FAILED(rv)) {
newChannel2Succeeded = false;
rv = handler->NewChannel(aURI, result);
}
}
NS_ENSURE_SUCCESS(rv, rv);
if ((aLoadingNode || aLoadingPrincipal) && newChannel2Succeeded) {
// Make sure that all the individual protocolhandlers attach
// a loadInfo within it's implementation of ::newChannel2().
// Once Bug 1087720 lands, we should remove the surrounding
// if-clause here and always assert that we indeed have a
// loadinfo on the newly created channel.
nsCOMPtr<nsILoadInfo> loadInfo;
(*result)->GetLoadInfo(getter_AddRefs(loadInfo));
MOZ_ASSERT(loadInfo);
// If we're sandboxed, make sure to clear any owner the channel
// might already have.
if (loadInfo->GetLoadingSandboxed()) {
(*result)->SetOwner(nullptr);
}
}
// Some extensions override the http protocol handler and provide their own
// implementation. The channels returned from that implementation doesn't