From 59d0d383e936237ba8f38da70e23a478d3a46537 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Tue, 8 Apr 2025 00:00:09 +0200 Subject: [PATCH] Add compression. (#1210) --- backend/src/Squidex.Web/CompressionOptions.cs | 21 ++++++++++++ .../src/Squidex/Config/Web/WebExtensions.cs | 34 ++++++++++++------- backend/src/Squidex/Config/Web/WebServices.cs | 27 +++++++++++++++ backend/src/Squidex/Startup.cs | 6 ++-- backend/src/Squidex/appsettings.json | 18 ++++++++++ 5 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 backend/src/Squidex.Web/CompressionOptions.cs diff --git a/backend/src/Squidex.Web/CompressionOptions.cs b/backend/src/Squidex.Web/CompressionOptions.cs new file mode 100644 index 000000000..a5c8fbf00 --- /dev/null +++ b/backend/src/Squidex.Web/CompressionOptions.cs @@ -0,0 +1,21 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.IO.Compression; + +namespace Squidex.Web; + +public class CompressionOptions +{ + public bool Enabled { get; set; } + + public bool EnableForHttps { get; set; } + + public CompressionLevel LevelGzip { get; set; } = CompressionLevel.Fastest; + + public CompressionLevel LevelBrotli { get; set; } = CompressionLevel.Fastest; +} diff --git a/backend/src/Squidex/Config/Web/WebExtensions.cs b/backend/src/Squidex/Config/Web/WebExtensions.cs index 5e55962ff..5f0846c15 100644 --- a/backend/src/Squidex/Config/Web/WebExtensions.cs +++ b/backend/src/Squidex/Config/Web/WebExtensions.cs @@ -7,9 +7,11 @@ using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Options; using Microsoft.Net.Http.Headers; using Squidex.Infrastructure.Json; using Squidex.Pipeline.Robots; +using Squidex.Web; using Squidex.Web.Pipeline; namespace Squidex.Config.Web; @@ -19,14 +21,12 @@ public static class WebExtensions public static IApplicationBuilder UseSquidexCacheKeys(this IApplicationBuilder app) { app.UseMiddleware(); - return app; } public static IApplicationBuilder UseSquidexLocalCache(this IApplicationBuilder app) { app.UseMiddleware(); - return app; } @@ -40,28 +40,30 @@ public static class WebExtensions .AddSupportedUICultures(supportedCultures); app.UseRequestLocalization(localizationOptions); - return app; } public static IApplicationBuilder UseSquidexLogging(this IApplicationBuilder app) { app.UseMiddleware(); - return app; } public static IApplicationBuilder UseSquidexUsage(this IApplicationBuilder app) { app.UseMiddleware(); - return app; } public static IApplicationBuilder UseSquidexExceptionHandling(this IApplicationBuilder app) { app.UseMiddleware(); + return app; + } + public static IApplicationBuilder UseSquidexRobotsTxt(this IApplicationBuilder app) + { + app.Map("/robots.txt", builder => builder.UseMiddleware()); return app; } @@ -117,19 +119,25 @@ public static class WebExtensions return app; } - public static IApplicationBuilder UseSquidexRobotsTxt(this IApplicationBuilder app) - { - app.Map("/robots.txt", builder => builder.UseMiddleware()); - - return app; - } - - public static void UseSquidexCors(this IApplicationBuilder app) + public static IApplicationBuilder UseSquidexCors(this IApplicationBuilder app) { app.UseCors(builder => builder .SetIsOriginAllowed(x => true) .AllowCredentials() .AllowAnyMethod() .AllowAnyHeader()); + + return app; + } + + public static IApplicationBuilder UseSquidexCompression(this IApplicationBuilder app) + { + var compressionOptions = app.ApplicationServices.GetRequiredService>().Value; + if (compressionOptions.Enabled) + { + app.UseResponseCompression(); + } + + return app; } } diff --git a/backend/src/Squidex/Config/Web/WebServices.cs b/backend/src/Squidex/Config/Web/WebServices.cs index 1e86f8cc8..748013a9d 100644 --- a/backend/src/Squidex/Config/Web/WebServices.cs +++ b/backend/src/Squidex/Config/Web/WebServices.cs @@ -11,6 +11,7 @@ using GraphQL.Server.Transports.AspNetCore; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.AspNetCore.ResponseCompression; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; using Squidex.Config.Domain; @@ -31,6 +32,9 @@ public static class WebServices { public static void AddSquidexMvcWithPlugins(this IServiceCollection services, IConfiguration config) { + services.Configure(config, + "compression"); + services.AddSingletonAs(c => new ExposedValues(c.GetRequiredService>().Value, config, typeof(WebServices).Assembly)) .AsSelf(); @@ -79,6 +83,29 @@ public static class WebServices .AutoCleanup() .AddWebSockets(); + services.Configure((services, options) => + { + var compressionOptions = services.GetRequiredService>().Value; + + options.EnableForHttps = compressionOptions.EnableForHttps; + }); + + services.Configure((services, options) => + { + var compressionOptions = services.GetRequiredService>().Value; + + options.Level = compressionOptions.LevelBrotli; + }); + + services.Configure((services, options) => + { + var compressionOptions = services.GetRequiredService>().Value; + + options.Level = compressionOptions.LevelGzip; + }); + + services.AddResponseCompression(); + services.AddMvc(options => { // Never change this order here. diff --git a/backend/src/Squidex/Startup.cs b/backend/src/Squidex/Startup.cs index e7709c876..44aeb1e68 100644 --- a/backend/src/Squidex/Startup.cs +++ b/backend/src/Squidex/Startup.cs @@ -71,16 +71,18 @@ public sealed class Startup(IConfiguration config) public void Configure(IApplicationBuilder app) { + app.UseWebSockets(); app.UseCookiePolicy(); app.UseDefaultPathBase(); app.UseDefaultForwardRules(); - app.UseSquidexHealthCheck(); - app.UseSquidexRobotsTxt(); app.UseSquidexLogging(); app.UseSquidexLocalization(); app.UseSquidexLocalCache(); app.UseSquidexCors(); + app.UseSquidexCompression(); + app.UseSquidexHealthCheck(); + app.UseSquidexRobotsTxt(); app.UseOpenApi(options => { diff --git a/backend/src/Squidex/appsettings.json b/backend/src/Squidex/appsettings.json index 7fe226c87..9823fd2c2 100644 --- a/backend/src/Squidex/appsettings.json +++ b/backend/src/Squidex/appsettings.json @@ -4,6 +4,24 @@ "isReadonly": false }, + "compression": { + // Indicates if responses over HTTPS connections should be compressed. + "enableForHttps": true, + + // Enables compression. + "enabled": false, + + // The compression level for gzip. + // + // SUPPORTED: Fastest (default), OptimOptimal, SmallestSize, NoCompression + "levelGzip": "Fastest", + + // The compression level for brotli. + // + // SUPPORTED: Fastest (default), OptimOptimal, SmallestSize, NoCompression + "levelBrotli": "Fastest" + }, + "urls": { // Set the base url of your application, to generate correct urls in background process. "baseUrl": "https://localhost:5001",