зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1166910 - Referrer attribute for img tag. r=ckerschb, r=hsivonen, r=bz
--HG-- extra : rebase_source : ceb3a3d18acf7deb9d13cfae499b7e112db8ffce
This commit is contained in:
Родитель
8e360c243e
Коммит
2ae91f6891
|
@ -46,6 +46,7 @@
|
|||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#ifdef LoadImage
|
||||
// Undefine LoadImage to prevent naming conflict with Windows.
|
||||
|
@ -930,15 +931,27 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
|||
loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS;
|
||||
}
|
||||
|
||||
// get document wide referrer policy
|
||||
mozilla::net::ReferrerPolicy referrerPolicy = aDocument->GetReferrerPolicy();
|
||||
bool referrerAttributeEnabled = Preferences::GetBool("network.http.enablePerElementReferrer", false);
|
||||
// if referrer attributes are enabled in preferences, load img referrer attribute
|
||||
nsresult rv;
|
||||
if (referrerAttributeEnabled) {
|
||||
mozilla::net::ReferrerPolicy imgReferrerPolicy = GetImageReferrerPolicy();
|
||||
// if the image does not provide a referrer attribute, ignore this
|
||||
if (imgReferrerPolicy != mozilla::net::RP_Unset) {
|
||||
referrerPolicy = imgReferrerPolicy;
|
||||
}
|
||||
}
|
||||
|
||||
// Not blocked. Do the load.
|
||||
nsRefPtr<imgRequestProxy>& req = PrepareNextRequest(aImageLoadType);
|
||||
nsCOMPtr<nsIContent> content =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
nsresult rv;
|
||||
rv = nsContentUtils::LoadImage(aNewURI, aDocument,
|
||||
aDocument->NodePrincipal(),
|
||||
aDocument->GetDocumentURI(),
|
||||
aDocument->GetReferrerPolicy(),
|
||||
referrerPolicy,
|
||||
this, loadFlags,
|
||||
content->LocalName(),
|
||||
getter_AddRefs(req),
|
||||
|
@ -1566,3 +1579,11 @@ nsImageLoadingContent::ImageObserver::~ImageObserver()
|
|||
MOZ_COUNT_DTOR(ImageObserver);
|
||||
NS_CONTENT_DELETE_LIST_MEMBER(ImageObserver, this, mNext);
|
||||
}
|
||||
|
||||
// Only HTMLInputElement.h overrides this for <img> tags
|
||||
// all other subclasses use this one, i.e. ignore referrer attributes
|
||||
mozilla::net::ReferrerPolicy
|
||||
nsImageLoadingContent::GetImageReferrerPolicy()
|
||||
{
|
||||
return mozilla::net::RP_Unset;
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "nsAutoPtr.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIDocument;
|
||||
|
@ -198,6 +199,8 @@ protected:
|
|||
*/
|
||||
virtual mozilla::CORSMode GetCORSMode();
|
||||
|
||||
virtual mozilla::net::ReferrerPolicy GetImageReferrerPolicy();
|
||||
|
||||
// Subclasses are *required* to call BindToTree/UnbindFromTree.
|
||||
void BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent, bool aCompileEventHandlers);
|
||||
|
|
|
@ -189,6 +189,20 @@ public:
|
|||
{
|
||||
SetHTMLAttr(nsGkAtoms::border, aBorder, aError);
|
||||
}
|
||||
void SetReferrer(const nsAString& aReferrer, ErrorResult& aError)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::referrer, aReferrer, aError);
|
||||
}
|
||||
void GetReferrer(nsAString& aReferrer)
|
||||
{
|
||||
GetEnumAttr(nsGkAtoms::referrer, nullptr, aReferrer);
|
||||
}
|
||||
|
||||
mozilla::net::ReferrerPolicy
|
||||
GetImageReferrerPolicy()
|
||||
{
|
||||
return GetReferrerPolicy();
|
||||
}
|
||||
|
||||
int32_t X();
|
||||
int32_t Y();
|
||||
|
|
|
@ -106,6 +106,8 @@
|
|||
#include "mozilla/dom/HTMLBodyElement.h"
|
||||
#include "imgIContainer.h"
|
||||
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
|
@ -995,6 +997,10 @@ nsGenericHTMLElement::ParseAttribute(int32_t aNamespaceID,
|
|||
return aResult.ParseIntValue(aValue);
|
||||
}
|
||||
|
||||
if (aAttribute == nsGkAtoms::referrer) {
|
||||
return ParseReferrerAttribute(aValue, aResult);
|
||||
}
|
||||
|
||||
if (aAttribute == nsGkAtoms::name) {
|
||||
// Store name as an atom. name="" means that the element has no name,
|
||||
// not that it has an emptystring as the name.
|
||||
|
@ -1262,6 +1268,19 @@ nsGenericHTMLElement::ParseImageAttribute(nsIAtom* aAttribute,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsGenericHTMLElement::ParseReferrerAttribute(const nsAString& aString,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
static const nsAttrValue::EnumTable kReferrerTable[] = {
|
||||
{ "no-referrer", net::RP_No_Referrer },
|
||||
{ "origin", net::RP_Origin },
|
||||
{ "unsafe-url", net::RP_Unsafe_URL },
|
||||
{ 0 }
|
||||
};
|
||||
return aResult.ParseEnumValue(aString, kReferrerTable, false);
|
||||
}
|
||||
|
||||
bool
|
||||
nsGenericHTMLElement::ParseFrameborderValue(const nsAString& aString,
|
||||
nsAttrValue& aResult)
|
||||
|
|
|
@ -233,6 +233,17 @@ public:
|
|||
mScrollgrab = aValue;
|
||||
}
|
||||
|
||||
mozilla::net::ReferrerPolicy
|
||||
GetReferrerPolicy()
|
||||
{
|
||||
nsAutoString aPolicyString;
|
||||
GetEnumAttr(nsGkAtoms::referrer, nullptr, aPolicyString);
|
||||
if (aPolicyString.IsEmpty()) {
|
||||
return mozilla::net::RP_Unset;
|
||||
}
|
||||
return mozilla::net::ReferrerPolicyFromString(aPolicyString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether an attribute is an event (onclick, etc.)
|
||||
* @param aName the attribute
|
||||
|
@ -711,6 +722,10 @@ public:
|
|||
static bool ParseImageAttribute(nsIAtom* aAttribute,
|
||||
const nsAString& aString,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
static bool ParseReferrerAttribute(const nsAString& aString,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
/**
|
||||
* Convert a frameborder string to value (yes/no/1/0)
|
||||
*
|
||||
|
|
|
@ -30,6 +30,8 @@ interface HTMLImageElement : HTMLElement {
|
|||
[SetterThrows]
|
||||
attribute DOMString useMap;
|
||||
[SetterThrows]
|
||||
attribute DOMString referrer;
|
||||
[SetterThrows]
|
||||
attribute boolean isMap;
|
||||
[SetterThrows]
|
||||
attribute unsigned long width;
|
||||
|
|
|
@ -670,6 +670,9 @@ ValidateSecurityInfo(imgRequest* request, bool forcePrincipalCheck,
|
|||
nsISupports* aCX, ReferrerPolicy referrerPolicy)
|
||||
{
|
||||
// If the entry's Referrer Policy doesn't match, we can't use this request.
|
||||
// XXX: this will return false if an image has different referrer attributes,
|
||||
// i.e. we currently don't use the cached image but reload the image with
|
||||
// the new referrer policy bug 1174921
|
||||
if (referrerPolicy != request->GetReferrerPolicy()) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1274,6 +1274,9 @@ pref("network.http.referer.XOriginPolicy", 0);
|
|||
// By default this is enabled for compatibility (see bug 141641)
|
||||
pref("network.http.sendSecureXSiteReferrer", true);
|
||||
|
||||
// Controls whether referrer attributes in <a>, <img>, <area>, and <iframe> are honoured
|
||||
pref("network.http.enablePerElementReferrer", false);
|
||||
|
||||
// Maximum number of consecutive redirects before aborting.
|
||||
pref("network.http.redirection-limit", 20);
|
||||
|
||||
|
|
|
@ -25,7 +25,10 @@ enum ReferrerPolicy {
|
|||
RP_Origin_When_Crossorigin = nsIHttpChannel::REFERRER_POLICY_ORIGIN_WHEN_XORIGIN,
|
||||
|
||||
/* spec tokens: always unsafe-url */
|
||||
RP_Unsafe_URL = nsIHttpChannel::REFERRER_POLICY_UNSAFE_URL
|
||||
RP_Unsafe_URL = nsIHttpChannel::REFERRER_POLICY_UNSAFE_URL,
|
||||
|
||||
/* referrer policy is not set */
|
||||
RP_Unset = nsIHttpChannel::REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE
|
||||
};
|
||||
|
||||
inline ReferrerPolicy
|
||||
|
|
|
@ -28,10 +28,10 @@ nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor)
|
|||
aExecutor->SetSpeculationBase(mUrl);
|
||||
break;
|
||||
case eSpeculativeLoadMetaReferrer:
|
||||
aExecutor->SetSpeculationReferrerPolicy(mMetaReferrerPolicy);
|
||||
aExecutor->SetSpeculationReferrerPolicy(mReferrerPolicy);
|
||||
break;
|
||||
case eSpeculativeLoadImage:
|
||||
aExecutor->PreloadImage(mUrl, mCrossOrigin, mSrcset, mSizes);
|
||||
aExecutor->PreloadImage(mUrl, mCrossOrigin, mSrcset, mSizes, mReferrerPolicy);
|
||||
break;
|
||||
case eSpeculativeLoadOpenPicture:
|
||||
aExecutor->PreloadOpenPicture();
|
||||
|
|
|
@ -45,12 +45,13 @@ class nsHtml5SpeculativeLoad {
|
|||
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
|
||||
"Trying to reinitialize a speculative load!");
|
||||
mOpCode = eSpeculativeLoadMetaReferrer;
|
||||
mMetaReferrerPolicy.Assign(
|
||||
mReferrerPolicy.Assign(
|
||||
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aReferrerPolicy));
|
||||
}
|
||||
|
||||
inline void InitImage(const nsAString& aUrl,
|
||||
const nsAString& aCrossOrigin,
|
||||
const nsAString& aReferrerPolicy,
|
||||
const nsAString& aSrcset,
|
||||
const nsAString& aSizes)
|
||||
{
|
||||
|
@ -59,6 +60,8 @@ class nsHtml5SpeculativeLoad {
|
|||
mOpCode = eSpeculativeLoadImage;
|
||||
mUrl.Assign(aUrl);
|
||||
mCrossOrigin.Assign(aCrossOrigin);
|
||||
mReferrerPolicy.Assign(
|
||||
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aReferrerPolicy));
|
||||
mSrcset.Assign(aSrcset);
|
||||
mSizes.Assign(aSizes);
|
||||
}
|
||||
|
@ -179,7 +182,7 @@ class nsHtml5SpeculativeLoad {
|
|||
private:
|
||||
eHtml5SpeculativeLoad mOpCode;
|
||||
nsString mUrl;
|
||||
nsString mMetaReferrerPolicy;
|
||||
nsString mReferrerPolicy;
|
||||
/**
|
||||
* If mOpCode is eSpeculativeLoadStyle or eSpeculativeLoadScript[FromHead]
|
||||
* then this is the value of the "charset" attribute. For
|
||||
|
|
|
@ -125,11 +125,14 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
|
|||
aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET);
|
||||
nsString* crossOrigin =
|
||||
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
|
||||
nsString* referrerPolicy =
|
||||
aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRER);
|
||||
nsString* sizes =
|
||||
aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
|
||||
mSpeculativeLoadQueue.AppendElement()->
|
||||
InitImage(url ? *url : NullString(),
|
||||
crossOrigin ? *crossOrigin : NullString(),
|
||||
referrerPolicy ? *referrerPolicy : NullString(),
|
||||
srcset ? *srcset : NullString(),
|
||||
sizes ? *sizes : NullString());
|
||||
} else if (nsHtml5Atoms::source == aName) {
|
||||
|
@ -202,6 +205,7 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
|
|||
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER);
|
||||
if (url) {
|
||||
mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString(),
|
||||
NullString(),
|
||||
NullString(),
|
||||
NullString());
|
||||
}
|
||||
|
@ -238,6 +242,7 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
|
|||
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
|
||||
if (url) {
|
||||
mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString(),
|
||||
NullString(),
|
||||
NullString(),
|
||||
NullString());
|
||||
}
|
||||
|
|
|
@ -943,13 +943,25 @@ void
|
|||
nsHtml5TreeOpExecutor::PreloadImage(const nsAString& aURL,
|
||||
const nsAString& aCrossOrigin,
|
||||
const nsAString& aSrcset,
|
||||
const nsAString& aSizes)
|
||||
const nsAString& aSizes,
|
||||
const nsAString& aImageReferrerPolicy)
|
||||
{
|
||||
nsCOMPtr<nsIURI> baseURI = BaseURIForPreload();
|
||||
nsCOMPtr<nsIURI> uri = mDocument->ResolvePreloadImage(baseURI, aURL, aSrcset,
|
||||
aSizes);
|
||||
if (uri && ShouldPreloadURI(uri)) {
|
||||
mDocument->MaybePreLoadImage(uri, aCrossOrigin, mSpeculationReferrerPolicy);
|
||||
// use document wide referrer policy
|
||||
mozilla::net::ReferrerPolicy referrerPolicy = mSpeculationReferrerPolicy;
|
||||
// if enabled in preferences, use the referrer attribute from the image, if provided
|
||||
bool referrerAttributeEnabled = Preferences::GetBool("network.http.enablePerElementReferrer", false);
|
||||
if (referrerAttributeEnabled) {
|
||||
mozilla::net::ReferrerPolicy imageReferrerPolicy = mozilla::net::ReferrerPolicyFromString(aImageReferrerPolicy);
|
||||
if (imageReferrerPolicy != mozilla::net::RP_Unset) {
|
||||
referrerPolicy = imageReferrerPolicy;
|
||||
}
|
||||
}
|
||||
|
||||
mDocument->MaybePreLoadImage(uri, aCrossOrigin, referrerPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -256,7 +256,8 @@ class nsHtml5TreeOpExecutor final : public nsHtml5DocumentBuilder,
|
|||
void PreloadImage(const nsAString& aURL,
|
||||
const nsAString& aCrossOrigin,
|
||||
const nsAString& aSrcset,
|
||||
const nsAString& aSizes);
|
||||
const nsAString& aSizes,
|
||||
const nsAString& aImageReferrerPolicy);
|
||||
|
||||
void PreloadOpenPicture();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче