IPC: Implement ResponseCaching

This actually does two things: client caching and server caching

Client caching considers only static files, for which we instruct the web browser to revalidate each cache usage with our server to ensure that it's up-to-date.

Server caching with those settings actually doesn't work (nothing to do), but may in the future as lack of no-store means that server is technically allowed to cache I/O read files for as long as it can guarantee they didn't change on the disk.
This commit is contained in:
Archi
2021-07-04 21:36:54 +02:00
parent f58a9be02a
commit 28242aa6e8
3 changed files with 30 additions and 5 deletions

View File

@@ -39,6 +39,7 @@
<PackageReference Include="Microsoft.AspNetCore.Cors" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" />
<PackageReference Include="Microsoft.AspNetCore.HttpOverrides" />
<PackageReference Include="Microsoft.AspNetCore.ResponseCaching" />
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" />
<PackageReference Include="Microsoft.AspNetCore.WebSockets" />

View File

@@ -83,6 +83,11 @@ namespace ArchiSteamFarm.IPC {
// Add support for proxies, this one comes usually after developer exception page, but could be before
app.UseForwardedHeaders();
if (ASF.GlobalConfig?.OptimizationMode != GlobalConfig.EOptimizationMode.MinMemoryUsage) {
// Add support for response caching - must be called before static files as we want to cache those as well
app.UseResponseCaching();
}
// Add support for response compression - must be called before static files as we want to compress those as well
app.UseResponseCompression();
@@ -105,21 +110,34 @@ namespace ArchiSteamFarm.IPC {
app.UseStaticFiles(
new StaticFileOptions {
OnPrepareResponse = context => {
// Add support for SRI-protected static files
if (context.File.Exists && !context.File.IsDirectory && !string.IsNullOrEmpty(context.File.Name)) {
string extension = Path.GetExtension(context.File.Name);
CacheControlHeaderValue cacheControl = new();
switch (extension.ToUpperInvariant()) {
case ".CSS":
case ".JS":
ResponseHeaders headers = context.Context.Response.GetTypedHeaders();
// Add support for SRI-protected static files
// SRI requires from us to notify the caller (especially proxy) to avoid modifying the data
cacheControl.NoTransform = true;
headers.CacheControl = new CacheControlHeaderValue {
NoTransform = true
};
goto default;
default:
// Instruct the caller to always ask us first about every file it requests
// Contrary to the name, this doesn't prevent client from caching, but rather informs it that it must verify with us first that his cache is still up-to-date
// This is used to handle ASF and user updates to WWW root, we don't want from the client to ever use outdated scripts
cacheControl.NoCache = true;
// All static files are public by definition, we don't have any authorization here
cacheControl.Public = true;
break;
}
ResponseHeaders headers = context.Context.Response.GetTypedHeaders();
headers.CacheControl = cacheControl;
}
}
}
@@ -208,6 +226,11 @@ namespace ArchiSteamFarm.IPC {
}
);
if (ASF.GlobalConfig?.OptimizationMode != GlobalConfig.EOptimizationMode.MinMemoryUsage) {
// Add support for response caching
services.AddResponseCaching();
}
// Add support for response compression
services.AddResponseCompression();

View File

@@ -33,6 +33,7 @@
<PackageVersion Include="Microsoft.AspNetCore.Diagnostics" Version="2.2.0" />
<PackageVersion Include="Microsoft.AspNetCore.HttpOverrides" Version="2.2.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageVersion Include="Microsoft.AspNetCore.ResponseCaching" Version="2.2.0" />
<PackageVersion Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
<PackageVersion Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
<PackageVersion Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />