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
羽毛球分组比赛记分
小程序二维码

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

小夜