Bug 1944052 - Set stylesheet metadata on OnStartRequest. r=dshin
SKIP_BMO_CHECK Differential Revision: https://phabricator.services.mozilla.com/D238592
This commit is contained in:
@@ -633,18 +633,8 @@ static nsresult VerifySheetIntegrity(const SRIMetadata& aMetadata,
|
|||||||
const nsACString& aSourceFileURI,
|
const nsACString& aSourceFileURI,
|
||||||
nsIConsoleReportCollector* aReporter) {
|
nsIConsoleReportCollector* aReporter) {
|
||||||
NS_ENSURE_ARG_POINTER(aReporter);
|
NS_ENSURE_ARG_POINTER(aReporter);
|
||||||
|
|
||||||
if (MOZ_LOG_TEST(SRILogHelper::GetSriLog(), LogLevel::Debug)) {
|
|
||||||
nsAutoCString requestURL;
|
|
||||||
nsCOMPtr<nsIURI> originalURI;
|
|
||||||
if (aChannel &&
|
|
||||||
NS_SUCCEEDED(aChannel->GetOriginalURI(getter_AddRefs(originalURI))) &&
|
|
||||||
originalURI) {
|
|
||||||
originalURI->GetAsciiSpec(requestURL);
|
|
||||||
}
|
|
||||||
MOZ_LOG(SRILogHelper::GetSriLog(), LogLevel::Debug,
|
MOZ_LOG(SRILogHelper::GetSriLog(), LogLevel::Debug,
|
||||||
("VerifySheetIntegrity (unichar stream)"));
|
("VerifySheetIntegrity (unichar stream)"));
|
||||||
}
|
|
||||||
|
|
||||||
SRICheckDataVerifier verifier(aMetadata, aSourceFileURI, aReporter);
|
SRICheckDataVerifier verifier(aMetadata, aSourceFileURI, aReporter);
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
@@ -667,17 +657,69 @@ static bool AllLoadsCanceled(const SheetLoadData& aData) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SheetLoadData::OnStartRequest(nsIRequest* aRequest) {
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
NotifyStart(aRequest);
|
||||||
|
|
||||||
|
SetMinimumExpirationTime(
|
||||||
|
nsContentUtils::GetSubresourceCacheExpirationTime(aRequest, mURI));
|
||||||
|
|
||||||
|
// We need to block resolution of parse promise until we receive OnStopRequest
|
||||||
|
// on Main thread. This is necessary because parse promise resolution fires
|
||||||
|
// OnLoad event must not be dispatched until OnStopRequest in main thread is
|
||||||
|
// processed, for stuff like performance resource entries.
|
||||||
|
mSheet->BlockParsePromise();
|
||||||
|
|
||||||
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||||
|
if (!channel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> originalURI;
|
||||||
|
channel->GetOriginalURI(getter_AddRefs(originalURI));
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(originalURI,
|
||||||
|
"Someone just violated the nsIRequest contract");
|
||||||
|
nsCOMPtr<nsIURI> finalURI;
|
||||||
|
NS_GetFinalChannelURI(channel, getter_AddRefs(finalURI));
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(finalURI,
|
||||||
|
"Someone just violated the nsIRequest contract");
|
||||||
|
mSheet->SetURIs(finalURI, originalURI, finalURI);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPrincipal> principal;
|
||||||
|
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||||
|
if (mUseSystemPrincipal) {
|
||||||
|
secMan->GetSystemPrincipal(getter_AddRefs(principal));
|
||||||
|
} else {
|
||||||
|
secMan->GetChannelResultPrincipal(channel, getter_AddRefs(principal));
|
||||||
|
}
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(principal);
|
||||||
|
mSheet->SetPrincipal(principal);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIReferrerInfo> referrerInfo =
|
||||||
|
ReferrerInfo::CreateForExternalCSSResources(
|
||||||
|
mSheet, nsContentUtils::GetReferrerPolicyFromChannel(channel));
|
||||||
|
mSheet->SetReferrerInfo(referrerInfo);
|
||||||
|
|
||||||
|
if (nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel)) {
|
||||||
|
nsCString sourceMapURL;
|
||||||
|
if (nsContentUtils::GetSourceMapURL(httpChannel, sourceMapURL)) {
|
||||||
|
mSheet->SetSourceMapURL(std::move(sourceMapURL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mIsCrossOriginNoCORS = mSheet->GetCORSMode() == CORS_NONE &&
|
||||||
|
!mTriggeringPrincipal->Subsumes(mSheet->Principal());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stream completion code shared by Stylo and the old style system.
|
|
||||||
*
|
|
||||||
* Here we need to check that the load did not give us an http error
|
* Here we need to check that the load did not give us an http error
|
||||||
* page and check the mimetype on the channel to make sure we're not
|
* page and check the mimetype on the channel to make sure we're not
|
||||||
* loading non-text/css data in standards mode.
|
* loading non-text/css data in standards mode.
|
||||||
*/
|
*/
|
||||||
nsresult SheetLoadData::VerifySheetReadyToParse(
|
nsresult SheetLoadData::VerifySheetReadyToParse(nsresult aStatus,
|
||||||
nsresult aStatus, const nsACString& aBytes1, const nsACString& aBytes2,
|
const nsACString& aBytes1,
|
||||||
nsIChannel* aChannel, nsIURI* aFinalChannelURI,
|
const nsACString& aBytes2,
|
||||||
nsIPrincipal* aChannelResultPrincipal) {
|
nsIChannel* aChannel) {
|
||||||
LOG(("SheetLoadData::VerifySheetReadyToParse"));
|
LOG(("SheetLoadData::VerifySheetReadyToParse"));
|
||||||
NS_ASSERTION((!NS_IsMainThread() || !mLoader->mSyncCallback),
|
NS_ASSERTION((!NS_IsMainThread() || !mLoader->mSyncCallback),
|
||||||
"Synchronous callback from necko");
|
"Synchronous callback from necko");
|
||||||
@@ -726,51 +768,11 @@ nsresult SheetLoadData::VerifySheetReadyToParse(
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> originalURI;
|
|
||||||
aChannel->GetOriginalURI(getter_AddRefs(originalURI));
|
|
||||||
|
|
||||||
// If the channel's original URI is "chrome:", we want that, since
|
|
||||||
// the observer code in nsXULPrototypeCache depends on chrome stylesheets
|
|
||||||
// having a chrome URI. (Whether or not chrome stylesheets come through
|
|
||||||
// this codepath seems nondeterministic.)
|
|
||||||
// Otherwise we want the potentially-HTTP-redirected URI.
|
|
||||||
if (!aFinalChannelURI || !originalURI) {
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
NS_ERROR("Someone just violated the nsIRequest contract");
|
|
||||||
LOG_WARN((" Channel without a URI. Bad!"));
|
|
||||||
mLoader->SheetComplete(*this, NS_ERROR_UNEXPECTED);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> principal;
|
|
||||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
|
||||||
nsresult result = NS_ERROR_NOT_AVAILABLE;
|
|
||||||
if (secMan) { // Could be null if we already shut down
|
|
||||||
if (mUseSystemPrincipal) {
|
|
||||||
result = secMan->GetSystemPrincipal(getter_AddRefs(principal));
|
|
||||||
} else {
|
|
||||||
if (aChannelResultPrincipal) {
|
|
||||||
principal = aChannelResultPrincipal;
|
|
||||||
result = NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_FAILED(result)) {
|
|
||||||
if (NS_IsMainThread()) {
|
|
||||||
LOG_WARN((" Couldn't get principal"));
|
|
||||||
mLoader->SheetComplete(*this, result);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
mSheet->SetPrincipal(principal);
|
|
||||||
|
|
||||||
// If it's an HTTP channel, we want to make sure this is not an
|
// If it's an HTTP channel, we want to make sure this is not an
|
||||||
// error document we got.
|
// error document we got.
|
||||||
if (nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel)) {
|
if (nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel)) {
|
||||||
bool requestSucceeded;
|
bool requestSucceeded;
|
||||||
result = httpChannel->GetRequestSucceeded(&requestSucceeded);
|
nsresult result = httpChannel->GetRequestSucceeded(&requestSucceeded);
|
||||||
if (NS_SUCCEEDED(result) && !requestSucceeded) {
|
if (NS_SUCCEEDED(result) && !requestSucceeded) {
|
||||||
if (NS_IsMainThread()) {
|
if (NS_IsMainThread()) {
|
||||||
LOG((" Load returned an error page"));
|
LOG((" Load returned an error page"));
|
||||||
@@ -778,11 +780,6 @@ nsresult SheetLoadData::VerifySheetReadyToParse(
|
|||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCString sourceMapURL;
|
|
||||||
if (nsContentUtils::GetSourceMapURL(httpChannel, sourceMapURL)) {
|
|
||||||
mSheet->SetSourceMapURL(std::move(sourceMapURL));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoCString contentType;
|
nsAutoCString contentType;
|
||||||
@@ -793,7 +790,7 @@ nsresult SheetLoadData::VerifySheetReadyToParse(
|
|||||||
// MIME type, but only if the style sheet is same-origin with the
|
// MIME type, but only if the style sheet is same-origin with the
|
||||||
// requesting document or parent sheet. See bug 524223.
|
// requesting document or parent sheet. See bug 524223.
|
||||||
|
|
||||||
bool validType = contentType.EqualsLiteral("text/css") ||
|
const bool validType = contentType.EqualsLiteral("text/css") ||
|
||||||
contentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE) ||
|
contentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE) ||
|
||||||
contentType.IsEmpty();
|
contentType.IsEmpty();
|
||||||
|
|
||||||
@@ -806,7 +803,8 @@ nsresult SheetLoadData::VerifySheetReadyToParse(
|
|||||||
bool sameOrigin = true;
|
bool sameOrigin = true;
|
||||||
|
|
||||||
bool subsumed;
|
bool subsumed;
|
||||||
result = mTriggeringPrincipal->Subsumes(principal, &subsumed);
|
nsresult result =
|
||||||
|
mTriggeringPrincipal->Subsumes(mSheet->Principal(), &subsumed);
|
||||||
if (NS_FAILED(result) || !subsumed) {
|
if (NS_FAILED(result) || !subsumed) {
|
||||||
sameOrigin = false;
|
sameOrigin = false;
|
||||||
}
|
}
|
||||||
@@ -820,7 +818,7 @@ nsresult SheetLoadData::VerifySheetReadyToParse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
AutoTArray<nsString, 2> strings;
|
AutoTArray<nsString, 2> strings;
|
||||||
CopyUTF8toUTF16(aFinalChannelURI->GetSpecOrDefault(),
|
CopyUTF8toUTF16(mSheet->GetSheetURI()->GetSpecOrDefault(),
|
||||||
*strings.AppendElement());
|
*strings.AppendElement());
|
||||||
CopyASCIItoUTF16(contentType, *strings.AppendElement());
|
CopyASCIItoUTF16(contentType, *strings.AppendElement());
|
||||||
|
|
||||||
@@ -871,21 +869,6 @@ nsresult SheetLoadData::VerifySheetReadyToParse(
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSheet->GetCORSMode() == CORS_NONE &&
|
|
||||||
!mTriggeringPrincipal->Subsumes(principal)) {
|
|
||||||
mIsCrossOriginNoCORS = true;
|
|
||||||
}
|
|
||||||
// Enough to set the URIs on mSheet, since any sibling datas we have share
|
|
||||||
// the same mInner as mSheet and will thus get the same URI.
|
|
||||||
mSheet->SetURIs(aFinalChannelURI, originalURI, aFinalChannelURI);
|
|
||||||
|
|
||||||
ReferrerPolicy policy =
|
|
||||||
nsContentUtils::GetReferrerPolicyFromChannel(aChannel);
|
|
||||||
nsCOMPtr<nsIReferrerInfo> referrerInfo =
|
|
||||||
ReferrerInfo::CreateForExternalCSSResources(mSheet, policy);
|
|
||||||
|
|
||||||
mSheet->SetReferrerInfo(referrerInfo);
|
|
||||||
return NS_OK_PARSE_SHEET;
|
return NS_OK_PARSE_SHEET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,13 +94,12 @@ class SheetLoadData final
|
|||||||
NotNull<const Encoding*> DetermineNonBOMEncoding(const nsACString& aSegment,
|
NotNull<const Encoding*> DetermineNonBOMEncoding(const nsACString& aSegment,
|
||||||
nsIChannel*) const;
|
nsIChannel*) const;
|
||||||
|
|
||||||
|
void OnStartRequest(nsIRequest*);
|
||||||
|
|
||||||
// The caller may have the bytes for the stylesheet split across two strings,
|
// The caller may have the bytes for the stylesheet split across two strings,
|
||||||
// so aBytes1 and aBytes2 refer to those pieces.
|
// so aBytes1 and aBytes2 refer to those pieces.
|
||||||
nsresult VerifySheetReadyToParse(nsresult aStatus, const nsACString& aBytes1,
|
nsresult VerifySheetReadyToParse(nsresult aStatus, const nsACString& aBytes1,
|
||||||
const nsACString& aBytes2,
|
const nsACString& aBytes2, nsIChannel*);
|
||||||
nsIChannel* aChannel,
|
|
||||||
nsIURI* aFinalChannelURI,
|
|
||||||
nsIPrincipal* aPrincipal);
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ NS_IMETHODIMP
|
|||||||
StreamLoader::OnStartRequest(nsIRequest* aRequest) {
|
StreamLoader::OnStartRequest(nsIRequest* aRequest) {
|
||||||
MOZ_ASSERT(aRequest);
|
MOZ_ASSERT(aRequest);
|
||||||
mRequest = aRequest;
|
mRequest = aRequest;
|
||||||
mSheetLoadData->NotifyStart(aRequest);
|
mSheetLoadData->OnStartRequest(aRequest);
|
||||||
|
|
||||||
// It's kinda bad to let Web content send a number that results
|
// It's kinda bad to let Web content send a number that results
|
||||||
// in a potentially large allocation directly, but efficiency of
|
// in a potentially large allocation directly, but efficiency of
|
||||||
@@ -62,12 +62,6 @@ StreamLoader::OnStartRequest(nsIRequest* aRequest) {
|
|||||||
return (mStatus = NS_ERROR_OUT_OF_MEMORY);
|
return (mStatus = NS_ERROR_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_GetFinalChannelURI(channel, getter_AddRefs(mFinalChannelURI));
|
|
||||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
|
||||||
// we dont return on error here as the error is handled in
|
|
||||||
// SheetLoadData::VerifySheetReadyToParse
|
|
||||||
Unused << secMan->GetChannelResultPrincipal(
|
|
||||||
channel, getter_AddRefs(mChannelResultPrincipal));
|
|
||||||
}
|
}
|
||||||
if (nsCOMPtr<nsIThreadRetargetableRequest> rr = do_QueryInterface(aRequest)) {
|
if (nsCOMPtr<nsIThreadRetargetableRequest> rr = do_QueryInterface(aRequest)) {
|
||||||
nsCOMPtr<nsIEventTarget> sts =
|
nsCOMPtr<nsIEventTarget> sts =
|
||||||
@@ -77,17 +71,6 @@ StreamLoader::OnStartRequest(nsIRequest* aRequest) {
|
|||||||
rr->RetargetDeliveryTo(queue);
|
rr->RetargetDeliveryTo(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
mSheetLoadData->SetMinimumExpirationTime(
|
|
||||||
nsContentUtils::GetSubresourceCacheExpirationTime(aRequest,
|
|
||||||
mSheetLoadData->mURI));
|
|
||||||
|
|
||||||
// We need to block block resolution of parse promise until we receive
|
|
||||||
// OnStopRequest on Main thread. This is necessary because parse promise
|
|
||||||
// resolution fires OnLoad event OnLoad event must not be dispatched until
|
|
||||||
// OnStopRequest in main thread is processed, for stuff like performance
|
|
||||||
// resource entries.
|
|
||||||
mSheetLoadData->mSheet->BlockParsePromise();
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,10 +126,7 @@ StreamLoader::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
|
|||||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||||
|
|
||||||
if (NS_FAILED(mStatus)) {
|
if (NS_FAILED(mStatus)) {
|
||||||
mSheetLoadData->VerifySheetReadyToParse(mStatus, ""_ns, ""_ns, channel,
|
mSheetLoadData->VerifySheetReadyToParse(mStatus, ""_ns, ""_ns, channel);
|
||||||
mFinalChannelURI,
|
|
||||||
mChannelResultPrincipal);
|
|
||||||
|
|
||||||
if (!NS_IsMainThread()) {
|
if (!NS_IsMainThread()) {
|
||||||
// When processing OMT, we have code paths in VerifySheetReadyToParse
|
// When processing OMT, we have code paths in VerifySheetReadyToParse
|
||||||
// that are main-thread only. We bail on such scenarios and continue
|
// that are main-thread only. We bail on such scenarios and continue
|
||||||
@@ -157,8 +137,7 @@ StreamLoader::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rv = mSheetLoadData->VerifySheetReadyToParse(aStatus, mBOMBytes, mBytes,
|
rv = mSheetLoadData->VerifySheetReadyToParse(aStatus, mBOMBytes, mBytes,
|
||||||
channel, mFinalChannelURI,
|
channel);
|
||||||
mChannelResultPrincipal);
|
|
||||||
if (rv != NS_OK_PARSE_SHEET) {
|
if (rv != NS_OK_PARSE_SHEET) {
|
||||||
if (!NS_IsMainThread()) {
|
if (!NS_IsMainThread()) {
|
||||||
mOnStopProcessingDone = false;
|
mOnStopProcessingDone = false;
|
||||||
|
|||||||
@@ -60,8 +60,6 @@ class StreamLoader : public nsIThreadRetargetableStreamListener,
|
|||||||
nsCString mBytes;
|
nsCString mBytes;
|
||||||
nsAutoCStringN<3> mBOMBytes;
|
nsAutoCStringN<3> mBOMBytes;
|
||||||
nsCOMPtr<nsIRequest> mRequest;
|
nsCOMPtr<nsIRequest> mRequest;
|
||||||
nsCOMPtr<nsIURI> mFinalChannelURI;
|
|
||||||
nsCOMPtr<nsIPrincipal> mChannelResultPrincipal;
|
|
||||||
// flag to indicate that we can skip processing of data in OnStopRequest
|
// flag to indicate that we can skip processing of data in OnStopRequest
|
||||||
bool mOnStopProcessingDone{false};
|
bool mOnStopProcessingDone{false};
|
||||||
RefPtr<SheetLoadDataHolder> mMainThreadSheetLoadData;
|
RefPtr<SheetLoadDataHolder> mMainThreadSheetLoadData;
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ namespace mozilla {
|
|||||||
void StyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI,
|
void StyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI,
|
||||||
nsIURI* aBaseURI) {
|
nsIURI* aBaseURI) {
|
||||||
MOZ_ASSERT(aSheetURI && aBaseURI, "null ptr");
|
MOZ_ASSERT(aSheetURI && aBaseURI, "null ptr");
|
||||||
// HasRules() should be accessed only on the main thread
|
MOZ_ASSERT(!HasRules() && !IsComplete());
|
||||||
MOZ_ASSERT_IF(NS_IsMainThread(), !HasRules() && !IsComplete());
|
|
||||||
StyleSheetInfo& info = Inner();
|
StyleSheetInfo& info = Inner();
|
||||||
info.mSheetURI = aSheetURI;
|
info.mSheetURI = aSheetURI;
|
||||||
info.mOriginalSheetURI = aOriginalSheetURI;
|
info.mOriginalSheetURI = aOriginalSheetURI;
|
||||||
|
|||||||
Reference in New Issue
Block a user