HEAD auf den Download, und /api verschluckt nichts mehr

Zwei Fehler, derselbe Grund — und beide zeigte erst der Browser.

**Der Spieler bekam die Webseite statt des Films.** „MEDIA_ELEMENT_ERROR:
Format error", 531 Byte, `Content-Type: text/html`. Das ist genau die Grösse
von `index.html`.

`MapGet` nimmt HEAD nicht an. Die Oberfläche fragt aber mit HEAD nach, ob das
Umpacken fertig ist — einen halbfertigen Film herunterzuladen, nur um das zu
erfahren, wäre absurd. Die Anfrage fiel durch den Methodenabgleich hindurch
bis zum SPA-Rückfall, und der nimmt jeden Pfad ohne Dateiendung. Antwort:
200, mit der Startseite im Rumpf. Der Client hielt das Umpacken für fertig
und reichte HTML an `<video>` weiter.

Jetzt `MapMethods` mit GET und HEAD. Kestrel lässt den Rumpf bei HEAD selbst
weg.

**Und ein vertippter Aufruf sah aus wie ein Erfolg.** `GET /api/v1/gibtsnicht`
gab 200 und die Webseite zurück — derselbe Rückfall. Ein Fehler, der erst
dort auffällt, wo jemand HTML durch einen JSON-Parser schickt.

`app.Map("/api/{*rest}", 404)` davor. Buchstaben schlagen Platzhalter, also
gewinnt jeder echte Endpunkt; was übrig bleibt, ist nicht da und sagt das
auch.

350 Tests grün, die zwei neuen eingerechnet. Am Container nachgemessen: HEAD
auf den Download gibt 200 `video/mp4` mit 71 920 Byte, `/api/v1/gibtsnicht`
gibt 404, und ein Neuladen auf `/verwaltung` bekommt weiterhin die Seite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-03 21:33:56 +02:00
co-authored by Claude Opus 5
parent c4081ff251
commit 67cf0fd1d9
4 changed files with 72 additions and 3 deletions
@@ -180,6 +180,30 @@ public class DeliveryTests
Assert.That(antwort.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
/// <summary>Der Client fragt mit HEAD nach, ob das Umpacken fertig ist.</summary>
///
/// <remarks>
/// <b>Der Fehler, den erst der Browser zeigte.</b> <c>MapGet</c> nimmt
/// HEAD nicht an. Die Anfrage fiel durch bis zum SPA-Rückfall, bekam
/// <c>200 text/html</c>, und der Spieler hielt die Webseite für den Film:
/// „MEDIA_ELEMENT_ERROR: Format error", 531 Byte lang.
/// </remarks>
[Test]
public async Task HEAD_auf_den_Download_antwortet_mit_dem_Download()
{
Film("Kopfpruefung (2021)", "mp4");
var (client, datei) = await Eingelesen();
var antwort = await client.SendAsync(
new HttpRequestMessage(HttpMethod.Head, $"/api/v1/files/{datei.Id}/download"));
Assert.Multiple(() =>
{
Assert.That(antwort.StatusCode, Is.EqualTo(HttpStatusCode.OK));
Assert.That(antwort.Content.Headers.ContentType?.MediaType, Is.EqualTo("video/mp4"));
});
}
[Test]
public async Task Ohne_Anmeldung_gibt_es_nichts()
{