using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Headers; using Microsoft.Extensions.Options; using Microsoft.Net.Http.Headers; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Web.Commands; using SixLabors.ImageSharp.Web.Middleware; using SixLabors.ImageSharp.Web.Processors; using Umbraco.Cms.Core.Configuration.Models; namespace Umbraco.Cms.Web.Common.DependencyInjection { /// /// Configures the ImageSharp middleware options. /// /// public sealed class ConfigureImageSharpMiddlewareOptions : IConfigureOptions { private readonly Configuration _configuration; private readonly ImagingSettings _imagingSettings; /// /// Initializes a new instance of the class. /// /// The ImageSharp configuration. /// The Umbraco imaging settings. public ConfigureImageSharpMiddlewareOptions(Configuration configuration, IOptions imagingSettings) { _configuration = configuration; _imagingSettings = imagingSettings.Value; } /// public void Configure(ImageSharpMiddlewareOptions options) { options.Configuration = _configuration; options.BrowserMaxAge = _imagingSettings.Cache.BrowserMaxAge; options.CacheMaxAge = _imagingSettings.Cache.CacheMaxAge; options.CacheHashLength = _imagingSettings.Cache.CacheHashLength; // Use configurable maximum width and height options.OnParseCommandsAsync = context => { if (context.Commands.Count == 0) { return Task.CompletedTask; } int width = context.Parser.ParseValue(context.Commands.GetValueOrDefault(ResizeWebProcessor.Width), context.Culture); if (width <= 0 || width > _imagingSettings.Resize.MaxWidth) { context.Commands.Remove(ResizeWebProcessor.Width); } int height = context.Parser.ParseValue(context.Commands.GetValueOrDefault(ResizeWebProcessor.Height), context.Culture); if (height <= 0 || height > _imagingSettings.Resize.MaxHeight) { context.Commands.Remove(ResizeWebProcessor.Height); } return Task.CompletedTask; }; // Change Cache-Control header when cache buster value is present options.OnPrepareResponseAsync = context => { if (context.Request.Query.ContainsKey("rnd") || context.Request.Query.ContainsKey("v")) { ResponseHeaders headers = context.Response.GetTypedHeaders(); CacheControlHeaderValue cacheControl = headers.CacheControl ?? new CacheControlHeaderValue() { Public = true }; cacheControl.MustRevalidate = false; // ImageSharp enables this by default cacheControl.Extensions.Add(new NameValueHeaderValue("immutable")); headers.CacheControl = cacheControl; } return Task.CompletedTask; }; } } }