-
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
.avifand.epubWith
.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-Allowedresponse 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
.csprojproperties. For example,appsettings.jsoncould 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
IFileCompressorinterface, 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.jsfile withgzencoding, the middleware (.UseStaticFiles()perhaps?) could cache the compressed response in ascript.js.gzfile 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.