╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │275 } │ │276 │ │277 fn handleLogout(request: *std.http.Server.Request) !void { │ │278 - // request.respond's discardBody reads any unused body for us and lands │ │279 - // the connection back in the .ready state for the next request on the │ │280 - // same connection (keep_alive defaults to true). │ │278 + // close the connection instead of keeping it alive: we don't read the │ │279 + // request body, and respond()'s keep-alive path would otherwise try to │ │280 + // discard it — which asserts on a bodyless POST that carries no │ │281 + // content-length, and would block on one with no framing at all. a logout │ │282 + // is just a redirect, so the browser reconnects for the follow-up GET. │ │283 try request.respond("", .{ │ │284 .status = .see_other, │ │285 + .keep_alive = false, │ │286 .extra_headers = &.{ │ │287 .{ .name = "location", .value = ui.RoutablePage.url(.home_auth) }, │ │288 .{ .name = "set-cookie", .value = cookie_name ++ "=; Path=/; HttpOnly; SameSite=Strict; Max-Age=0" },│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯