-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Is there an existing issue for this?
- I have searched the existing issues
Is your feature request related to a problem? Please describe the problem.
-
I'm trying to serve non-standard files, like
.avif
and.epub
With
.UseStaticFiles()
it's very easy to do:var extensionsProvider = new FileExtensionContentTypeProvider(); extensionsProvider.Mappings.Add(".bar", "foo/bar"); app.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = extensionsProvider, });
With
.MapStaticAssets()
it's not possible, as far as I can tell. -
I'm trying to add ZStandard compression.
With
.UseStaticFiles()
it's fairly easy to do, for example using code yoinked from here:services.AddResponseCompression(options => { options.Providers.Add<ZstdCompressionProvider>(); options.Providers.Add<BrotliCompressionProvider>(); options.Providers.Add<GzipCompressionProvider>(); }) .Configure<ZstdCompressionProvider.Options>(o => o.CompressionLevel = CompressionLevel.Optimal);
With
.MapStaticAssets()
it's not possible, as far as I can tell. -
I'm trying to serve service workers, which might require a
Service-Worker-Allowed
response header.With
.UseStaticFiles()
it's pretty trivial as well:app.UseStaticFiles(new StaticFileOptions { OnPrepareResponse = ctx => { if (ctx.File.Name.Contains("worker") { ctx.Context.Response.Headers.Append("Service-Worker-Allowed", "/"); } }, });
With
.MapStaticAssets()
it's not possible, as far as I can tell.
Describe the solution you'd like
Since .MapStaticAssets()
works on build-time, adding customization options is tricky. I see two ways to go about it:
-
Some basic customization can probably be achieved via some settings file or
.csproj
properties. For example,appsettings.json
could get a section like{ "ConfigureStaticFiles": { "ContentTypes": { ".foo": "foo/bar", ".avif": "image/avif" }, "ExtraHeaders": { "**/*.worker.js": { "Service-Worker-Allowed": "/" } } } }
which could then be read on build-time, and the settings could be used in the generated manifest as they are.
Any more advanced settings like custom compression algorithms (forementioned ZStandard) would not be easy to achieve this way. We'd have to encroach on a weird DSL territory, specifying the compression class as a JSON string or something. That said, for completness' sake, let's say it could look like this:
{ "ConfigureStaticFiles": { "FileCompression": [ "MyProject.Infrastructure.ZStandardCompressor", "brotli", "gzip" ] } }
With the compressor being defined by some
IFileCompressor
interface, likeinterface IFileCompressor { byte[] Compress(byte[] file); }
-
Precompression should be done on startup or first access, not build time.
Compressing all files on startup could increase startup times a fair bit, but compressing them on first access should be fine. First time the browser requests a
script.js
file withgz
encoding, the middleware (.UseStaticFiles()
perhaps?) could cache the compressed response in ascript.js.gz
file and just serve that next time it is requested.That way, any more advanced config could be defined not unlike it is being defined now. The only difference would be that it doesn't run on every request.