-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[Static Web Assets] Fix compressed endpoint headers #41511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,7 @@ public override bool Execute() | |
.ToDictionary(g => g.Key, g => g.ToList()); | ||
|
||
var compressedAssets = assetsById.Values.Where(a => a.AssetTraitName == "Content-Encoding").ToList(); | ||
var updatedEndpoints = new List<StaticWebAssetEndpoint>(); | ||
var updatedEndpoints = new HashSet<StaticWebAssetEndpoint>(StaticWebAssetEndpoint.RouteAndAssetComparer); | ||
|
||
var preservedEndpoints = new Dictionary<(string, string), StaticWebAssetEndpoint>(); | ||
|
||
|
@@ -89,13 +89,14 @@ public override bool Execute() | |
} | ||
|
||
Log.LogMessage(MessageImportance.Low, " Updated endpoint '{0}' with Content-Encoding and Vary headers", compressedEndpoint.Route); | ||
if (!updatedEndpoints.Contains(compressedEndpoint)) | ||
{ | ||
updatedEndpoints.Add(compressedEndpoint); | ||
} | ||
updatedEndpoints.Add(compressedEndpoint); | ||
|
||
foreach (var relatedEndpointCandidate in relatedAssetEndpoints) | ||
{ | ||
if (!IsCompatible(compressedEndpoint, relatedEndpointCandidate)) | ||
{ | ||
continue; | ||
} | ||
Comment on lines
+96
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We were copying the related endpoint and applying a selector + the compressed endpoint properties. That caused for example that we created a fingerprinted endpoint using a non-fingerprinted compressed endpoint. To address that, we check that both endpoints have or don't have fingerprint and in case of having it, they match. This way the fingerprinted endpoint we create for content-negotiation has the same headers as the fingerprinted compressed endpoint. |
||
Log.LogMessage(MessageImportance.Low, "Processing related endpoint '{0}'", relatedEndpointCandidate.Route); | ||
var encodingSelector = new StaticWebAssetEndpointSelector | ||
{ | ||
|
@@ -188,7 +189,10 @@ public override bool Execute() | |
{ | ||
Log.LogMessage(MessageImportance.Low, " Adding endpoint '{0}'", endpoint.AssetFile); | ||
} | ||
updatedEndpoints.AddRange(endpoints); | ||
foreach (var endpoint in endpoints) | ||
{ | ||
updatedEndpoints.Add(endpoint); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -197,6 +201,13 @@ public override bool Execute() | |
return true; | ||
} | ||
|
||
private static bool IsCompatible(StaticWebAssetEndpoint compressedEndpoint, StaticWebAssetEndpoint relatedEndpointCandidate) | ||
{ | ||
var compressedFingerprint = compressedEndpoint.EndpointProperties.FirstOrDefault(ep => ep.Name == "fingerprint"); | ||
var relatedFingerprint = relatedEndpointCandidate.EndpointProperties.FirstOrDefault(ep => ep.Name == "fingerprint"); | ||
return string.Equals(compressedFingerprint?.Value, relatedFingerprint?.Value, StringComparison.Ordinal); | ||
} | ||
|
||
private void ApplyCompressedEndpointHeaders(List<StaticWebAssetEndpointResponseHeader> headers, StaticWebAssetEndpoint compressedEndpoint, string relatedEndpointCandidateRoute) | ||
{ | ||
foreach (var header in compressedEndpoint.ResponseHeaders) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -190,6 +190,8 @@ public static StaticWebAssetPathPattern Parse(string rawPath, string assetIdenti | |
} | ||
else if (!string.IsNullOrEmpty(part.Value)) | ||
{ | ||
// Token was embedded, so add it to the dictionary. | ||
dictionary[part.Name] = part.Value; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When the token was embedded in the expression (for example, |
||
result.Append(part.Value); | ||
} | ||
else | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The combination of route + asset file is unique, when we have fingerprinting expressions more than one endpoint is associated with a given compressed asset, so we need to make sure we don't add it multiple times.
Using a HashSet is simpler and better than using a list, also, in this case we need to avoid comparing using the headers and properties because those will be different.