using Flaro.Metadata; using Microsoft.AspNetCore.Mvc; namespace Flaro.Api.Endpoints; public static class ImageEndpoints { public static void MapImages(this IEndpointRouteBuilder app) { app.MapGet("/api/v1/images/{key}", (string key, ImageCache ablage) => { // Gibt `null` zurück, sobald der Schlüssel kein reiner Hash ist — // ohne diese Prüfung wäre die Adresszeile ein Weg in jedes // Verzeichnis des Containers. var pfad = ablage.PfadFür(key); if (pfad is null || !File.Exists(pfad)) return Results.NotFound(); // Der Schlüssel ist der Hash des Inhalts, also ändert sich das Bild // unter dieser Adresse nie. Ein Jahr zwischenspeichern spart bei // einer Mediathek mit tausend Plakaten das meiste an Verkehr. return Results.File(pfad, ImageCache.MedientypVon(pfad), enableRangeProcessing: true); }) .RequireAuthorization() .AddEndpointFilter(async (zusammenhang, weiter) => { var ergebnis = await weiter(zusammenhang); zusammenhang.HttpContext.Response.Headers.CacheControl = "private, max-age=31536000, immutable"; return ergebnis; }); } }