From 693a6cc867a78f45f5728b80faa0e18128005ec6 Mon Sep 17 00:00:00 2001 From: Scarriffle Date: Sat, 10 Oct 2026 20:42:29 +0200 Subject: [PATCH] Cookie heisst Cookie MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit „Keks", „Keksglas", „Kekse" — eingedeutscht, wo es nichts zu verdeutschen gibt. Ein Cookie ist ein Cookie; wer danach sucht, sucht nicht nach Keksen, und wer den Quelltext liest, liest daneben die Schnittstelle, in der es `HTTPCookieStorage` heisst. Betrifft Kommentare und Prüfungsnamen, kein Verhalten. Co-Authored-By: Claude Opus 5 --- .../FlaroPlayback/Engine/AVPlayerEngine.swift | 4 +-- .../FlaroPlayback/Prefetch/StreamCache.swift | 4 +-- .../FlaroServerKitTests/AdressenTests.swift | 26 +++++++++---------- .../FlaroServerKitTests/Hilfsmittel.swift | 6 ++--- .../Flaro.Api.Tests/WebInterfaceTests.cs | 22 ++++++++-------- web/app/src/api.ts | 2 +- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Packages/FlaroKit/Sources/FlaroPlayback/Engine/AVPlayerEngine.swift b/Packages/FlaroKit/Sources/FlaroPlayback/Engine/AVPlayerEngine.swift index 14dc575..084bd6d 100644 --- a/Packages/FlaroKit/Sources/FlaroPlayback/Engine/AVPlayerEngine.swift +++ b/Packages/FlaroKit/Sources/FlaroPlayback/Engine/AVPlayerEngine.swift @@ -135,14 +135,14 @@ public final class AVPlayerEngine: VideoPlayerEngine { // // Serverneutral: wo kein Cookie liegt, ist die Liste leer und es // ändert sich nichts. - let kekse = HTTPCookieStorage.shared.cookies(for: source.url) ?? [] + let cookies = HTTPCookieStorage.shared.cookies(for: source.url) ?? [] let asset = AVURLAsset(url: source.url, options: [ // Keine genaue Dauer verlangen. Sonst durchsucht AVFoundation bei // manchen Formaten die ganze Datei, bevor es überhaupt anfängt — // und „ganze Datei" heißt bei einem Remux vierzig Gigabyte. AVURLAssetPreferPreciseDurationAndTimingKey: false, - AVURLAssetHTTPCookiesKey: kekse, + AVURLAssetHTTPCookiesKey: cookies, ]) let item = AVPlayerItem(asset: asset) diff --git a/Packages/FlaroKit/Sources/FlaroPlayback/Prefetch/StreamCache.swift b/Packages/FlaroKit/Sources/FlaroPlayback/Prefetch/StreamCache.swift index a0a4ebd..a357afb 100644 --- a/Packages/FlaroKit/Sources/FlaroPlayback/Prefetch/StreamCache.swift +++ b/Packages/FlaroKit/Sources/FlaroPlayback/Prefetch/StreamCache.swift @@ -83,10 +83,10 @@ public actor StreamCache { // **Die Anmeldung muss mit.** // - // Eine flüchtige Sitzung bringt ihren eigenen, leeren Keksspeicher + // Eine flüchtige Sitzung bringt ihren eigenen, leeren Cookie-Speicher // mit — jede Anfrage von hier ging also unangemeldet hinaus. Bei // Jellyfin fiel das nie auf: dort steht der Schlüssel in der Adresse. - // Flaro meldet über ein Keks an, und im Protokoll stand genau das: + // Flaro meldet über ein Cookie an, und im Protokoll stand genau das: // `FlaroToken was challenged`, einmal je Wiedergabe, gefolgt von // zwölf Sekunden Stille und einer zweiten Bestellung. configuration.httpCookieStorage = HTTPCookieStorage.shared diff --git a/Packages/FlaroKit/Tests/FlaroServerKitTests/AdressenTests.swift b/Packages/FlaroKit/Tests/FlaroServerKitTests/AdressenTests.swift index 0a8918f..aa8504a 100644 --- a/Packages/FlaroKit/Tests/FlaroServerKitTests/AdressenTests.swift +++ b/Packages/FlaroKit/Tests/FlaroServerKitTests/AdressenTests.swift @@ -6,11 +6,11 @@ import MediaKit /// Adressen und Zugang — alles, was ohne Netz entsteht. @Suite("Flaro: Adressen und Zugang") struct AdressenTests { - private func backend(_ transport: Attrappe, keksglas: Keksglas? = nil) -> FlaroBackend { + private func backend(_ transport: Attrappe, cookieglas: Cookieglas? = nil) -> FlaroBackend { FlaroBackend( client: FlaroClient( baseURL: Proben.adresse, identity: Proben.kennung, token: "geheim-123", - transport: transport, cookieJar: keksglas), + transport: transport, cookieJar: cookieglas), account: FlaroAccount( baseURL: Proben.adresse, serverName: "Wohnzimmer", userID: "u1", userName: "guido", isAdministrator: true)) @@ -32,17 +32,17 @@ struct AdressenTests { } @Test("Ein Zugang wird als Cookie abgelegt") - func tokenWirdZuKeks() async { - let glas = Keksglas() + func tokenWirdZuCookie() async { + let glas = Cookieglas() _ = FlaroClient( baseURL: Proben.adresse, identity: Proben.kennung, token: "geheim-123", transport: Attrappe(rumpf: "{}"), cookieJar: glas) - let keks = glas.kekse.first - #expect(keks?.name == "flaro_session") - #expect(keks?.value == "geheim-123") - #expect(keks?.path == "/") - #expect(keks?.domain.hasSuffix("nas") == true) + let cookie = glas.cookies.first + #expect(cookie?.name == "flaro_session") + #expect(cookie?.value == "geheim-123") + #expect(cookie?.path == "/") + #expect(cookie?.domain.hasSuffix("nas") == true) } /// **Nach einem Neustart meldet sich niemand neu an.** @@ -51,8 +51,8 @@ struct AdressenTests { /// allein aus der Antwort des Servers, wäre keines da — und jedes Plakat /// bliebe grau, obwohl der Zugang gilt. @Test("Auch ein wiederaufgenommenes Token legt das Cookie an") - func keksAuchOhneAnmeldung() async throws { - let glas = Keksglas() + func cookieAuchOhneAnmeldung() async throws { + let glas = Cookieglas() let transport = Attrappe([ ("/api/v1/auth/me", 200, #"{"id":"u1","userName":"guido","isAdministrator":false}"#), ("/api/v1/system/info", 200, Proben.info), @@ -62,7 +62,7 @@ struct AdressenTests { baseURL: Proben.adresse, token: "geheim-123", identity: Proben.kennung, transport: transport, cookieJar: glas) - #expect(glas.kekse.contains { $0.name == "flaro_session" && $0.value == "geheim-123" }) + #expect(glas.cookies.contains { $0.name == "flaro_session" && $0.value == "geheim-123" }) } @Test("Die Download-Adresse zeigt auf die Datei, nicht auf den Titel") @@ -104,7 +104,7 @@ struct AdressenTests { let (token, konto, _) = try await FlaroSignIn.signIn( baseURL: Proben.adresse, userName: "guido", password: "geheim", - identity: Proben.kennung, transport: transport, cookieJar: Keksglas()) + identity: Proben.kennung, transport: transport, cookieJar: Cookieglas()) let rumpf = try #require(transport.rumpf(von: "/api/v1/auth/login")) diff --git a/Packages/FlaroKit/Tests/FlaroServerKitTests/Hilfsmittel.swift b/Packages/FlaroKit/Tests/FlaroServerKitTests/Hilfsmittel.swift index 82f1fa2..657c8bb 100644 --- a/Packages/FlaroKit/Tests/FlaroServerKitTests/Hilfsmittel.swift +++ b/Packages/FlaroKit/Tests/FlaroServerKitTests/Hilfsmittel.swift @@ -46,15 +46,15 @@ final class Attrappe: FlaroTransport, @unchecked Sendable { } } -/// Ein Keksglas, das nur mitschreibt. +/// Ein Cookieglas, das nur mitschreibt. /// /// Der Speicher des Systems anzufassen hiesse, dass eine Prüfung die nächste /// beeinflusst — und auf einem Entwicklerrechner auch den Browser. -final class Keksglas: FlaroCookieJar, @unchecked Sendable { +final class Cookieglas: FlaroCookieJar, @unchecked Sendable { private let sperre = NSLock() private var inhalt: [HTTPCookie] = [] - var kekse: [HTTPCookie] { sperre.withLock { inhalt } } + var cookies: [HTTPCookie] { sperre.withLock { inhalt } } func store(_ cookie: HTTPCookie) { sperre.withLock { inhalt.append(cookie) } } diff --git a/server/tests/Flaro.Api.Tests/WebInterfaceTests.cs b/server/tests/Flaro.Api.Tests/WebInterfaceTests.cs index b9d137d..5ca80c0 100644 --- a/server/tests/Flaro.Api.Tests/WebInterfaceTests.cs +++ b/server/tests/Flaro.Api.Tests/WebInterfaceTests.cs @@ -50,11 +50,11 @@ public sealed class WebInterfaceTests var client = server.OhneGedaechtnis(); var angemeldet = await client.PostAsJsonAsync("/api/v1/auth/login", new LoginRequest("guido", "ein-langes-passwort", "Browser", "browser-1")); - var keks = Keks(angemeldet); + var cookie = Cookie(angemeldet); // Ohne Kopfzeile — genau so, wie ein fragt. var anfrage = new HttpRequestMessage(HttpMethod.Get, "/api/v1/movies"); - anfrage.Headers.Add("Cookie", keks); + anfrage.Headers.Add("Cookie", cookie); var antwort = await client.SendAsync(anfrage); Assert.That(antwort.StatusCode, Is.EqualTo(HttpStatusCode.OK)); @@ -80,17 +80,17 @@ public sealed class WebInterfaceTests var client = server.OhneGedaechtnis(); var angemeldet = await client.PostAsJsonAsync("/api/v1/auth/login", new LoginRequest("guido", "ein-langes-passwort", "Browser", "browser-1")); - var keks = Keks(angemeldet); + var cookie = Cookie(angemeldet); var abmelden = new HttpRequestMessage(HttpMethod.Post, "/api/v1/auth/logout"); - abmelden.Headers.Add("Cookie", keks); + abmelden.Headers.Add("Cookie", cookie); (await client.SendAsync(abmelden)).EnsureSuccessStatusCode(); // **Das Token muss serverseitig weg sein, nicht nur das Cookie im // Browser.** Ein gelöschtes Cookie schützt niemanden, der den Wert // vorher mitgeschrieben hat. var danach = new HttpRequestMessage(HttpMethod.Get, "/api/v1/movies"); - danach.Headers.Add("Cookie", keks); + danach.Headers.Add("Cookie", cookie); Assert.That((await client.SendAsync(danach)).StatusCode, Is.EqualTo(HttpStatusCode.Unauthorized)); @@ -236,8 +236,8 @@ public sealed class WebInterfaceTests Assert.Multiple(() => { - Assert.That(GanzerKeks(dauerhaft), Does.Contain("max-age=31536000").IgnoreCase); - Assert.That(GanzerKeks(nurJetzt), Does.Not.Contain("max-age").IgnoreCase); + Assert.That(GanzesCookie(dauerhaft), Does.Contain("max-age=31536000").IgnoreCase); + Assert.That(GanzesCookie(nurJetzt), Does.Not.Contain("max-age").IgnoreCase); }); } @@ -251,7 +251,7 @@ public sealed class WebInterfaceTests var antwort = await server.OhneGedaechtnis().PostAsJsonAsync("/api/v1/auth/login", new LoginRequest("guido", "ein-langes-passwort", "Browser", "b1")); - Assert.That(GanzerKeks(antwort), Does.Contain("max-age=31536000").IgnoreCase); + Assert.That(GanzesCookie(antwort), Does.Contain("max-age=31536000").IgnoreCase); } /// Abmelden scheitert nie — auch nicht ohne gültiges Token. @@ -300,10 +300,10 @@ public sealed class WebInterfaceTests } /// Nimmt den Namen und den Wert aus der Set-Cookie-Kopfzeile. - private static string Keks(HttpResponseMessage antwort) => - GanzerKeks(antwort).Split(';')[0]; + private static string Cookie(HttpResponseMessage antwort) => + GanzesCookie(antwort).Split(';')[0]; /// Die ganze Kopfzeile — samt Lebensdauer und Schutzangaben. - private static string GanzerKeks(HttpResponseMessage antwort) => + private static string GanzesCookie(HttpResponseMessage antwort) => antwort.Headers.GetValues("Set-Cookie").Single(); } diff --git a/web/app/src/api.ts b/web/app/src/api.ts index cf9f19c..44084a7 100644 --- a/web/app/src/api.ts +++ b/web/app/src/api.ts @@ -720,7 +720,7 @@ export type Untertitelstand = * einem Dreistünder zu ziehen heisst, die ganze Datei zu lesen, und das * dauert beim ersten Mal Minuten. * - * **Und mit Token, nicht mit Keks.** Ein `` wies sich über das Cookie + * **Und mit Token, nicht mit Cookie.** Ein `` wies sich über das Cookie * aus. Das geht, solange es eines gibt — gemessen fiel es auf, als keines da * war und jeder Abruf mit 401 zurückkam, ohne dass irgendwo etwas stand. */ export async function untertitelHolen(