ported from mozilla: Bug 1460920 - Part 1 - Speculative loading script should take referrerpolicy attribute in script element into account r=hsivonen (045f98957a)

This commit is contained in:
roytam1 2024-10-01 11:43:05 +08:00
commit 281e3f4d1b
5 changed files with 67 additions and 29 deletions

View file

@ -55,25 +55,25 @@ nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor)
case eSpeculativeLoadScript: case eSpeculativeLoadScript:
aExecutor->PreloadScript(mUrlOrSizes, mCharsetOrSrcset, aExecutor->PreloadScript(mUrlOrSizes, mCharsetOrSrcset,
mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity, mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity,
mCrossOriginOrMedia, mReferrerPolicyOrIntegrity, false, mCrossOriginOrMedia, mReferrerPolicyOrIntegrity, mScriptReferrerPolicy, false,
mIsAsync, mIsDefer, false); mIsAsync, mIsDefer, false);
break; break;
case eSpeculativeLoadScriptFromHead: case eSpeculativeLoadScriptFromHead:
aExecutor->PreloadScript(mUrlOrSizes, mCharsetOrSrcset, aExecutor->PreloadScript(mUrlOrSizes, mCharsetOrSrcset,
mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity, mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity,
mCrossOriginOrMedia, mReferrerPolicyOrIntegrity, true, mCrossOriginOrMedia, mReferrerPolicyOrIntegrity, mScriptReferrerPolicy, true,
mIsAsync, mIsDefer, false); mIsAsync, mIsDefer, false);
break; break;
case eSpeculativeLoadNoModuleScript: case eSpeculativeLoadNoModuleScript:
aExecutor->PreloadScript(mUrlOrSizes, mCharsetOrSrcset, aExecutor->PreloadScript(mUrlOrSizes, mCharsetOrSrcset,
mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity, mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity,
mCrossOriginOrMedia, mReferrerPolicyOrIntegrity, false, mCrossOriginOrMedia, mReferrerPolicyOrIntegrity, mScriptReferrerPolicy, false,
mIsAsync, mIsDefer, true); mIsAsync, mIsDefer, true);
break; break;
case eSpeculativeLoadNoModuleScriptFromHead: case eSpeculativeLoadNoModuleScriptFromHead:
aExecutor->PreloadScript(mUrlOrSizes, mCharsetOrSrcset, aExecutor->PreloadScript(mUrlOrSizes, mCharsetOrSrcset,
mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity, mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity,
mCrossOriginOrMedia, mReferrerPolicyOrIntegrity, true, mCrossOriginOrMedia, mReferrerPolicyOrIntegrity, mScriptReferrerPolicy, true,
mIsAsync, mIsDefer, true); mIsAsync, mIsDefer, true);
break; break;
case eSpeculativeLoadStyle: case eSpeculativeLoadStyle:

View file

@ -7,6 +7,7 @@
#include "nsString.h" #include "nsString.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "mozilla/net/ReferrerPolicy.h"
class nsHtml5TreeOpExecutor; class nsHtml5TreeOpExecutor;
@ -131,6 +132,7 @@ class nsHtml5SpeculativeLoad {
nsHtml5String aType, nsHtml5String aType,
nsHtml5String aCrossOrigin, nsHtml5String aCrossOrigin,
nsHtml5String aIntegrity, nsHtml5String aIntegrity,
nsHtml5String aReferrerPolicy,
bool aParserInHead, bool aParserInHead,
bool aAsync, bool aAsync,
bool aDefer, bool aDefer,
@ -150,6 +152,14 @@ class nsHtml5SpeculativeLoad {
aType.ToString(mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity); aType.ToString(mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity);
aCrossOrigin.ToString(mCrossOriginOrMedia); aCrossOrigin.ToString(mCrossOriginOrMedia);
aIntegrity.ToString(mReferrerPolicyOrIntegrity); aIntegrity.ToString(mReferrerPolicyOrIntegrity);
nsAutoString referrerPolicy;
aReferrerPolicy.ToString(referrerPolicy);
referrerPolicy =
nsContentUtils::TrimWhitespace<
nsContentUtils::IsHTMLWhitespace>(referrerPolicy);
mScriptReferrerPolicy =
mozilla::net::AttributeReferrerPolicyFromString(referrerPolicy);
mIsAsync = aAsync; mIsAsync = aAsync;
mIsDefer = aDefer; mIsDefer = aDefer;
} }
@ -166,7 +176,12 @@ class nsHtml5SpeculativeLoad {
aUrl.ToString(mUrlOrSizes); aUrl.ToString(mUrlOrSizes);
aCharset.ToString(mCharsetOrSrcset); aCharset.ToString(mCharsetOrSrcset);
aCrossOrigin.ToString(mCrossOriginOrMedia); aCrossOrigin.ToString(mCrossOriginOrMedia);
aReferrerPolicy.ToString(mReferrerPolicyOrIntegrity); nsString
referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
aReferrerPolicy.ToString(referrerPolicy);
mReferrerPolicyOrIntegrity.Assign(
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
referrerPolicy));
aIntegrity.ToString(mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity); aIntegrity.ToString(mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity);
} }
@ -287,6 +302,12 @@ class nsHtml5SpeculativeLoad {
* "media" attribute. If the attribute is not set, this will be a void string. * "media" attribute. If the attribute is not set, this will be a void string.
*/ */
nsString mCrossOriginOrMedia; nsString mCrossOriginOrMedia;
/**
* If mOpCode is eSpeculativeLoadScript[FromHead] this represents the value
* of the "referrerpolicy" attribute. This field holds one of the values
* (REFERRER_POLICY_*) defined in nsIHttpChannel.
*/
mozilla::net::ReferrerPolicy mScriptReferrerPolicy;
}; };
#endif // nsHtml5SpeculativeLoad_h #endif // nsHtml5SpeculativeLoad_h

View file

@ -184,6 +184,8 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace,
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN); aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsHtml5String integrity = nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY); aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
nsHtml5String referrerPolicy =
aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRERPOLICY);
bool async = bool async =
aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC); aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC);
bool defer = bool defer =
@ -196,6 +198,7 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace,
type, type,
crossOrigin, crossOrigin,
integrity, integrity,
referrerPolicy,
mode == nsHtml5TreeBuilder::IN_HEAD, mode == nsHtml5TreeBuilder::IN_HEAD,
async, async,
defer, defer,
@ -247,12 +250,15 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace,
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN); aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsHtml5String integrity = nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY); aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
nsHtml5String referrerPolicy =
aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRERPOLICY);
mSpeculativeLoadQueue.AppendElement()->InitScript( mSpeculativeLoadQueue.AppendElement()->InitScript(
url, url,
charset, charset,
type, type,
crossOrigin, crossOrigin,
integrity, integrity,
referrerPolicy,
mode == nsHtml5TreeBuilder::IN_HEAD, mode == nsHtml5TreeBuilder::IN_HEAD,
false, false,
false, false,
@ -349,12 +355,15 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace,
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN); aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsHtml5String integrity = nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY); aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
nsHtml5String referrerPolicy =
aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRERPOLICY);
mSpeculativeLoadQueue.AppendElement()->InitScript( mSpeculativeLoadQueue.AppendElement()->InitScript(
url, url,
nullptr, nullptr,
type, type,
crossOrigin, crossOrigin,
integrity, integrity,
referrerPolicy,
mode == nsHtml5TreeBuilder::IN_HEAD, mode == nsHtml5TreeBuilder::IN_HEAD,
false /* async */, false /* async */,
false /* defer */, false /* defer */,

View file

@ -914,12 +914,23 @@ nsHtml5TreeOpExecutor::ShouldPreloadURI(nsIURI *aURI)
return true; return true;
} }
net::ReferrerPolicy
nsHtml5TreeOpExecutor::GetPreloadReferrerPolicy(
const nsAString& aReferrerPolicy)
{
net::ReferrerPolicy referrerPolicy =
net::AttributeReferrerPolicyFromString(aReferrerPolicy);
return referrerPolicy != net::RP_Unset ? referrerPolicy :
mSpeculationReferrerPolicy;
}
void void
nsHtml5TreeOpExecutor::PreloadScript(const nsAString& aURL, nsHtml5TreeOpExecutor::PreloadScript(const nsAString& aURL,
const nsAString& aCharset, const nsAString& aCharset,
const nsAString& aType, const nsAString& aType,
const nsAString& aCrossOrigin, const nsAString& aCrossOrigin,
const nsAString& aIntegrity, const nsAString& aIntegrity,
net::ReferrerPolicy aReferrerPolicy,
bool aScriptFromHead, bool aScriptFromHead,
bool aAsync, bool aAsync,
bool aDefer, bool aDefer,
@ -929,10 +940,19 @@ nsHtml5TreeOpExecutor::PreloadScript(const nsAString& aURL,
if (!uri) { if (!uri) {
return; return;
} }
mDocument->ScriptLoader()->PreloadURI(uri, aCharset, aType, aCrossOrigin, net::ReferrerPolicy referrerPolicy = aReferrerPolicy != net::RP_Unset ?
aIntegrity, aScriptFromHead, aAsync, aReferrerPolicy : mSpeculationReferrerPolicy;
aDefer, aNoModule, mDocument->ScriptLoader()
mSpeculationReferrerPolicy); ->PreloadURI(uri,
aCharset,
aType,
aCrossOrigin,
aIntegrity,
aScriptFromHead,
aAsync,
aDefer,
aNoModule,
referrerPolicy);
} }
void void
@ -947,14 +967,7 @@ nsHtml5TreeOpExecutor::PreloadStyle(const nsAString& aURL,
return; return;
} }
mozilla::net::ReferrerPolicy referrerPolicy = mSpeculationReferrerPolicy; mDocument->PreloadStyle(uri, aCharset, aCrossOrigin, GetPreloadReferrerPolicy(aReferrerPolicy),
mozilla::net::ReferrerPolicy styleReferrerPolicy =
mozilla::net::AttributeReferrerPolicyFromString(aReferrerPolicy);
if (styleReferrerPolicy != mozilla::net::RP_Unset) {
referrerPolicy = styleReferrerPolicy;
}
mDocument->PreloadStyle(uri, aCharset, aCrossOrigin, referrerPolicy,
aIntegrity); aIntegrity);
} }
@ -971,18 +984,10 @@ nsHtml5TreeOpExecutor::PreloadImage(const nsAString& aURL,
aSizes, &isImgSet); aSizes, &isImgSet);
if (uri && ShouldPreloadURI(uri)) { if (uri && ShouldPreloadURI(uri)) {
// use document wide referrer policy // use document wide referrer policy
mozilla::net::ReferrerPolicy referrerPolicy = mSpeculationReferrerPolicy; mDocument->MaybePreLoadImage(uri,
// if enabled in preferences, use the referrer attribute from the image, if provided aCrossOrigin,
bool referrerAttributeEnabled = Preferences::GetBool("network.http.enablePerElementReferrer", true); GetPreloadReferrerPolicy(aImageReferrerPolicy),
if (referrerAttributeEnabled) { isImgSet);
mozilla::net::ReferrerPolicy imageReferrerPolicy =
mozilla::net::AttributeReferrerPolicyFromString(aImageReferrerPolicy);
if (imageReferrerPolicy != mozilla::net::RP_Unset) {
referrerPolicy = imageReferrerPolicy;
}
}
mDocument->MaybePreLoadImage(uri, aCrossOrigin, referrerPolicy, isImgSet);
} }
} }

View file

@ -249,6 +249,7 @@ class nsHtml5TreeOpExecutor final : public nsHtml5DocumentBuilder,
const nsAString& aType, const nsAString& aType,
const nsAString& aCrossOrigin, const nsAString& aCrossOrigin,
const nsAString& aIntegrity, const nsAString& aIntegrity,
ReferrerPolicy aReferrerPolicy,
bool aScriptFromHead, bool aScriptFromHead,
bool aAsync, bool aAsync,
bool aDefer, bool aDefer,
@ -305,6 +306,8 @@ class nsHtml5TreeOpExecutor final : public nsHtml5DocumentBuilder,
* list of preloaded URIs * list of preloaded URIs
*/ */
bool ShouldPreloadURI(nsIURI *aURI); bool ShouldPreloadURI(nsIURI *aURI);
ReferrerPolicy GetPreloadReferrerPolicy(const nsAString& aReferrerPolicy);
}; };
#endif // nsHtml5TreeOpExecutor_h #endif // nsHtml5TreeOpExecutor_h