Nice little directory browser :D
at e2d879cb8b32efb0d337146d295d144b9f3aca90 122 lines 3.8 kB view raw
1/* 2 This file is part of Utatane. 3 4 Utatane is free software: you can redistribute it and/or modify it under 5 the 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 Utatane 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 Utatane. If not, see <http://www.gnu.org/licenses/>. 16*/ 17 18using System.IO.Compression; 19using System.Text; 20using FluentResults; 21using Microsoft.AspNetCore.Http.Features; 22using Utatane.Components; 23using Microsoft.AspNetCore.ResponseCompression; 24using Microsoft.AspNetCore.Rewrite; 25using Microsoft.Extensions.FileProviders; 26using Utatane; 27 28var builder = WebApplication.CreateBuilder(new WebApplicationOptions() { 29 Args = args, 30 WebRootPath = "public" 31}); 32 33// Add services to the container. 34// Add services to the container. 35builder.Services.AddRazorComponents(); 36builder.Services.AddResponseCompression(options => { 37 options.EnableForHttps = true; 38 options.Providers.Add<BrotliCompressionProvider>(); 39 options.Providers.Add<GzipCompressionProvider>(); 40 options.MimeTypes = ResponseCompressionDefaults.MimeTypes; 41} ); 42builder.Services.Configure<BrotliCompressionProviderOptions>(options => { 43 options.Level = CompressionLevel.SmallestSize; 44}); 45 46builder.Services.Configure<GzipCompressionProviderOptions>(options => { 47 options.Level = CompressionLevel.SmallestSize; 48}); 49 50var app = builder.Build(); 51 52// Configure the HTTP request pipeline. 53if (!app.Environment.IsDevelopment()) { 54 app.UseExceptionHandler("/Error", createScopeForErrors: true); 55 // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 56 app.UseHsts(); 57} 58 59app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true); 60app.UseHttpsRedirection(); 61 62app.UseAntiforgery(); 63app.UseResponseCompression(); 64 65app.Use(async (context, next) => { 66 // context.Response.Body is a direct line to the client, so 67 // swap it out for our own in-memory stream for now 68 Stream responseStream = context.Response.Body; 69 using var memoryStream = new MemoryStream(); 70 context.Response.Body = memoryStream; 71 72 // let downstream render the response & write to our stream 73 await next(context); 74 75 if ( 76 context.Response.ContentType?.StartsWith("text/html") != true 77 /* || TODO: don't compress when serving HTML files found by Utatane!! */ ) { 78 // oops my bad gangalang 79 // ok now put it back 80 memoryStream.Position = 0; 81 await memoryStream.CopyToAsync(responseStream); 82 context.Response.Body = responseStream; 83 84 return; 85 } 86 87 memoryStream.Position = 0; 88 String html = await new StreamReader(memoryStream).ReadToEndAsync(); 89 String minified = Utils.OptimizeHtml(html); 90 91 context.Response.ContentLength = Encoding.UTF8.GetByteCount(minified); 92 await responseStream.WriteAsync(Encoding.UTF8.GetBytes(minified)); 93 context.Response.Body = responseStream; 94}); 95 96// check paths exist 97app.Use(async (context, next) => { 98 if ( 99 context.Request.Path.StartsWithSegments("/api/files") 100 || context.Request.Path.StartsWithSegments("/.nhnd") 101 ) { 102 await next(context); 103 return; 104 } 105 106 var pathCheck = Utils.CheckJoinedPathIsBased(context.Request.Path); 107 if (pathCheck.IsFailed) { 108 context.Response.StatusCode = StatusCodes.Status404NotFound; 109 return; 110 } 111 112 await next(context); 113}); 114 115app.UseRewriter(new RewriteOptions().AddRedirect(@"^favicon\.ico$", "/.nhnd/favicon.ico")); 116 117app.UseStaticFiles(new StaticFileOptions { 118 RequestPath = "/.nhnd" 119}); 120app.MapRazorComponents<App>(); 121 122app.Run();