Bug 1566417 - Update to use ReferrerInfo in prefetch and preload URI r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D38323

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Thomas Nguyen 2019-07-19 11:42:09 +00:00
parent 75c80a355d
commit 20e4651f5b
9 changed files with 144 additions and 76 deletions

View File

@ -2,12 +2,23 @@ var prefetch = Cc["@mozilla.org/prefetch-service;1"].getService(
Ci.nsIPrefetchService
);
var ReferrerInfo = Components.Constructor(
"@mozilla.org/referrer-info;1",
"nsIReferrerInfo",
"init"
);
function run_test() {
// Fill up the queue
Services.prefs.setBoolPref("network.prefetch-next", true);
for (var i = 0; i < 5; i++) {
var uri = Services.io.newURI("http://localhost/" + i);
prefetch.prefetchURI(uri, uri, null, true);
var referrerInfo = new ReferrerInfo(
Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
true,
uri
);
prefetch.prefetchURI(uri, referrerInfo, null, true);
}
// Make sure the queue has items in it...
@ -21,7 +32,12 @@ function run_test() {
Services.prefs.setBoolPref("network.prefetch-next", true);
for (var k = 0; k < 5; k++) {
var uri2 = Services.io.newURI("http://localhost/" + k);
prefetch.prefetchURI(uri2, uri2, null, true);
var referrerInfo2 = new ReferrerInfo(
Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
true,
uri2
);
prefetch.prefetchURI(uri2, referrerInfo2, null, true);
}
Assert.ok(prefetch.hasMoreElements());
}

View File

@ -138,9 +138,11 @@ void Link::TryDNSPrefetchOrPreconnectOrPrefetchOrPreloadOrPrerender() {
if (prefetchService) {
nsCOMPtr<nsIURI> uri(GetURI());
if (uri) {
if (linkTypes & nsStyleLinkElement::ePRELOAD) {
bool preload = !!(linkTypes & nsStyleLinkElement::ePRELOAD);
nsContentPolicyType policyType;
if (preload) {
nsAttrValue asAttr;
nsContentPolicyType policyType;
nsAutoString mimeType;
nsAutoString media;
GetContentPolicyMimeTypeMedia(asAttr, policyType, mimeType, media);
@ -154,13 +156,15 @@ void Link::TryDNSPrefetchOrPreconnectOrPrefetchOrPreloadOrPrerender() {
mElement->OwnerDoc())) {
policyType = nsIContentPolicy::TYPE_INVALID;
}
}
prefetchService->PreloadURI(uri,
mElement->OwnerDoc()->GetDocumentURI(),
mElement, policyType);
nsCOMPtr<nsIReferrerInfo> referrerInfo = new ReferrerInfo();
referrerInfo->InitWithNode(mElement);
if (preload) {
prefetchService->PreloadURI(uri, referrerInfo, mElement, policyType);
} else {
prefetchService->PrefetchURI(
uri, mElement->OwnerDoc()->GetDocumentURI(), mElement,
uri, referrerInfo, mElement,
linkTypes & nsStyleLinkElement::ePREFETCH);
}
return;
@ -243,8 +247,10 @@ void Link::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
CORSMode oldCorsMode = Element::AttrValueToCORSMode(aOldValue);
if (corsMode != oldCorsMode) {
prefetchService->CancelPrefetchPreloadURI(uri, mElement);
prefetchService->PreloadURI(uri, mElement->OwnerDoc()->GetDocumentURI(),
mElement, policyType);
nsCOMPtr<nsIReferrerInfo> referrerInfo = new ReferrerInfo();
referrerInfo->InitWithNode(mElement);
prefetchService->PreloadURI(uri, referrerInfo, mElement, policyType);
}
return;
}
@ -303,8 +309,9 @@ void Link::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
// trigger an error event.
if ((policyType != oldPolicyType) ||
(policyType == nsIContentPolicy::TYPE_INVALID)) {
prefetchService->PreloadURI(uri, mElement->OwnerDoc()->GetDocumentURI(),
mElement, policyType);
nsCOMPtr<nsIReferrerInfo> referrerInfo = new ReferrerInfo();
referrerInfo->InitWithNode(mElement);
prefetchService->PreloadURI(uri, referrerInfo, mElement, policyType);
}
}

View File

@ -698,7 +698,7 @@ nsresult nsContentSink::ProcessLinkFromHeader(
if ((linkTypes & nsStyleLinkElement::eNEXT) ||
(linkTypes & nsStyleLinkElement::ePREFETCH) ||
(linkTypes & nsStyleLinkElement::ePRELOAD)) {
PrefetchPreloadHref(aHref, mDocument, linkTypes, aAs, aType, aMedia);
PrefetchPreloadHref(aHref, linkTypes, aAs, aType, aMedia);
}
if (!aHref.IsEmpty() && (linkTypes & nsStyleLinkElement::eDNS_PREFETCH)) {
@ -832,7 +832,7 @@ nsresult nsContentSink::ProcessMETATag(nsIContent* aContent) {
}
void nsContentSink::PrefetchPreloadHref(const nsAString& aHref,
nsINode* aSource, uint32_t aLinkTypes,
uint32_t aLinkTypes,
const nsAString& aAs,
const nsAString& aType,
const nsAString& aMedia) {
@ -843,10 +843,13 @@ void nsContentSink::PrefetchPreloadHref(const nsAString& aHref,
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), aHref, encoding, mDocument->GetDocBaseURI());
if (uri) {
if (aLinkTypes & nsStyleLinkElement::ePRELOAD) {
bool preload = !!(aLinkTypes & nsStyleLinkElement::ePRELOAD);
nsContentPolicyType policyType;
if (preload) {
nsAttrValue asAttr;
Link::ParseAsValue(aAs, asAttr);
nsContentPolicyType policyType = Link::AsValueToContentPolicy(asAttr);
policyType = Link::AsValueToContentPolicy(asAttr);
if (policyType == nsIContentPolicy::TYPE_INVALID) {
// Ignore preload with a wrong or empty as attribute.
@ -860,11 +863,18 @@ void nsContentSink::PrefetchPreloadHref(const nsAString& aHref,
mDocument)) {
policyType = nsIContentPolicy::TYPE_INVALID;
}
}
prefetchService->PreloadURI(uri, mDocumentURI, aSource, policyType);
nsCOMPtr<nsIReferrerInfo> referrerInfo = new ReferrerInfo();
referrerInfo->InitWithDocument(mDocument);
referrerInfo = static_cast<ReferrerInfo*>(referrerInfo.get())
->CloneWithNewOriginalReferrer(mDocumentURI);
if (preload) {
prefetchService->PreloadURI(uri, referrerInfo, mDocument, policyType);
} else {
prefetchService->PrefetchURI(
uri, mDocumentURI, aSource,
uri, referrerInfo, mDocument,
aLinkTypes & nsStyleLinkElement::ePREFETCH);
}
}

View File

@ -165,9 +165,9 @@ class nsContentSink : public nsICSSLoaderObserver,
const nsAString& aMedia,
const nsAString& aReferrerPolicy);
void PrefetchPreloadHref(const nsAString& aHref, nsINode* aSource,
uint32_t aLinkTypes, const nsAString& aAs,
const nsAString& aType, const nsAString& aMedia);
void PrefetchPreloadHref(const nsAString& aHref, uint32_t aLinkTypes,
const nsAString& aAs, const nsAString& aType,
const nsAString& aMedia);
// For PrefetchDNS() aHref can either be the usual
// URI format or of the form "//www.hostname.com" without a scheme.

View File

@ -2,6 +2,13 @@
var prefetch = Cc["@mozilla.org/prefetch-service;1"].getService(
Ci.nsIPrefetchService
);
var ReferrerInfo = Components.Constructor(
"@mozilla.org/referrer-info;1",
"nsIReferrerInfo",
"init"
);
var ios = Services.io;
var prefs = Services.prefs;
@ -30,7 +37,13 @@ function run_test() {
add_test(function test_cancel1() {
var uri = ios.newURI("http://localhost/1");
prefetch.prefetchURI(uri, uri, node1, true);
var referrerInfo = new ReferrerInfo(
Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
true,
uri
);
prefetch.prefetchURI(uri, referrerInfo, node1, true);
Assert.ok(prefetch.hasMoreElements(), "There is a request in the queue");
@ -38,7 +51,7 @@ add_test(function test_cancel1() {
var didFail = 0;
try {
prefetch.prefetchURI(uri, uri, node1, true);
prefetch.prefetchURI(uri, referrerInfo, node1, true);
} catch (e) {
didFail = 1;
}
@ -61,8 +74,14 @@ add_test(function test_cancel2() {
// in the queue and canceling one will not cancel the other.
var uri = ios.newURI("http://localhost/1");
prefetch.prefetchURI(uri, uri, node1, true);
prefetch.prefetchURI(uri, uri, node2, true);
var referrerInfo = new ReferrerInfo(
Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
true,
uri
);
prefetch.prefetchURI(uri, referrerInfo, node1, true);
prefetch.prefetchURI(uri, referrerInfo, node2, true);
Assert.ok(prefetch.hasMoreElements(), "There are requests in the queue");
@ -83,7 +102,13 @@ add_test(function test_cancel3() {
// Request a prefetch of a uri. Trying to cancel a prefetch for the same uri
// with a different node will fail.
var uri = ios.newURI("http://localhost/1");
prefetch.prefetchURI(uri, uri, node1, true);
var referrerInfo = new ReferrerInfo(
Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
true,
uri
);
prefetch.prefetchURI(uri, referrerInfo, node1, true);
Assert.ok(prefetch.hasMoreElements(), "There is a request in the queue");
@ -111,7 +136,13 @@ add_test(function test_cancel4() {
// with the same node will fail.
var uri1 = ios.newURI("http://localhost/1");
var uri2 = ios.newURI("http://localhost/2");
prefetch.prefetchURI(uri1, uri1, node1, true);
var referrerInfo = new ReferrerInfo(
Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
true,
uri1
);
prefetch.prefetchURI(uri1, referrerInfo, node1, true);
Assert.ok(prefetch.hasMoreElements(), "There is a request in the queue");

View File

@ -927,9 +927,9 @@ void ReferrerInfo::GetReferrerPolicyFromAtribute(nsINode* aNode,
aPolicy = mozilla::net::RP_Unset;
mozilla::dom::Element* element = aNode->AsElement();
if (!element->IsAnyOfHTMLElements(nsGkAtoms::a, nsGkAtoms::area,
nsGkAtoms::script, nsGkAtoms::iframe,
nsGkAtoms::link, nsGkAtoms::img)) {
if (!element || !element->IsAnyOfHTMLElements(
nsGkAtoms::a, nsGkAtoms::area, nsGkAtoms::script,
nsGkAtoms::iframe, nsGkAtoms::link, nsGkAtoms::img)) {
return;
}
@ -940,7 +940,8 @@ bool ReferrerInfo::HasRelNoReferrer(nsINode* aNode) const {
mozilla::dom::Element* element = aNode->AsElement();
// rel=noreferrer is only support in <a> and <area>
if (!element->IsAnyOfHTMLElements(nsGkAtoms::a, nsGkAtoms::area)) {
if (!element ||
!element->IsAnyOfHTMLElements(nsGkAtoms::a, nsGkAtoms::area)) {
return false;
}

View File

@ -7,6 +7,7 @@
interface nsIURI;
interface nsISimpleEnumerator;
interface nsIReferrerInfo;
webidl Node;
@ -17,13 +18,13 @@ interface nsIPrefetchService : nsISupports
* Enqueue a request to prefetch the specified URI.
*
* @param aURI the URI of the document to prefetch
* @param aReferrerURI the URI of the referring page
* @param aReferrerInfo the referrerInfo of the request
* @param aSource the DOM node (such as a <link> tag) that requested this
* fetch, or null if the prefetch was not requested by a DOM node.
* @param aExplicit the link element has an explicit prefetch link type
*/
void prefetchURI(in nsIURI aURI,
in nsIURI aReferrerURI,
in nsIReferrerInfo aReferrerInfo,
in Node aSource,
in boolean aExplicit);
@ -31,13 +32,13 @@ interface nsIPrefetchService : nsISupports
* Start a preload of the specified URI.
*
* @param aURI the URI of the document to preload
* @param aReferrerURI the URI of the referring page
* @param aReferrerInfo the referrerInfo of the request
* @param aSource the DOM node (such as a <link> tag) that requested this
* fetch, or null if the prefetch was not requested by a DOM node.
* @param aPolicyType content policy to be used for this load.
*/
void preloadURI(in nsIURI aURI,
in nsIURI aReferrerURI,
in nsIReferrerInfo aReferrerInfo,
in Node aSource,
in nsContentPolicyType aPolicyType);

View File

@ -69,10 +69,10 @@ static LazyLogModule gPrefetchLog("nsPrefetch");
//-----------------------------------------------------------------------------
nsPrefetchNode::nsPrefetchNode(nsPrefetchService* aService, nsIURI* aURI,
nsIURI* aReferrerURI, nsINode* aSource,
nsIReferrerInfo* aReferrerInfo, nsINode* aSource,
nsContentPolicyType aPolicyType, bool aPreload)
: mURI(aURI),
mReferrerURI(aReferrerURI),
mReferrerInfo(aReferrerInfo),
mPolicyType(aPolicyType),
mPreload(aPreload),
mService(aService),
@ -105,14 +105,8 @@ nsresult nsPrefetchNode::OpenChannel() {
}
nsCOMPtr<nsILoadGroup> loadGroup = source->OwnerDoc()->GetDocumentLoadGroup();
CORSMode corsMode = CORS_NONE;
net::ReferrerPolicy referrerPolicy = net::RP_Unset;
if (auto* link = dom::HTMLLinkElement::FromNode(source)) {
corsMode = link->GetCORSMode();
referrerPolicy = link->GetReferrerPolicyAsEnum();
}
if (referrerPolicy == net::RP_Unset) {
referrerPolicy = source->OwnerDoc()->GetReferrerPolicy();
}
uint32_t securityFlags;
@ -139,13 +133,11 @@ nsresult nsPrefetchNode::OpenChannel() {
// configure HTTP specific stuff
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
if (httpChannel) {
nsCOMPtr<nsIReferrerInfo> referrerInfo =
new mozilla::dom::ReferrerInfo(mReferrerURI, referrerPolicy);
rv = httpChannel->SetReferrerInfoWithoutClone(referrerInfo);
MOZ_ASSERT(NS_SUCCEEDED(rv));
rv = httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("X-Moz"),
NS_LITERAL_CSTRING("prefetch"), false);
MOZ_ASSERT(NS_SUCCEEDED(rv));
DebugOnly<nsresult> success = httpChannel->SetReferrerInfo(mReferrerInfo);
MOZ_ASSERT(NS_SUCCEEDED(success));
success = httpChannel->SetRequestHeader(
NS_LITERAL_CSTRING("X-Moz"), NS_LITERAL_CSTRING("prefetch"), false);
MOZ_ASSERT(NS_SUCCEEDED(success));
}
// Reduce the priority of prefetch network requests.
@ -491,11 +483,12 @@ void nsPrefetchService::RemoveProgressListener() {
if (progress) progress->RemoveProgressListener(this);
}
nsresult nsPrefetchService::EnqueueURI(nsIURI* aURI, nsIURI* aReferrerURI,
nsresult nsPrefetchService::EnqueueURI(nsIURI* aURI,
nsIReferrerInfo* aReferrerInfo,
nsINode* aSource,
nsPrefetchNode** aNode) {
RefPtr<nsPrefetchNode> node = new nsPrefetchNode(
this, aURI, aReferrerURI, aSource, nsIContentPolicy::TYPE_OTHER, false);
this, aURI, aReferrerInfo, aSource, nsIContentPolicy::TYPE_OTHER, false);
mPrefetchQueue.push_back(node);
node.forget(aNode);
return NS_OK;
@ -564,7 +557,8 @@ void nsPrefetchService::StopAll() {
EmptyPrefetchQueue();
}
nsresult nsPrefetchService::CheckURIScheme(nsIURI* aURI, nsIURI* aReferrerURI) {
nsresult nsPrefetchService::CheckURIScheme(nsIURI* aURI,
nsIReferrerInfo* aReferrerInfo) {
//
// XXX we should really be asking the protocol handler if it supports
// caching, so we can determine if there is any value to prefetching.
@ -584,9 +578,14 @@ nsresult nsPrefetchService::CheckURIScheme(nsIURI* aURI, nsIURI* aReferrerURI) {
//
// the referrer URI must be http:
//
rv = aReferrerURI->SchemeIs("http", &match);
nsCOMPtr<nsIURI> referrer = aReferrerInfo->GetOriginalReferrer();
if (!referrer) {
return NS_ERROR_ABORT;
}
rv = referrer->SchemeIs("http", &match);
if (NS_FAILED(rv) || !match) {
rv = aReferrerURI->SchemeIs("https", &match);
rv = referrer->SchemeIs("https", &match);
if (NS_FAILED(rv) || !match) {
LOG(("rejected: referrer URL is neither http nor https\n"));
return NS_ERROR_ABORT;
@ -607,11 +606,12 @@ NS_IMPL_ISUPPORTS(nsPrefetchService, nsIPrefetchService, nsIWebProgressListener,
// nsPrefetchService::nsIPrefetchService
//-----------------------------------------------------------------------------
nsresult nsPrefetchService::Preload(nsIURI* aURI, nsIURI* aReferrerURI,
nsresult nsPrefetchService::Preload(nsIURI* aURI,
nsIReferrerInfo* aReferrerInfo,
nsINode* aSource,
nsContentPolicyType aPolicyType) {
NS_ENSURE_ARG_POINTER(aURI);
NS_ENSURE_ARG_POINTER(aReferrerURI);
NS_ENSURE_ARG_POINTER(aReferrerInfo);
if (LOG_ENABLED()) {
LOG(("PreloadURI [%s]\n", aURI->GetSpecOrDefault().get()));
}
@ -621,7 +621,7 @@ nsresult nsPrefetchService::Preload(nsIURI* aURI, nsIURI* aReferrerURI,
return NS_ERROR_ABORT;
}
nsresult rv = CheckURIScheme(aURI, aReferrerURI);
nsresult rv = CheckURIScheme(aURI, aReferrerInfo);
if (NS_FAILED(rv)) {
return rv;
}
@ -666,7 +666,7 @@ nsresult nsPrefetchService::Preload(nsIURI* aURI, nsIURI* aReferrerURI,
LOG(("This is a preload, so start loading immediately.\n"));
RefPtr<nsPrefetchNode> enqueuedNode;
enqueuedNode =
new nsPrefetchNode(this, aURI, aReferrerURI, aSource, aPolicyType, true);
new nsPrefetchNode(this, aURI, aReferrerInfo, aSource, aPolicyType, true);
NotifyLoadRequested(enqueuedNode);
rv = enqueuedNode->OpenChannel();
@ -683,10 +683,11 @@ nsresult nsPrefetchService::Preload(nsIURI* aURI, nsIURI* aReferrerURI,
return NS_OK;
}
nsresult nsPrefetchService::Prefetch(nsIURI* aURI, nsIURI* aReferrerURI,
nsresult nsPrefetchService::Prefetch(nsIURI* aURI,
nsIReferrerInfo* aReferrerInfo,
nsINode* aSource, bool aExplicit) {
NS_ENSURE_ARG_POINTER(aURI);
NS_ENSURE_ARG_POINTER(aReferrerURI);
NS_ENSURE_ARG_POINTER(aReferrerInfo);
if (LOG_ENABLED()) {
LOG(("PrefetchURI [%s]\n", aURI->GetSpecOrDefault().get()));
@ -697,7 +698,7 @@ nsresult nsPrefetchService::Prefetch(nsIURI* aURI, nsIURI* aReferrerURI,
return NS_ERROR_ABORT;
}
nsresult rv = CheckURIScheme(aURI, aReferrerURI);
nsresult rv = CheckURIScheme(aURI, aReferrerInfo);
if (NS_FAILED(rv)) {
return rv;
}
@ -765,7 +766,7 @@ nsresult nsPrefetchService::Prefetch(nsIURI* aURI, nsIURI* aReferrerURI,
}
RefPtr<nsPrefetchNode> enqueuedNode;
rv = EnqueueURI(aURI, aReferrerURI, aSource, getter_AddRefs(enqueuedNode));
rv = EnqueueURI(aURI, aReferrerInfo, aSource, getter_AddRefs(enqueuedNode));
NS_ENSURE_SUCCESS(rv, rv);
NotifyLoadRequested(enqueuedNode);
@ -839,16 +840,16 @@ nsPrefetchService::CancelPrefetchPreloadURI(nsIURI* aURI, nsINode* aSource) {
}
NS_IMETHODIMP
nsPrefetchService::PreloadURI(nsIURI* aURI, nsIURI* aReferrerURI,
nsPrefetchService::PreloadURI(nsIURI* aURI, nsIReferrerInfo* aReferrerInfo,
nsINode* aSource,
nsContentPolicyType aPolicyType) {
return Preload(aURI, aReferrerURI, aSource, aPolicyType);
return Preload(aURI, aReferrerInfo, aSource, aPolicyType);
}
NS_IMETHODIMP
nsPrefetchService::PrefetchURI(nsIURI* aURI, nsIURI* aReferrerURI,
nsPrefetchService::PrefetchURI(nsIURI* aURI, nsIReferrerInfo* aReferrerInfo,
nsINode* aSource, bool aExplicit) {
return Prefetch(aURI, aReferrerURI, aSource, aExplicit);
return Prefetch(aURI, aReferrerInfo, aSource, aExplicit);
}
NS_IMETHODIMP

View File

@ -22,6 +22,7 @@
class nsPrefetchService;
class nsPrefetchNode;
class nsIReferrerInfo;
//-----------------------------------------------------------------------------
// nsPrefetchService
@ -50,23 +51,23 @@ class nsPrefetchService final : public nsIPrefetchService,
private:
~nsPrefetchService();
nsresult Prefetch(nsIURI* aURI, nsIURI* aReferrerURI, nsINode* aSource,
bool aExplicit);
nsresult Prefetch(nsIURI* aURI, nsIReferrerInfo* aReferrerInfo,
nsINode* aSource, bool aExplicit);
nsresult Preload(nsIURI* aURI, nsIURI* aReferrerURI, nsINode* aSource,
nsContentPolicyType aPolicyType);
nsresult Preload(nsIURI* aURI, nsIReferrerInfo* aReferrerInfo,
nsINode* aSource, nsContentPolicyType aPolicyType);
void AddProgressListener();
void RemoveProgressListener();
nsresult EnqueueURI(nsIURI* aURI, nsIURI* aReferrerURI, nsINode* aSource,
nsPrefetchNode** node);
nsresult EnqueueURI(nsIURI* aURI, nsIReferrerInfo* aReferrerInfo,
nsINode* aSource, nsPrefetchNode** node);
void EmptyPrefetchQueue();
void StartPrefetching();
void StopPrefetching();
void StopCurrentPrefetchsPreloads(bool aPreload);
void StopAll();
nsresult CheckURIScheme(nsIURI* aURI, nsIURI* aReferrerURI);
nsresult CheckURIScheme(nsIURI* aURI, nsIReferrerInfo* aReferrerInfo);
std::deque<RefPtr<nsPrefetchNode>> mPrefetchQueue;
nsTArray<RefPtr<nsPrefetchNode>> mCurrentNodes;
@ -100,14 +101,14 @@ class nsPrefetchNode final : public nsIStreamListener,
NS_DECL_NSIREDIRECTRESULTLISTENER
nsPrefetchNode(nsPrefetchService* aPrefetchService, nsIURI* aURI,
nsIURI* aReferrerURI, nsINode* aSource,
nsIReferrerInfo* aReferrerInfo, nsINode* aSource,
nsContentPolicyType aPolicyType, bool aPreload);
nsresult OpenChannel();
nsresult CancelChannel(nsresult error);
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIURI> mReferrerURI;
nsCOMPtr<nsIReferrerInfo> mReferrerInfo;
nsTArray<nsWeakPtr> mSources;
// The policy type to be used for fetching the resource.