namespace DTLib.Web.Routes; public class ServeFilesRoute(IOPath _publicDir, string _homePageUrl = "index.html") : Route { public override async Task HandleRequest(HttpListenerContext ctx) { if (ctx.Request.HttpMethod != "GET") return HttpStatusCode.BadRequest; string requestPath = ctx.Request.Url?.AbsolutePath ?? "/"; if (requestPath == "/") requestPath = _homePageUrl; string ext = Path.Extension(requestPath).Str; IOPath filePath = Path.Concat(_publicDir, requestPath); if (!File.Exists(filePath)) return HttpStatusCode.NotFound; string contentType = ext switch { "html" => "text/html", "css" => "text/css", "js" or "jsx" or "ts" or "tsx" or "map" => "text/javascript", _ => "binary/octet-stream" }; ctx.Response.Headers.Set("Content-Type", contentType); ctx.Response.Headers.Set("Content-Disposition", "attachment filename=" + filePath.LastName()); var fileStream = File.OpenRead(filePath); ctx.Response.ContentLength64 = fileStream.Length; await fileStream.CopyToAsync(ctx.Response.OutputStream); return HttpStatusCode.OK; } }