From 0c93475ab986fe1c344a9ef3db4a8c89f31f2d2b Mon Sep 17 00:00:00 2001 From: richblack Date: Wed, 29 Jul 2026 22:47:46 +0800 Subject: [PATCH] =?UTF-8?q?t150=20=E4=BA=8C=E4=BF=AE=EF=BC=9A=E7=B9=9E?= =?UTF-8?q?=E9=96=8B=20jsDelivr=20@main=20=E7=9A=84=207=20=E5=A4=A9?= =?UTF-8?q?=E5=BF=AB=E5=8F=96=EF=BC=88=E5=90=A6=E5=89=87=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=A9=9F=E5=88=B6=E5=BD=A2=E5=90=8C=E8=99=9B=E8=A8=AD=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 實測(07-29):jsDelivr 對 @main 回 cache-control max-age=604800=**7 天** ⇒ 用戶小幫手連續七天看不到新版;下載 zip 同理會抓到舊檔 ⇒ sha256 不符 ⇒ 更新永遠失敗。 修:manifest 與 zip 下載都帶 ?t= 繞快取(實測即取得最新)。 不用 raw.githubusercontent——那是實名讀 GitHub,受 D20 頻率閘管制。 另修副作用:檔名要用去掉查詢字串的網址算,否則存成 ...zip?t=1785... 怪檔名。 --- cmd/arcrun-tray/selfupdate.go | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/cmd/arcrun-tray/selfupdate.go b/cmd/arcrun-tray/selfupdate.go index e2efefa..6f54402 100644 --- a/cmd/arcrun-tray/selfupdate.go +++ b/cmd/arcrun-tray/selfupdate.go @@ -24,12 +24,23 @@ import ( "os" "os/exec" "path/filepath" + "strconv" "strings" "time" ) -// manifestURL 是 bundle manifest(含 daemon 區塊)。與安裝器同源,不另開發佈通道。 -const manifestURL = "https://cdn.jsdelivr.net/gh/youlinhsieh/arcrun-rag-bundles@main/manifest.json" +// manifestBase 是 bundle manifest(含 daemon 區塊)。與安裝器同源,不另開發佈通道。 +// +// ⚠️ 必須帶時間戳查詢字串繞快取(2026-07-29 實測): +// jsDelivr 對 `@main` 回 `cache-control: max-age=604800`=**7 天**, +// 用戶的小幫手會連續七天看不到新版 ⇒ 整套更新機制形同虛設。 +// 帶 ?t= 實測即取得最新內容。 +// (不用 raw.githubusercontent:那是「實名讀 GitHub」,受 D20 頻率閘管制。) +const manifestBase = "https://cdn.jsdelivr.net/gh/youlinhsieh/arcrun-rag-bundles@main/manifest.json" + +func manifestURLNoCache() string { + return manifestBase + "?t=" + strconv.FormatInt(time.Now().Unix(), 10) +} // updateCheckInterval:背景檢查頻率。守「不輪詢」紅線——這是**單一 CDN 靜態檔**、 // 每天一次、非 GitHub API,不構成 fan-out 或高頻寫入。 @@ -67,7 +78,7 @@ var currentUpdate updateState // fetchLatestRelease 抓 manifest 的 daemon 區塊。 func fetchLatestRelease() (*daemonRelease, error) { cli := &http.Client{Timeout: 20 * time.Second} - resp, err := cli.Get(manifestURL) + resp, err := cli.Get(manifestURLNoCache()) if err != nil { return nil, err } @@ -117,11 +128,14 @@ func checkForUpdate() updateState { // downloadURLFor 回傳本平台的下載網址。 func downloadURLFor(rel *daemonRelease) string { - const base = "https://cdn.jsdelivr.net/gh/youlinhsieh/arcrun-rag-bundles@main/" + // 同 manifestURLNoCache 的理由:@main 有 7 天快取,下載也要繞, + // 否則會抓到舊 zip ⇒ sha256 校驗不符 ⇒ 更新永遠失敗。 + base := "https://cdn.jsdelivr.net/gh/youlinhsieh/arcrun-rag-bundles@main/" + suffix := "?t=" + strconv.FormatInt(time.Now().Unix(), 10) if isWindows() { - return base + rel.Win.File + return base + rel.Win.File + suffix } - return base + rel.Mac.File + return base + rel.Mac.File + suffix } // updateStagePath 是下載暫存位置(~/.arcrun-rag/updates/)。 @@ -186,7 +200,9 @@ func downloadUpdate(rel *daemonRelease) (string, error) { if resp.StatusCode != 200 { return "", fmt.Errorf("下載 HTTP %d", resp.StatusCode) } - dst := updateStagePath(rel.Version + "-" + filepath.Base(url)) + // 檔名要用「去掉查詢字串」的網址算,否則會變成 ...zip?t=1785... 這種怪檔名。 + cleanURL := strings.SplitN(url, "?", 2)[0] + dst := updateStagePath(rel.Version + "-" + filepath.Base(cleanURL)) f, err := os.Create(dst) if err != nil { return "", err