Personal website
at master 91 lines 3.0 kB view raw
1/* 2 This file is part of NKK. 3 4 NKK is free software: you can redistribute it and/or modify it under the 5 terms of the GNU Affero General Public License as published by the Free 6 Software Foundation, either version 3 of the License, or (at your option) 7 any later version. 8 9 NKK is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for 12 more details. 13 14 You should have received a copy of the GNU Affero General Public License 15 along with NKK. If not, see <http://www.gnu.org/licenses/>. 16*/ 17 18using System.IO.Compression; 19using System.Text; 20using NKK.Components; 21using Microsoft.AspNetCore.ResponseCompression; 22using NKK; 23 24var builder = WebApplication.CreateBuilder(new WebApplicationOptions() { 25 Args = args, 26 WebRootPath = "public" 27}); 28 29// Add services to the container. 30builder.Services.AddRazorComponents(); 31builder.Services.AddResponseCompression(options => { 32 options.EnableForHttps = true; 33 options.Providers.Add<BrotliCompressionProvider>(); 34 options.Providers.Add<GzipCompressionProvider>(); 35 options.MimeTypes = ResponseCompressionDefaults.MimeTypes; 36} ); 37builder.Services.Configure<BrotliCompressionProviderOptions>(options => { 38 options.Level = CompressionLevel.SmallestSize; 39}); 40 41builder.Services.Configure<GzipCompressionProviderOptions>(options => { 42 options.Level = CompressionLevel.SmallestSize; 43}); 44 45var app = builder.Build(); 46 47// Configure the HTTP request pipeline. 48if (!app.Environment.IsDevelopment()) { 49 app.UseExceptionHandler("/Error", createScopeForErrors: true); 50 // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 51 app.UseHsts(); 52} 53 54app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true); 55app.UseHttpsRedirection(); 56 57app.UseAntiforgery(); 58app.UseResponseCompression(); 59app.Use(async (context, next) => { 60 // context.Response.Body is a direct line to the client, so 61 // swap it out for our own in-memory stream for now 62 Stream responseStream = context.Response.Body; 63 using var memoryStream = new MemoryStream(); 64 context.Response.Body = memoryStream; 65 66 // let downstream render the response & write to our stream 67 await next(context); 68 69 if (context.Response.ContentType?.StartsWith("text/html") != true) { 70 // oops my bad gangalang 71 // ok now put it back 72 memoryStream.Position = 0; 73 await memoryStream.CopyToAsync(responseStream); 74 context.Response.Body = responseStream; 75 76 return; 77 } 78 79 memoryStream.Position = 0; 80 String html = await new StreamReader(memoryStream).ReadToEndAsync(); 81 String minified = Utils.OptimizeHtml(html); 82 83 context.Response.ContentLength = Encoding.UTF8.GetByteCount(minified); 84 await responseStream.WriteAsync(Encoding.UTF8.GetBytes(minified)); 85 context.Response.Body = responseStream; 86}); 87 88app.UseStaticFiles(); 89app.MapRazorComponents<App>(); 90 91app.Run();