Skip to content

Instantly share code, notes, and snippets.

@flq
Created March 1, 2025 10:20
Show Gist options
  • Save flq/90a074e38fb4a48cf5d51d43a7b68145 to your computer and use it in GitHub Desktop.
Save flq/90a074e38fb4a48cf5d51d43a7b68145 to your computer and use it in GitHub Desktop.
Http File server V2025
using System.Net.Mime;
using Microsoft.AspNetCore.StaticFiles;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton(new RootDirectory(args[0]));
var app = builder.Build();
app.MapGet("/{*path}", (string? path, RootDirectory dir) =>
{
var fsItem = dir.Combine(path);
return fsItem switch
{
{IsDirectory: true} => ListDirectory(),
{IsFile: true} => Results.File(fsItem.Path, fsItem.ContentType),
_ => Results.NotFound()
};
IResult ListDirectory()
{
return Results.Stream(async s =>
{
await using var sw = new StreamWriter(s);
await sw.WriteLineAsync($"""
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>{fsItem.Path}</title>
</head>
<body><h1>{fsItem.Path}</h1><ul>
""");
foreach (var d in fsItem.GetDirectories())
await sw.WriteLineAsync($"<li>&lt;DIR&gt; <a href=\"{dir.Linkify(d)}\">{Path.GetFileName(d)}</a></li>");
foreach (var f in fsItem.GetFiles())
await sw.WriteLineAsync($"<li><a href=\"{dir.Linkify(f)}\">{Path.GetFileName(f)}</a></li>");
await sw.WriteLineAsync("</ul></body></html>");
}, MediaTypeNames.Text.Html);
}
});
app.Run();
internal record RootDirectory(string Root)
{
public FsItem Combine(string? path) => new(path != null ? Path.Combine(Root, path) : Root);
public string Linkify(string path) => path.Replace(Root, "").Replace('\\', '/');
}
internal record FsItem(string Path)
{
private static readonly FileExtensionContentTypeProvider Extensions = new();
public bool IsDirectory => Directory.Exists(Path);
public bool IsFile => File.Exists(Path);
public string? ContentType => Extensions.TryGetContentType(Path, out var contentType) ? contentType : null;
public string[] GetDirectories() => Directory.GetDirectories(Path);
public string[] GetFiles() => Directory.GetFiles(Path);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment