Bug 1957490 - Factor out clearing logic from SharedSubResourceCache. r=arai

No behavior change intended.

This will be useful to clear inline styles in bug 1956486.

Differential Revision: https://phabricator.services.mozilla.com/D243713
This commit is contained in:
Emilio Cobos Álvarez
2025-04-01 07:51:07 +00:00
parent e11981455f
commit 66216ac6a7
2 changed files with 90 additions and 59 deletions

View File

@@ -61,6 +61,84 @@ void AddPerformanceEntryForCache(
storage->AddEntry(aEntryName, aInitiatorType, std::move(data));
}
bool ShouldClearEntry(nsIURI* aEntryURI, nsIPrincipal* aEntryLoaderPrincipal,
nsIPrincipal* aEntryPartitionPrincipal,
const Maybe<bool>& aChrome,
const Maybe<nsCOMPtr<nsIPrincipal>>& aPrincipal,
const Maybe<nsCString>& aSchemelessSite,
const Maybe<OriginAttributesPattern>& aPattern,
const Maybe<nsCString>& aURL) {
if (aChrome.isSome()) {
RefPtr<nsIURI> uri = aEntryURI;
if (!uri) {
// If there's no uri (inline resource) try to use the principal URI.
uri = aEntryLoaderPrincipal->GetURI();
}
const bool isChrome = [&] {
if (uri && (uri->SchemeIs("chrome") || uri->SchemeIs("resource"))) {
return true;
}
if (!aEntryURI && aEntryLoaderPrincipal->IsSystemPrincipal()) {
return true;
}
return false;
}();
if (*aChrome != isChrome) {
return false;
}
if (!aPrincipal && !aSchemelessSite && !aURL) {
return true;
}
}
if (aURL) {
if (!aEntryURI) {
// Inline resources have no URL.
return false;
}
nsAutoCString spec;
nsresult rv = aEntryURI->GetSpec(spec);
if (NS_FAILED(rv)) {
return false;
}
return spec == *aURL;
}
if (aPrincipal && aEntryLoaderPrincipal->Equals(aPrincipal.ref())) {
return true;
}
if (!aSchemelessSite) {
return false;
}
// Clear by site.
// Clear entries with site. This includes entries which are partitioned
// under other top level sites (= have a partitionKey set).
nsAutoCString principalBaseDomain;
nsresult rv = aEntryPartitionPrincipal->GetBaseDomain(principalBaseDomain);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (principalBaseDomain.Equals(aSchemelessSite.ref()) &&
aPattern.ref().Matches(aEntryPartitionPrincipal->OriginAttributesRef())) {
return true;
}
// Clear entries partitioned under aSchemelessSite. We need to add the
// partition key filter to aPattern so that we include any OA filtering
// specified by the caller. For example the caller may pass aPattern = {
// privateBrowsingId: 1 } which means we may only clear partitioned
// private browsing data.
OriginAttributesPattern patternWithPartitionKey(aPattern.ref());
patternWithPartitionKey.mPartitionKeyPattern.Construct();
patternWithPartitionKey.mPartitionKeyPattern.Value().mBaseDomain.Construct(
NS_ConvertUTF8toUTF16(aSchemelessSite.ref()));
return patternWithPartitionKey.Matches(
aEntryPartitionPrincipal->OriginAttributesRef());
}
} // namespace SharedSubResourceCacheUtils
SubResourceNetworkMetadataHolder::SubResourceNetworkMetadataHolder(

View File

@@ -120,6 +120,14 @@ void AddPerformanceEntryForCache(
const SubResourceNetworkMetadataHolder* aNetworkMetadata,
TimeStamp aStartTime, TimeStamp aEndTime, dom::Document* aDocument);
bool ShouldClearEntry(nsIURI* aEntryURI, nsIPrincipal* aEntryLoaderPrincipal,
nsIPrincipal* aEntryPartitionPrincipal,
const Maybe<bool>& aChrome,
const Maybe<nsCOMPtr<nsIPrincipal>>& aPrincipal,
const Maybe<nsCString>& aSchemelessSite,
const Maybe<OriginAttributesPattern>& aPattern,
const Maybe<nsCString>& aURL);
} // namespace SharedSubResourceCacheUtils
template <typename Traits, typename Derived>
@@ -286,65 +294,10 @@ void SharedSubResourceCache<Traits, Derived>::ClearInProcess(
}
for (auto iter = mComplete.Iter(); !iter.Done(); iter.Next()) {
const bool shouldRemove = [&] {
if (aChrome.isSome()) {
nsIURI* uri = iter.Key().URI();
bool isChrome = uri->SchemeIs("chrome") || uri->SchemeIs("resource");
if (*aChrome != isChrome) {
return false;
}
if (!aPrincipal && !aSchemelessSite && !aURL) {
return true;
}
}
if (aURL) {
nsAutoCString spec;
nsresult rv = iter.Key().URI()->GetSpec(spec);
if (NS_FAILED(rv)) {
return false;
}
return spec == *aURL;
}
if (aPrincipal &&
iter.Key().LoaderPrincipal()->Equals(aPrincipal.ref())) {
return true;
}
if (!aSchemelessSite) {
return false;
}
// Clear by site.
nsIPrincipal* partitionPrincipal = iter.Key().PartitionPrincipal();
// Clear entries with site. This includes entries which are partitioned
// under other top level sites (= have a partitionKey set).
nsAutoCString principalBaseDomain;
nsresult rv = partitionPrincipal->GetBaseDomain(principalBaseDomain);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (principalBaseDomain.Equals(aSchemelessSite.ref()) &&
aPattern.ref().Matches(partitionPrincipal->OriginAttributesRef())) {
return true;
}
// Clear entries partitioned under aSchemelessSite. We need to add the
// partition key filter to aPattern so that we include any OA filtering
// specified by the caller. For example the caller may pass aPattern = {
// privateBrowsingId: 1 } which means we may only clear partitioned
// private browsing data.
OriginAttributesPattern patternWithPartitionKey(aPattern.ref());
patternWithPartitionKey.mPartitionKeyPattern.Construct();
patternWithPartitionKey.mPartitionKeyPattern.Value()
.mBaseDomain.Construct(NS_ConvertUTF8toUTF16(aSchemelessSite.ref()));
return patternWithPartitionKey.Matches(
partitionPrincipal->OriginAttributesRef());
}();
if (shouldRemove) {
if (SharedSubResourceCacheUtils::ShouldClearEntry(
iter.Key().URI(), iter.Key().LoaderPrincipal(),
iter.Key().PartitionPrincipal(), aChrome, aPrincipal,
aSchemelessSite, aPattern, aURL)) {
iter.Remove();
}
}