Bug 1804086 - Allow classic script hint to be passed from content to parent r=smaug,necko-reviewers,kershaw

This is needed for doing content decoding for ORB.

Differential Revision: https://phabricator.services.mozilla.com/D172490
This commit is contained in:
Sean Feng 2023-03-22 14:21:39 +00:00
parent cc5ef8b4c3
commit b32e4554a9
13 changed files with 108 additions and 21 deletions

View File

@ -107,8 +107,12 @@ nsresult ModuleLoader::StartFetch(ModuleLoadRequest* aRequest) {
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
// Delegate Shared Behavior to base ScriptLoader
nsresult rv =
GetScriptLoader()->StartLoadInternal(aRequest, securityFlags, 0);
//
// aCharsetForPreload is passed as Nothing() because this is not a preload
// and `StartLoadInternal` is able to find the charset by using `aRequest`
// for this case.
nsresult rv = GetScriptLoader()->StartLoadInternal(
aRequest, securityFlags, 0, Nothing() /* aCharsetForPreload */);
NS_ENSURE_SUCCESS(rv, rv);
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-an-import()-module-script-graph

View File

@ -520,7 +520,7 @@ nsresult ScriptLoader::RestartLoad(ScriptLoadRequest* aRequest) {
if (aRequest->IsModuleRequest()) {
rv = aRequest->AsModuleRequest()->RestartModuleLoad();
} else {
rv = StartLoad(aRequest, 0);
rv = StartLoad(aRequest, 0, Nothing());
}
if (NS_FAILED(rv)) {
return rv;
@ -531,17 +531,19 @@ nsresult ScriptLoader::RestartLoad(ScriptLoadRequest* aRequest) {
return NS_BINDING_RETARGETED;
}
nsresult ScriptLoader::StartLoad(ScriptLoadRequest* aRequest,
uint64_t aEarlyHintPreloaderId) {
nsresult ScriptLoader::StartLoad(
ScriptLoadRequest* aRequest, uint64_t aEarlyHintPreloaderId,
const Maybe<nsAutoString>& aCharsetForPreload) {
if (aRequest->IsModuleRequest()) {
return aRequest->AsModuleRequest()->StartModuleLoad();
}
return StartClassicLoad(aRequest, aEarlyHintPreloaderId);
return StartClassicLoad(aRequest, aEarlyHintPreloaderId, aCharsetForPreload);
}
nsresult ScriptLoader::StartClassicLoad(ScriptLoadRequest* aRequest,
uint64_t aEarlyHintPreloaderId) {
nsresult ScriptLoader::StartClassicLoad(
ScriptLoadRequest* aRequest, uint64_t aEarlyHintPreloaderId,
const Maybe<nsAutoString>& aCharsetForPreload) {
MOZ_ASSERT(aRequest->IsFetching());
NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER);
aRequest->SetUnknownDataType();
@ -565,8 +567,8 @@ nsresult ScriptLoader::StartClassicLoad(ScriptLoadRequest* aRequest,
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
nsresult rv =
StartLoadInternal(aRequest, securityFlags, aEarlyHintPreloaderId);
nsresult rv = StartLoadInternal(aRequest, securityFlags,
aEarlyHintPreloaderId, aCharsetForPreload);
NS_ENSURE_SUCCESS(rv, rv);
@ -583,9 +585,10 @@ static bool IsWebExtensionRequest(ScriptLoadRequest* aRequest) {
return loader->GetKind() == ModuleLoader::WebExtension;
}
nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
nsSecurityFlags securityFlags,
uint64_t aEarlyHintPreloaderId) {
nsresult ScriptLoader::StartLoadInternal(
ScriptLoadRequest* aRequest, nsSecurityFlags securityFlags,
uint64_t aEarlyHintPreloaderId,
const Maybe<nsAutoString>& aCharsetForPreload) {
nsContentPolicyType contentPolicyType =
ScriptLoadRequestToContentPolicyType(aRequest);
nsCOMPtr<nsINode> context;
@ -731,6 +734,18 @@ nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
aRequest->mIntegrity.GetIntegrityString());
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
nsAutoString hintCharset;
if (!aRequest->GetScriptLoadContext()->IsPreload() &&
aRequest->GetScriptLoadContext()->GetScriptElement()) {
aRequest->GetScriptLoadContext()->GetScriptElement()->GetScriptCharset(
hintCharset);
} else if (aCharsetForPreload.isSome()) {
hintCharset = aCharsetForPreload.ref();
}
rv = httpChannel->SetClassicScriptHintCharset(hintCharset);
NS_ENSURE_SUCCESS(rv, rv);
}
mozilla::net::PredictorLearn(
@ -1029,7 +1044,7 @@ bool ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
LOG(("ScriptLoadRequest (%p): Created request for external script",
request.get()));
nsresult rv = StartLoad(request, 0);
nsresult rv = StartLoad(request, 0, Nothing());
if (NS_FAILED(rv)) {
ReportErrorToConsole(request, rv);
@ -3565,7 +3580,8 @@ void ScriptLoader::PreloadURI(nsIURI* aURI, const nsAString& aCharset,
request.get(), url.get()));
}
nsresult rv = StartLoad(request, aEarlyHintPreloaderId);
nsAutoString charset(aCharset);
nsresult rv = StartLoad(request, aEarlyHintPreloaderId, Some(charset));
if (NS_FAILED(rv)) {
return;
}

View File

@ -505,20 +505,27 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface {
* Start a load for aRequest's URI.
*/
nsresult StartLoad(ScriptLoadRequest* aRequest,
uint64_t aEarlyHintPreloaderId);
uint64_t aEarlyHintPreloaderId,
const Maybe<nsAutoString>& aCharsetForPreload);
/**
* Start a load for a classic script URI.
* Sets up the necessary security flags before calling StartLoadInternal.
*/
nsresult StartClassicLoad(ScriptLoadRequest* aRequest,
uint64_t aEarlyHintPreloaderId);
uint64_t aEarlyHintPreloaderId,
const Maybe<nsAutoString>& aCharsetForPreload);
/**
* Start a load for a module script URI.
*
* aCharsetForPreload is only needed when this load is a preload (via
* ScriptLoader::PreloadURI), because ScriptLoadRequest doesn't
* have this information.
*/
nsresult StartLoadInternal(ScriptLoadRequest* aRequest,
nsSecurityFlags securityFlags,
uint64_t aEarlyHintPreloaderId);
uint64_t aEarlyHintPreloaderId,
const Maybe<nsAutoString>& aCharsetForPreload);
/**
* Abort the current stream, and re-start with a new load request from scratch

View File

@ -348,6 +348,7 @@ struct HttpChannelOpenArgs
bool preferCacheLoadOverBypass;
bool forceMainDocumentChannel;
uint8_t redirectionLimit;
nsString classicScriptHintCharset;
};
struct HttpChannelConnectArgs

View File

@ -6062,6 +6062,19 @@ HttpBaseChannel::GetEarlyHintPreloaderId(uint64_t* aEarlyHintPreloaderId) {
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetClassicScriptHintCharset(
const nsAString& aClassicScriptHintCharset) {
mClassicScriptHintCharset = aClassicScriptHintCharset;
return NS_OK;
}
NS_IMETHODIMP HttpBaseChannel::GetClassicScriptHintCharset(
nsAString& aClassicScriptHintCharset) {
aClassicScriptHintCharset = mClassicScriptHintCharset;
return NS_OK;
}
void HttpBaseChannel::SetConnectionInfo(nsHttpConnectionInfo* aCI) {
mConnectionInfo = aCI ? aCI->Clone() : nullptr;
}

View File

@ -352,6 +352,11 @@ class HttpBaseChannel : public nsHashPropertyBag,
NS_IMETHOD SetEarlyHintPreloaderId(uint64_t aEarlyHintPreloaderId) override;
NS_IMETHOD GetEarlyHintPreloaderId(uint64_t* aEarlyHintPreloaderId) override;
NS_IMETHOD SetClassicScriptHintCharset(
const nsAString& aClassicScriptHintCharset) override;
NS_IMETHOD GetClassicScriptHintCharset(
nsAString& aClassicScriptHintCharset) override;
virtual void SetConnectionInfo(
mozilla::net::nsHttpConnectionInfo* aCI) override;
@ -814,6 +819,7 @@ class HttpBaseChannel : public nsHashPropertyBag,
// channels started from the above list
uint64_t mEarlyHintPreloaderId = 0;
nsString mClassicScriptHintCharset;
// clang-format off
MOZ_ATOMIC_BITFIELDS(mAtomicBitfields1, 32, (
(uint32_t, UpgradeToSecure, 1),

View File

@ -2270,6 +2270,7 @@ nsresult HttpChannelChild::ContinueAsyncOpen() {
openArgs.navigationStartTimeStamp() = navigationStartTimeStamp;
openArgs.earlyHintPreloaderId() = mEarlyHintPreloaderId;
openArgs.classicScriptHintCharset() = mClassicScriptHintCharset;
// This must happen before the constructor message is sent. Otherwise messages
// from the parent could arrive quickly and be delivered to the wrong event
// target.

View File

@ -141,7 +141,7 @@ bool HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs) {
a.dispatchFetchEventStart(), a.dispatchFetchEventEnd(),
a.handleFetchEventStart(), a.handleFetchEventEnd(),
a.forceMainDocumentChannel(), a.navigationStartTimeStamp(),
a.earlyHintPreloaderId());
a.earlyHintPreloaderId(), a.classicScriptHintCharset());
}
case HttpChannelCreationArgs::THttpChannelConnectArgs: {
const HttpChannelConnectArgs& cArgs = aArgs.get_HttpChannelConnectArgs();
@ -404,7 +404,8 @@ bool HttpChannelParent::DoAsyncOpen(
const TimeStamp& aHandleFetchEventEnd,
const bool& aForceMainDocumentChannel,
const TimeStamp& aNavigationStartTimeStamp,
const uint64_t& aEarlyHintPreloaderId) {
const uint64_t& aEarlyHintPreloaderId,
const nsAString& aClassicScriptHintCharset) {
MOZ_ASSERT(aURI, "aURI should not be NULL");
if (aEarlyHintPreloaderId) {
@ -507,6 +508,7 @@ bool HttpChannelParent::DoAsyncOpen(
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
httpChannel->SetClassicScriptHintCharset(aClassicScriptHintCharset);
if (aAPIRedirectToURI) {
httpChannel->RedirectTo(aAPIRedirectToURI);
}

View File

@ -170,7 +170,8 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
const TimeStamp& aHandleFetchEventEnd,
const bool& aForceMainDocumentChannel,
const TimeStamp& aNavigationStartTimeStamp,
const uint64_t& aEarlyHintPreloaderId);
const uint64_t& aEarlyHintPreloaderId,
const nsAString& aClassicScriptHintCharset);
virtual mozilla::ipc::IPCResult RecvSetPriority(
const int16_t& priority) override;

View File

@ -800,6 +800,16 @@ NullHttpChannel::GetNativeServerTiming(
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP NullHttpChannel::SetClassicScriptHintCharset(
const nsAString& aClassicScriptHintCharset) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP NullHttpChannel::GetClassicScriptHintCharset(
nsAString& aClassicScriptHintCharset) {
return NS_ERROR_NOT_IMPLEMENTED;
}
#define IMPL_TIMING_ATTR(name) \
NS_IMETHODIMP \
NullHttpChannel::Get##name##Time(PRTime* _retval) { \

View File

@ -831,4 +831,14 @@ NS_IMETHODIMP ObliviousHttpChannel::CloneUploadStream(
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP ObliviousHttpChannel::SetClassicScriptHintCharset(
const nsAString& aClassicScriptHintCharset) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP ObliviousHttpChannel::GetClassicScriptHintCharset(
nsAString& aClassicScriptHintCharset) {
return NS_ERROR_NOT_IMPLEMENTED;
}
} // namespace mozilla::net

View File

@ -485,4 +485,6 @@ interface nsIHttpChannel : nsIIdentChannel
in AString aContentType);
[notxpcom, nostdcall] void setSource(in UniqueProfileChunkedBuffer aSource);
[must_use] attribute AString classicScriptHintCharset;
};

View File

@ -1018,6 +1018,20 @@ nsViewSourceChannel::SetIsMainDocumentChannel(bool aValue) {
: mHttpChannel->SetIsMainDocumentChannel(aValue);
}
NS_IMETHODIMP nsViewSourceChannel::SetClassicScriptHintCharset(
const nsAString& aClassicScriptHintCharset) {
return !mHttpChannel ? NS_ERROR_NULL_POINTER
: mHttpChannel->SetClassicScriptHintCharset(
aClassicScriptHintCharset);
}
NS_IMETHODIMP nsViewSourceChannel::GetClassicScriptHintCharset(
nsAString& aClassicScriptHintCharset) {
return !mHttpChannel ? NS_ERROR_NULL_POINTER
: mHttpChannel->GetClassicScriptHintCharset(
aClassicScriptHintCharset);
}
// Have to manually forward SetCorsPreflightParameters since it's [notxpcom]
void nsViewSourceChannel::SetCorsPreflightParameters(
const nsTArray<nsCString>& aUnsafeHeaders,