Skip to content

Commit 51838a2

Browse files
authored
[Blazor] Adds compresion support for all assets in an application (#55558)
Adds a new MapStaticAssetEndpoints routerware that reads a manifest generated at build / publish time and maps the endpoints defined in the manifest to the files in the application wwwroot folder. Adds a MatcherPolicy to perform content negotiation based on the Accept-Encoding header. Compressed resources contain a ContentEncoding attribute in their metadata that is used to filter out the compressed asset to serve to the client based on the Accept-Encoding header. The content encoding has an associated Quality value that represents the 'server preference' for the encoding. We always use the client preference and only rely on the server preference to break ties. This process is completely driven by de the build and transparent to the runtime, if in the future we add support for zstd, sbr, etc. we don't need to change the runtime. The logic for serving static files is borrowed from the static files middleware, with simplifications and additions. I've ported the relevant tests to ensure a high degree of compatibility. The logic is new "routerware" instead of directly baked into the static files middleware because we do not want to pollute that middleware with more complex logic and we are going to be layering fingerprinting on top of this change, which will register more endpoints that will include more custom headers, which is not suitable for the static files middleware. During development we wrap the endpoints we generate to support changing the files while the app is running (we recompute some of the values on the fly and also register a fallback route that matches file patterns to serve new files added while the app is running). The build/publish process computes all the required information about the assets that is used to emit the response. The ETag and Last-Modified values are computed using the Base64(SHA256) hash of the content and the LastWrite on the file at build/publish time.
1 parent 0b59b2c commit 51838a2

File tree

68 files changed

+3817
-50
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+3817
-50
lines changed

AspNetCore.sln

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,6 +1806,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.OpenAp
18061806
EndProject
18071807
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KeyManagementSimulator", "src\DataProtection\samples\KeyManagementSimulator\KeyManagementSimulator.csproj", "{5B5F86CC-3598-463C-9F9B-F78FBB6642F4}"
18081808
EndProject
1809+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StaticAssets", "StaticAssets", "{274100A5-5B2D-4EA2-AC42-A62257FC6BDC}"
1810+
EndProject
1811+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.StaticAssets", "src\StaticAssets\src\Microsoft.AspNetCore.StaticAssets.csproj", "{4D8DE54A-4F32-4881-B07B-DDC79619E573}"
1812+
EndProject
1813+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.StaticAssets.Tests", "src\StaticAssets\test\Microsoft.AspNetCore.StaticAssets.Tests.csproj", "{9536C284-65B4-4884-BB50-06D629095C3E}"
1814+
EndProject
18091815
Global
18101816
GlobalSection(SolutionConfigurationPlatforms) = preSolution
18111817
Debug|Any CPU = Debug|Any CPU
@@ -10903,6 +10909,38 @@ Global
1090310909
{5B5F86CC-3598-463C-9F9B-F78FBB6642F4}.Release|x64.Build.0 = Release|Any CPU
1090410910
{5B5F86CC-3598-463C-9F9B-F78FBB6642F4}.Release|x86.ActiveCfg = Release|Any CPU
1090510911
{5B5F86CC-3598-463C-9F9B-F78FBB6642F4}.Release|x86.Build.0 = Release|Any CPU
10912+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
10913+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Debug|Any CPU.Build.0 = Debug|Any CPU
10914+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Debug|arm64.ActiveCfg = Debug|Any CPU
10915+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Debug|arm64.Build.0 = Debug|Any CPU
10916+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Debug|x64.ActiveCfg = Debug|Any CPU
10917+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Debug|x64.Build.0 = Debug|Any CPU
10918+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Debug|x86.ActiveCfg = Debug|Any CPU
10919+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Debug|x86.Build.0 = Debug|Any CPU
10920+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Release|Any CPU.ActiveCfg = Release|Any CPU
10921+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Release|Any CPU.Build.0 = Release|Any CPU
10922+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Release|arm64.ActiveCfg = Release|Any CPU
10923+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Release|arm64.Build.0 = Release|Any CPU
10924+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Release|x64.ActiveCfg = Release|Any CPU
10925+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Release|x64.Build.0 = Release|Any CPU
10926+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Release|x86.ActiveCfg = Release|Any CPU
10927+
{4D8DE54A-4F32-4881-B07B-DDC79619E573}.Release|x86.Build.0 = Release|Any CPU
10928+
{9536C284-65B4-4884-BB50-06D629095C3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
10929+
{9536C284-65B4-4884-BB50-06D629095C3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
10930+
{9536C284-65B4-4884-BB50-06D629095C3E}.Debug|arm64.ActiveCfg = Debug|Any CPU
10931+
{9536C284-65B4-4884-BB50-06D629095C3E}.Debug|arm64.Build.0 = Debug|Any CPU
10932+
{9536C284-65B4-4884-BB50-06D629095C3E}.Debug|x64.ActiveCfg = Debug|Any CPU
10933+
{9536C284-65B4-4884-BB50-06D629095C3E}.Debug|x64.Build.0 = Debug|Any CPU
10934+
{9536C284-65B4-4884-BB50-06D629095C3E}.Debug|x86.ActiveCfg = Debug|Any CPU
10935+
{9536C284-65B4-4884-BB50-06D629095C3E}.Debug|x86.Build.0 = Debug|Any CPU
10936+
{9536C284-65B4-4884-BB50-06D629095C3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
10937+
{9536C284-65B4-4884-BB50-06D629095C3E}.Release|Any CPU.Build.0 = Release|Any CPU
10938+
{9536C284-65B4-4884-BB50-06D629095C3E}.Release|arm64.ActiveCfg = Release|Any CPU
10939+
{9536C284-65B4-4884-BB50-06D629095C3E}.Release|arm64.Build.0 = Release|Any CPU
10940+
{9536C284-65B4-4884-BB50-06D629095C3E}.Release|x64.ActiveCfg = Release|Any CPU
10941+
{9536C284-65B4-4884-BB50-06D629095C3E}.Release|x64.Build.0 = Release|Any CPU
10942+
{9536C284-65B4-4884-BB50-06D629095C3E}.Release|x86.ActiveCfg = Release|Any CPU
10943+
{9536C284-65B4-4884-BB50-06D629095C3E}.Release|x86.Build.0 = Release|Any CPU
1090610944
EndGlobalSection
1090710945
GlobalSection(SolutionProperties) = preSolution
1090810946
HideSolutionNode = FALSE
@@ -11795,6 +11833,9 @@ Global
1179511833
{9DC6B242-457B-4767-A84B-C3D23B76C642} = {2299CCD8-8F9C-4F2B-A633-9BF4DA81022B}
1179611834
{D53F0EF7-0CDC-49B4-AA2D-229901B0A734} = {9DC6B242-457B-4767-A84B-C3D23B76C642}
1179711835
{5B5F86CC-3598-463C-9F9B-F78FBB6642F4} = {8275510E-0E6C-45A8-99DF-4F106BC7F075}
11836+
{274100A5-5B2D-4EA2-AC42-A62257FC6BDC} = {017429CC-C5FB-48B4-9C46-034E29EE2F06}
11837+
{4D8DE54A-4F32-4881-B07B-DDC79619E573} = {274100A5-5B2D-4EA2-AC42-A62257FC6BDC}
11838+
{9536C284-65B4-4884-BB50-06D629095C3E} = {274100A5-5B2D-4EA2-AC42-A62257FC6BDC}
1179811839
EndGlobalSection
1179911840
GlobalSection(ExtensibilityGlobals) = postSolution
1180011841
SolutionGuid = {3E8720B3-DBDD-498C-B383-2CC32A054E8F}

eng/Build.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@
174174
$(RepoRoot)src\Mvc\**\*.*proj;
175175
$(RepoRoot)src\Azure\**\*.*proj;
176176
$(RepoRoot)src\SignalR\**\*.csproj;
177+
$(RepoRoot)src\StaticAssets\**\*.csproj;
177178
$(RepoRoot)src\Components\**\*.csproj;
178179
$(RepoRoot)src\Analyzers\**\*.csproj;
179180
$(RepoRoot)src\FileProviders\**\*.csproj;
@@ -219,6 +220,7 @@
219220
$(RepoRoot)src\Mvc\**\src\*.csproj;
220221
$(RepoRoot)src\Azure\**\src\*.csproj;
221222
$(RepoRoot)src\SignalR\**\src\*.csproj;
223+
$(RepoRoot)src\StaticAssets\src\*.csproj;
222224
$(RepoRoot)src\Components\**\src\*.csproj;
223225
$(RepoRoot)src\FileProviders\**\src\*.csproj;
224226
$(RepoRoot)src\Configuration.KeyPerFile\**\src\*.csproj;

eng/ProjectReferences.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139
<ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR" ProjectPath="$(RepoRoot)src\SignalR\server\SignalR\src\Microsoft.AspNetCore.SignalR.csproj" />
140140
<ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR.Specification.Tests" ProjectPath="$(RepoRoot)src\SignalR\server\Specification.Tests\src\Microsoft.AspNetCore.SignalR.Specification.Tests.csproj" />
141141
<ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" ProjectPath="$(RepoRoot)src\SignalR\server\StackExchangeRedis\src\Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj" />
142+
<ProjectReferenceProvider Include="Microsoft.AspNetCore.StaticAssets" ProjectPath="$(RepoRoot)src\StaticAssets\src\Microsoft.AspNetCore.StaticAssets.csproj" />
142143
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Components.Authorization" ProjectPath="$(RepoRoot)src\Components\Authorization\src\Microsoft.AspNetCore.Components.Authorization.csproj" />
143144
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Components" ProjectPath="$(RepoRoot)src\Components\Components\src\Microsoft.AspNetCore.Components.csproj" />
144145
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Components.CustomElements" ProjectPath="$(RepoRoot)src\Components\CustomElements\src\Microsoft.AspNetCore.Components.CustomElements.csproj" />

eng/SharedFramework.Local.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
<AspNetCoreAppReference Include="Microsoft.AspNetCore.Http.Connections" />
108108
<AspNetCoreAppReference Include="Microsoft.AspNetCore.SignalR.Core" />
109109
<AspNetCoreAppReference Include="Microsoft.AspNetCore.SignalR" />
110+
<AspNetCoreAppReference Include="Microsoft.AspNetCore.StaticAssets" />
110111
<AspNetCoreAppReference Include="Microsoft.AspNetCore.Components.Endpoints" />
111112
<AspNetCoreAppReference Include="Microsoft.AspNetCore.Components.Server" />
112113
</ItemGroup>

eng/ShippingAssemblies.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
<AspNetCoreShippingAssembly Include="Microsoft.AspNetCore.SignalR.Common" />
8989
<AspNetCoreShippingAssembly Include="Microsoft.AspNetCore.SignalR.Core" />
9090
<AspNetCoreShippingAssembly Include="Microsoft.AspNetCore.SignalR" />
91+
<AspNetCoreShippingAssembly Include="Microsoft.AspNetCore.StaticAssets" />
9192
<AspNetCoreShippingAssembly Include="Microsoft.AspNetCore.Components.Authorization" />
9293
<AspNetCoreShippingAssembly Include="Microsoft.AspNetCore.Components" />
9394
<AspNetCoreShippingAssembly Include="Microsoft.AspNetCore.Components.Endpoints" />

eng/TrimmableProjects.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
<TrimmableProject Include="Microsoft.AspNetCore.Http.Connections.Common" />
8989
<TrimmableProject Include="Microsoft.AspNetCore.Http.Connections" />
9090
<TrimmableProject Include="Microsoft.AspNetCore.SignalR.Common" />
91+
<TrimmableProject Include="Microsoft.AspNetCore.StaticAssets" />
9192
<TrimmableProject Include="Microsoft.AspNetCore.Components.Authorization" />
9293
<TrimmableProject Include="Microsoft.AspNetCore.Components" />
9394
<TrimmableProject Include="Microsoft.AspNetCore.Components.CustomElements" />

global.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"sdk": {
3-
"version": "9.0.100-preview.5.24229.2"
3+
"version": "9.0.100-preview.5.24253.17"
44
},
55
"tools": {
6-
"dotnet": "9.0.100-preview.5.24229.2",
6+
"dotnet": "9.0.100-preview.5.24253.17",
77
"runtimes": {
88
"dotnet/x86": [
99
"$(MicrosoftNETCoreBrowserDebugHostTransportVersion)"

src/Components/Components.slnf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
"src\\Components\\WebAssembly\\Authentication.Msal\\src\\Microsoft.Authentication.WebAssembly.Msal.csproj",
2626
"src\\Components\\WebAssembly\\DevServer\\src\\Microsoft.AspNetCore.Components.WebAssembly.DevServer.csproj",
2727
"src\\Components\\WebAssembly\\JSInterop\\src\\Microsoft.JSInterop.WebAssembly.csproj",
28+
"src\\Components\\WebAssembly\\Samples\\HostedBlazorWebassemblyApp\\Client\\HostedBlazorWebassemblyApp.Client.csproj",
29+
"src\\Components\\WebAssembly\\Samples\\HostedBlazorWebassemblyApp\\Server\\HostedBlazorWebassemblyApp.Server.csproj",
30+
"src\\Components\\WebAssembly\\Samples\\HostedBlazorWebassemblyApp\\Shared\\HostedBlazorWebassemblyApp.Shared.csproj",
2831
"src\\Components\\WebAssembly\\Server\\src\\Microsoft.AspNetCore.Components.WebAssembly.Server.csproj",
2932
"src\\Components\\WebAssembly\\Server\\test\\Microsoft.AspNetCore.Components.WebAssembly.Server.Tests.csproj",
3033
"src\\Components\\WebAssembly\\WebAssembly.Authentication\\src\\Microsoft.AspNetCore.Components.WebAssembly.Authentication.csproj",
@@ -145,6 +148,8 @@
145148
"src\\SignalR\\common\\SignalR.Common\\src\\Microsoft.AspNetCore.SignalR.Common.csproj",
146149
"src\\SignalR\\server\\Core\\src\\Microsoft.AspNetCore.SignalR.Core.csproj",
147150
"src\\SignalR\\server\\SignalR\\src\\Microsoft.AspNetCore.SignalR.csproj",
151+
"src\\StaticAssets\\src\\Microsoft.AspNetCore.StaticAssets.csproj",
152+
"src\\StaticAssets\\test\\Microsoft.AspNetCore.StaticAssets.Tests.csproj",
148153
"src\\Testing\\src\\Microsoft.AspNetCore.InternalTesting.csproj",
149154
"src\\WebEncoders\\src\\Microsoft.Extensions.WebEncoders.csproj"
150155
]

src/Components/Endpoints/src/Builder/ComponentEndpointConventionBuilderHelper.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using Microsoft.AspNetCore.Builder;
5+
using Microsoft.AspNetCore.Routing;
56

67
namespace Microsoft.AspNetCore.Components.Endpoints.Infrastructure;
78

@@ -19,5 +20,11 @@ public static void AddRenderMode(RazorComponentsEndpointConventionBuilder builde
1920
{
2021
builder.AddRenderMode(renderMode);
2122
}
23+
24+
/// <summary>
25+
/// This method is not recommended for use outside of the Blazor framework.
26+
/// </summary>
27+
/// <param name="builder"></param>
28+
public static IEndpointRouteBuilder GetEndpointRouteBuilder(RazorComponentsEndpointConventionBuilder builder) => builder.EndpointRouteBuilder;
2229
}
2330

src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,20 @@ internal class RazorComponentEndpointDataSource<[DynamicallyAccessedMembers(Comp
3939
public RazorComponentEndpointDataSource(
4040
ComponentApplicationBuilder builder,
4141
IEnumerable<RenderModeEndpointProvider> renderModeEndpointProviders,
42-
IApplicationBuilder applicationBuilder,
42+
IEndpointRouteBuilder endpointRouteBuilder,
4343
RazorComponentEndpointFactory factory,
4444
HotReloadService? hotReloadService = null)
4545
{
4646
_builder = builder;
47-
_applicationBuilder = applicationBuilder;
47+
_applicationBuilder = endpointRouteBuilder.CreateApplicationBuilder();
4848
_renderModeEndpointProviders = renderModeEndpointProviders.ToArray();
4949
_factory = factory;
5050
_hotReloadService = hotReloadService;
5151
HotReloadService.ClearCacheEvent += OnHotReloadClearCache;
5252
DefaultBuilder = new RazorComponentsEndpointConventionBuilder(
5353
_lock,
5454
builder,
55+
endpointRouteBuilder,
5556
_options,
5657
_conventions,
5758
_finallyConventions);

0 commit comments

Comments
 (0)