t150 二修:繞開 jsDelivr @main 的 7 天快取(否則更新機制形同虛設)

實測(07-29):jsDelivr 對 @main 回 cache-control max-age=604800=**7 天**
⇒ 用戶小幫手連續七天看不到新版;下載 zip 同理會抓到舊檔 ⇒ sha256 不符 ⇒ 更新永遠失敗。
修:manifest 與 zip 下載都帶 ?t=<unix> 繞快取(實測即取得最新)。
不用 raw.githubusercontent——那是實名讀 GitHub,受 D20 頻率閘管制。
另修副作用:檔名要用去掉查詢字串的網址算,否則存成 ...zip?t=1785... 怪檔名。
This commit is contained in:
2026-07-29 22:47:46 +08:00
parent 8dd15fbe43
commit 0c93475ab9
+23 -7
View File
@@ -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=<unix> 實測即取得最新內容。
// (不用 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