Bug 1771867 - Early Hints Phase 2 - Part 5: Pass early hint preload to script preloader r=necko-reviewers,valentin

Note that modules can't be specified in Link preloads with `rel=preload`,
only in `rel=modulepreload`.  We currently only support `rel=preload` in
early hints. See Bug 1798319 for updates on module preloads.

Differential Revision: https://phabricator.services.mozilla.com/D161175
This commit is contained in:
Manuel Bucher
2022-12-02 16:15:54 +00:00
parent 3fc1d3328e
commit d8da0082f1
5 changed files with 48 additions and 17 deletions

View File

@@ -107,7 +107,8 @@ nsresult ModuleLoader::StartFetch(ModuleLoadRequest* aRequest) {
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME; securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
// Delegate Shared Behavior to base ScriptLoader // Delegate Shared Behavior to base ScriptLoader
nsresult rv = GetScriptLoader()->StartLoadInternal(aRequest, securityFlags); nsresult rv =
GetScriptLoader()->StartLoadInternal(aRequest, securityFlags, 0);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-an-import()-module-script-graph // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-an-import()-module-script-graph

View File

@@ -9,6 +9,7 @@
#include "ScriptTrace.h" #include "ScriptTrace.h"
#include "ModuleLoader.h" #include "ModuleLoader.h"
#include "nsIChildChannel.h"
#include "zlib.h" #include "zlib.h"
#include "prsystem.h" #include "prsystem.h"
@@ -519,7 +520,7 @@ nsresult ScriptLoader::RestartLoad(ScriptLoadRequest* aRequest) {
if (aRequest->IsModuleRequest()) { if (aRequest->IsModuleRequest()) {
rv = aRequest->AsModuleRequest()->RestartModuleLoad(); rv = aRequest->AsModuleRequest()->RestartModuleLoad();
} else { } else {
rv = StartLoad(aRequest); rv = StartLoad(aRequest, 0);
} }
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
@@ -530,15 +531,17 @@ nsresult ScriptLoader::RestartLoad(ScriptLoadRequest* aRequest) {
return NS_BINDING_RETARGETED; return NS_BINDING_RETARGETED;
} }
nsresult ScriptLoader::StartLoad(ScriptLoadRequest* aRequest) { nsresult ScriptLoader::StartLoad(ScriptLoadRequest* aRequest,
uint64_t aEarlyHintPreloaderId) {
if (aRequest->IsModuleRequest()) { if (aRequest->IsModuleRequest()) {
return aRequest->AsModuleRequest()->StartModuleLoad(); return aRequest->AsModuleRequest()->StartModuleLoad();
} }
return StartClassicLoad(aRequest); return StartClassicLoad(aRequest, aEarlyHintPreloaderId);
} }
nsresult ScriptLoader::StartClassicLoad(ScriptLoadRequest* aRequest) { nsresult ScriptLoader::StartClassicLoad(ScriptLoadRequest* aRequest,
uint64_t aEarlyHintPreloaderId) {
MOZ_ASSERT(aRequest->IsFetching()); MOZ_ASSERT(aRequest->IsFetching());
NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER);
aRequest->SetUnknownDataType(); aRequest->SetUnknownDataType();
@@ -562,7 +565,8 @@ nsresult ScriptLoader::StartClassicLoad(ScriptLoadRequest* aRequest) {
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME; securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
nsresult rv = StartLoadInternal(aRequest, securityFlags); nsresult rv =
StartLoadInternal(aRequest, securityFlags, aEarlyHintPreloaderId);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@@ -580,7 +584,8 @@ static bool IsWebExtensionRequest(ScriptLoadRequest* aRequest) {
} }
nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest, nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
nsSecurityFlags securityFlags) { nsSecurityFlags securityFlags,
uint64_t aEarlyHintPreloaderId) {
nsContentPolicyType contentPolicyType = nsContentPolicyType contentPolicyType =
ScriptLoadRequestToContentPolicyType(aRequest); ScriptLoadRequestToContentPolicyType(aRequest);
nsCOMPtr<nsINode> context; nsCOMPtr<nsINode> context;
@@ -606,6 +611,15 @@ nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (aEarlyHintPreloaderId) {
nsCOMPtr<nsIHttpChannelInternal> channelInternal =
do_QueryInterface(channel);
NS_ENSURE_TRUE(channelInternal != nullptr, NS_ERROR_FAILURE);
rv = channelInternal->SetEarlyHintPreloaderId(aEarlyHintPreloaderId);
NS_ENSURE_SUCCESS(rv, rv);
}
// snapshot the nonce at load start time for performing CSP checks // snapshot the nonce at load start time for performing CSP checks
if (contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT || if (contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT ||
contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_MODULE) { contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_MODULE) {
@@ -727,7 +741,9 @@ nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
// Set the initiator type // Set the initiator type
nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(httpChannel)); nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(httpChannel));
if (timedChannel) { if (timedChannel) {
if (aRequest->GetScriptLoadContext()->IsLinkPreloadScript()) { if (aEarlyHintPreloaderId) {
timedChannel->SetInitiatorType(u"early-hints"_ns);
} else if (aRequest->GetScriptLoadContext()->IsLinkPreloadScript()) {
timedChannel->SetInitiatorType(u"link"_ns); timedChannel->SetInitiatorType(u"link"_ns);
} else { } else {
timedChannel->SetInitiatorType(u"script"_ns); timedChannel->SetInitiatorType(u"script"_ns);
@@ -757,6 +773,14 @@ nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
key, channel, mDocument, key, channel, mDocument,
aRequest->GetScriptLoadContext()->IsLinkPreloadScript()); aRequest->GetScriptLoadContext()->IsLinkPreloadScript());
if (aEarlyHintPreloaderId) {
nsCOMPtr<nsIHttpChannelInternal> channelInternal =
do_QueryInterface(channel);
NS_ENSURE_TRUE(channelInternal != nullptr, NS_ERROR_FAILURE);
rv = channelInternal->SetEarlyHintPreloaderId(aEarlyHintPreloaderId);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = channel->AsyncOpen(loader); rv = channel->AsyncOpen(loader);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
@@ -1002,7 +1026,7 @@ bool ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
LOG(("ScriptLoadRequest (%p): Created request for external script", LOG(("ScriptLoadRequest (%p): Created request for external script",
request.get())); request.get()));
nsresult rv = StartLoad(request); nsresult rv = StartLoad(request, 0);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
ReportErrorToConsole(request, rv); ReportErrorToConsole(request, rv);
@@ -3536,7 +3560,8 @@ void ScriptLoader::PreloadURI(nsIURI* aURI, const nsAString& aCharset,
const nsAString& aIntegrity, bool aScriptFromHead, const nsAString& aIntegrity, bool aScriptFromHead,
bool aAsync, bool aDefer, bool aNoModule, bool aAsync, bool aDefer, bool aNoModule,
bool aLinkPreload, bool aLinkPreload,
const ReferrerPolicy aReferrerPolicy) { const ReferrerPolicy aReferrerPolicy,
uint64_t aEarlyHintPreloaderId) {
NS_ENSURE_TRUE_VOID(mDocument); NS_ENSURE_TRUE_VOID(mDocument);
// Check to see if scripts has been turned off. // Check to see if scripts has been turned off.
if (!mEnabled || !mDocument->IsScriptEnabled()) { if (!mEnabled || !mDocument->IsScriptEnabled()) {
@@ -3584,7 +3609,7 @@ void ScriptLoader::PreloadURI(nsIURI* aURI, const nsAString& aCharset,
request.get(), url.get())); request.get(), url.get()));
} }
nsresult rv = StartLoad(request); nsresult rv = StartLoad(request, aEarlyHintPreloaderId);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return; return;
} }

View File

@@ -392,7 +392,8 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface {
const nsAString& aIntegrity, bool aScriptFromHead, const nsAString& aIntegrity, bool aScriptFromHead,
bool aAsync, bool aDefer, bool aNoModule, bool aAsync, bool aDefer, bool aNoModule,
bool aLinkPreload, bool aLinkPreload,
const ReferrerPolicy aReferrerPolicy); const ReferrerPolicy aReferrerPolicy,
uint64_t aEarlyHintPreloaderId);
/** /**
* Process a request that was deferred so that the script could be compiled * Process a request that was deferred so that the script could be compiled
@@ -490,18 +491,21 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface {
/** /**
* Start a load for aRequest's URI. * Start a load for aRequest's URI.
*/ */
nsresult StartLoad(ScriptLoadRequest* aRequest); nsresult StartLoad(ScriptLoadRequest* aRequest,
uint64_t aEarlyHintPreloaderId);
/** /**
* Start a load for a classic script URI. * Start a load for a classic script URI.
* Sets up the necessary security flags before calling StartLoadInternal. * Sets up the necessary security flags before calling StartLoadInternal.
*/ */
nsresult StartClassicLoad(ScriptLoadRequest* aRequest); nsresult StartClassicLoad(ScriptLoadRequest* aRequest,
uint64_t aEarlyHintPreloaderId);
/** /**
* Start a load for a module script URI. * Start a load for a module script URI.
*/ */
nsresult StartLoadInternal(ScriptLoadRequest* aRequest, nsresult StartLoadInternal(ScriptLoadRequest* aRequest,
nsSecurityFlags securityFlags); nsSecurityFlags securityFlags,
uint64_t aEarlyHintPreloaderId);
/** /**
* Abort the current stream, and re-start with a new load request from scratch * Abort the current stream, and re-start with a new load request from scratch

View File

@@ -1218,7 +1218,7 @@ void nsHtml5TreeOpExecutor::PreloadScript(
mDocument->ScriptLoader()->PreloadURI( mDocument->ScriptLoader()->PreloadURI(
uri, aCharset, aType, aCrossOrigin, aIntegrity, aScriptFromHead, aAsync, uri, aCharset, aType, aCrossOrigin, aIntegrity, aScriptFromHead, aAsync,
aDefer, aNoModule, aLinkPreload, aDefer, aNoModule, aLinkPreload,
GetPreloadReferrerPolicy(aReferrerPolicy)); GetPreloadReferrerPolicy(aReferrerPolicy), 0);
} }
void nsHtml5TreeOpExecutor::PreloadStyle(const nsAString& aURL, void nsHtml5TreeOpExecutor::PreloadStyle(const nsAString& aURL,

View File

@@ -198,7 +198,8 @@ void PreloadService::PreloadScript(nsIURI* aURI, const nsAString& aType,
uint64_t aEarlyHintPreloaderId) { uint64_t aEarlyHintPreloaderId) {
mDocument->ScriptLoader()->PreloadURI( mDocument->ScriptLoader()->PreloadURI(
aURI, aCharset, aType, aCrossOrigin, aIntegrity, aScriptFromHead, false, aURI, aCharset, aType, aCrossOrigin, aIntegrity, aScriptFromHead, false,
false, false, true, PreloadReferrerPolicy(aReferrerPolicy)); false, false, true, PreloadReferrerPolicy(aReferrerPolicy),
aEarlyHintPreloaderId);
} }
void PreloadService::PreloadImage(nsIURI* aURI, const nsAString& aCrossOrigin, void PreloadService::PreloadImage(nsIURI* aURI, const nsAString& aCrossOrigin,