From 2e404578e0fbd6fe8a30b859ae670e02fe2e99ff Mon Sep 17 00:00:00 2001 From: Javier Calvarro Nelson Date: Fri, 20 Dec 2024 16:54:15 +0100 Subject: [PATCH] Be more leanient when applying compression negotiation --- ...ET.Sdk.StaticWebAssets.Compression.targets | 15 +++--- .../Microsoft.NET.Sdk.StaticWebAssets.targets | 2 +- .../Tasks/ApplyCompressionNegotiation.cs | 48 ++++++++++++++----- .../DiscoverPrecompressedAssets.cs | 14 +++++- 4 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.Compression.targets b/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.Compression.targets index c969520ba8f9..711f1526e96a 100644 --- a/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.Compression.targets +++ b/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.Compression.targets @@ -161,11 +161,12 @@ Copyright (c) .NET Foundation. All rights reserved. - $(BuildCompressionFormats);gzip - $(PublishCompressionFormats);gzip;brotli + true + $(BuildCompressionFormats);gzip + $(PublishCompressionFormats);gzip;brotli false - $(CompressionIncludePatterns) - $(CompressionExcludePatterns) + + $(_BlazorBrotliCompressionLevel) @@ -195,7 +196,7 @@ Copyright (c) .NET Foundation. All rights reserved. GeneratePublishCompressedStaticWebAssets ResolvePublishCompressedStaticWebAssetsConfiguration --> - + ResolvePublishCompressedStaticWebAssets; $(ResolvePublishRelatedStaticWebAssetsDependsOn) @@ -216,7 +217,7 @@ Copyright (c) .NET Foundation. All rights reserved. <_DotNetHostFileName Condition="'$(OS)' == 'Windows_NT'">dotnet.exe - + diff --git a/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.targets b/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.targets index c4c9e9fea131..de69749def7a 100644 --- a/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.targets +++ b/src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.targets @@ -672,7 +672,7 @@ Copyright (c) .NET Foundation. All rights reserved. DependsOnTargets="ResolveStaticWebAssetsConfiguration;UpdateExistingPackageStaticWebAssets"> a.Identity); + var assetsById = new Dictionary(CandidateAssets.Length, OSPath.PathComparer); + // A good rule of thumb is that the number of compressed assets is half the number of assets. + var compressedAssets = new List(CandidateAssets.Length / 2); - var endpointsByAsset = CandidateEndpoints.Select(StaticWebAssetEndpoint.FromTaskItem) - .GroupBy(e => e.AssetFile) - .ToDictionary(g => g.Key, g => g.ToList()); + for (var i = 0; i < CandidateAssets.Length; i++) + { + var candidate = StaticWebAsset.FromTaskItem(CandidateAssets[i]); + if (assetsById.ContainsKey(CandidateAssets[i].ItemSpec)) + { + Log.LogWarning("Detected duplicated asset '{0}'. Skipping the asset because it was already processed.", candidate.Identity); + continue; + } - var compressedAssets = assetsById.Values.Where(a => a.AssetTraitName == "Content-Encoding").ToList(); - var updatedEndpoints = new HashSet(StaticWebAssetEndpoint.RouteAndAssetComparer); + assetsById[candidate.Identity] = candidate; + if (string.Equals(candidate.AssetTraitName, "Content-Encoding", StringComparison.Ordinal)) + { + compressedAssets.Add(candidate); + } + } + var endpointsByAsset = new Dictionary>(CandidateEndpoints.Length, StringComparer.OrdinalIgnoreCase); + for (var i = 0; i < CandidateEndpoints.Length; i++) + { + var endpoint = StaticWebAssetEndpoint.FromTaskItem(CandidateEndpoints[i]); + if (!endpointsByAsset.TryGetValue(endpoint.AssetFile, out var endpoints)) + { + endpoints = []; + endpointsByAsset[endpoint.AssetFile] = endpoints; + } + endpoints.Add(endpoint); + } + + var updatedEndpoints = new HashSet(StaticWebAssetEndpoint.RouteAndAssetComparer); var preservedEndpoints = new Dictionary<(string, string), StaticWebAssetEndpoint>(); // Add response headers to compressed endpoints @@ -52,20 +76,20 @@ public override bool Execute() { if (!assetsById.TryGetValue(compressedAsset.RelatedAsset, out var relatedAsset)) { - Log.LogWarning("Related asset not found for compressed asset: {0}", compressedAsset.Identity); - throw new InvalidOperationException($"Related asset not found for compressed asset: {compressedAsset.Identity}"); + Log.LogWarning("Related asset '{0}' not found for compressed asset: '{1}'. Skipping asset", compressedAsset.RelatedAsset, compressedAsset.Identity); + continue; } if (!endpointsByAsset.TryGetValue(compressedAsset.Identity, out var compressedEndpoints)) { - Log.LogWarning("Endpoints not found for compressed asset: {0} {1}", compressedAsset.RelativePath, compressedAsset.Identity); - throw new InvalidOperationException($"Endpoints not found for compressed asset: {compressedAsset.Identity}"); + Log.LogWarning("Endpoints not found for compressed asset: '{0}' '{1}'. Skipping asset", compressedAsset.RelativePath, compressedAsset.Identity); + continue; } if (!endpointsByAsset.TryGetValue(relatedAsset.Identity, out var relatedAssetEndpoints)) { - Log.LogWarning("Endpoints not found for related asset: {0}", relatedAsset.Identity); - throw new InvalidOperationException($"Endpoints not found for related asset: {relatedAsset.Identity}"); + Log.LogWarning("Endpoints not found for related asset: '{0}'. Skipping asset", relatedAsset.Identity); + continue; } Log.LogMessage("Processing compressed asset: {0}", compressedAsset.Identity); diff --git a/src/StaticWebAssetsSdk/Tasks/Compression/DiscoverPrecompressedAssets.cs b/src/StaticWebAssetsSdk/Tasks/Compression/DiscoverPrecompressedAssets.cs index ac72dd936950..71e8b884033e 100644 --- a/src/StaticWebAssetsSdk/Tasks/Compression/DiscoverPrecompressedAssets.cs +++ b/src/StaticWebAssetsSdk/Tasks/Compression/DiscoverPrecompressedAssets.cs @@ -30,7 +30,19 @@ public override bool Execute() var candidates = CandidateAssets.Select(StaticWebAsset.FromTaskItem).ToArray(); var assetsToUpdate = new List(); - var candidatesByIdentity = candidates.ToDictionary(asset => asset.Identity, OSPath.PathComparer); + var candidatesByIdentity = new Dictionary(CandidateAssets.Length, OSPath.PathComparer); + for (var i = 0; i < candidates.Length; i++) + { + var candidate = candidates[i]; + if (candidatesByIdentity.ContainsKey(candidate.Identity)) + { + Log.LogMessage(MessageImportance.Low, + "Detected duplicated asset '{0}'. Skipping the asset because it was already processed.", + candidate.Identity); + return false; + } + candidatesByIdentity[candidate.Identity] = candidate; + } foreach (var candidate in candidates) {