dsh-cookie-janitor:在 Cookie 头撞上 16 KiB 限制之前清理过期登录 Cookie

前言

DSH 的安装理念是「一切皆插件」,插件是扩展 Harness 的常规路径。下面介绍 07-dot/dsh-cookie-janitor,维护者为 07-dot,在社区目录的分类是 admin-security,仓库简介为「Expire stale dsh-auth cookies before the 16 KiB header limit (HTTP 431)」。

它解决的问题很具体:用浏览器打开 dsh web 时,登录用的 dsh-auth-* Cookies 会不断累积在同一个 jar 里。当 Cookie 请求头超过 Node HTTP 解析器的上限,服务端会直接返回 431,请求到不了任何路由、处理器或插件,浏览器里的页面也无法自行恢复。这个插件在头文件超限之前把这些过期的登录 Cookie 清掉。

问题来源

@deepseek-ai/dsh-client-connection 每次请求一个 authority 就会签发一个浏览器 Cookie:

dsh-auth-<base64url(sha256("host:port"))> = v1.<payload>.<hmac>
  ; Max-Age=2592000; Path=/; HttpOnly; SameSite=Strict

Cookie 名里带了 authority,有效期默认 30 天(对应 cookieMaxAgeDays),并且这个包从不发送删除指令,没有清理路径。Cookie 是按 host 而非按端口划分作用域,所以在 30 天内浏览器访问过的每一个 dsh web 端口,都会在 127.0.0.1 这同一个 jar 里留下一条 dsh-auth-*。

一个 Cookie 对约 226 字节,解析器限制是 16 KiB 的请求头。按 README 中的测试数据,Cookie 头为 16,400 字节的请求返回 431,而 16,200 字节仍能到达应用。也就是说大约累积 69 个 Cookie 就足以把浏览器端的 GUI 锁死,此时界面上没有任何按钮能恢复,因为每个请求都在路由前失败。

它做什么

1、插件在激活时向监听中的 http.Server 前置一个 request 监听器。

2、对每个携带 dsh-auth-* Cookies 的请求,先测量 Cookie 头的大小。

3、一旦 jar 越过预算,就按从旧到新的顺序,为所有不是当前请求自身 authority 的 Cookie 追加删除头:

Set-Cookie: <name>=; Path=/; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; SameSite=Strict

保留数量由 retain 决定。浏览器在这次响应中清空对应的 jar。

需要说明的是,请求本身仍由正常管线处理:钩子只设置响应头,不写响应体,因此路由、认证和 SPA fallback 的行为不变。

配置

在插件配置中设置预算:

- id: cookie-janitor
  name: dsh-cookie-janitor
  config:
    maxCookies: 8        # 超过这个数量的 dsh-auth Cookie 就裁剪
    maxHeaderBytes: 4096 # 超过这个 Cookie 头字节数就裁剪
    retain: 2            # 裁剪后保留的 Cookie 数,包含当前 authority 的
    dryRun: false        # 只记录将要执行的裁剪,不发送删除指令

裁剪只在超过预算后才触发。所以一个 jar 里只保存每个存活实例一个 Cookie 时不会被碰;同一台主机上有多个存活的 authority 也能继续工作,直到 jar 越过预算。之后被过期的是最旧的那些条目,被清理掉的实例需要从它打印出的 URL 重新登录。

安装与启用

dsh plugin add dsh-cookie-janitor

或直接来自本仓库:

dsh plugin add github:07-dot/dsh-cookie-janitor

如果主机不支持热加载插件,安装后需要重启 dsh web(或 Desktop 应用)。

手工救援与适用边界

当 jar 已经不可用时,可以让插件一次性清空。用同一个持有这些 Cookie 的浏览器打开下面这个地址,它会过期该请求携带的所有 dsh-auth-* 并打印统计信息(最大的 Cookie 头、见过的 Cookie 数量、累计裁剪数):

GET /__dsh-cookie-janitor

之后再重新打开 DSH URL 即可。

并非所有场景都需要它。Desktop 应用不会累积这类 Cookie:主窗口通过 dsh-app://app/ 协议处理器与 Host 通信,只转发 shell 内存里保存的那一个 Cookie,并且不让 set-cookie 进入页面 jar(README 中注明按 DSH 0.2.1-rc.5 核对)。真正暴露的场景是浏览器里的 web profile,jar 在 Cookie 生命周期内被所有用过的端口共享。插件在没有东西可清理时是无害的,低于预算时不发送任何头。

它也处理不了非 dsh-auth-* 原因导致的大 Cookie 头,这些是被刻意保留的。

运行要求

  • DSH 0.2.1-rc.1 或更新的 0.2.x 版本(见 engines.dsh)。
  • 无运行时依赖,无构建步骤,无安装脚本。

适用场景与注意

适合使用 dsh web 在真实浏览器里开发、调试,且端口会在一段时间内不断变化、可能多次触发登录的开发者。它能避免 431 把界面锁死后只能手工清空 Cookie 的局面。

插件以当前 dsh 进程的权限运行,可用于清理过期登录 Cookie、压缩请求头。安装前应查看源码与许可证(MIT),确认行为与你的部署环境相符再启用。

结尾

dsh-cookie-janitor 的价值在于把「登录 Cookie 无限累积直到 431」这个只能靠人工发现和清空的问题,变成一个在预算以内自动裁剪的行为。目录页和源码:

  • 社区目录:https://www.skillhub.cn/plugins/07-dot/dsh-cookie-janitor
  • GitHub:https://github.com/07-dot/dsh-cookie-janitor
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜