Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

curl 續傳後檔案損壞?用強 ETag 綁定每個位元組範圍

位元組位移不是內容身分。使用 Range 與 If-Range,只附加精確的 206;200 時從零重啟,並在原子取代前驗證。

curl 續傳後檔案損壞?用強 ETag 綁定每個位元組範圍
原創示意圖: 200 與 206 的安全寫入分支。 Watch at Ease

安全續傳要求每個附加位元組都來自同一個 HTTP 表示。curl -C - 使用的本機長度只是位移,不是內容身分。

把部分檔綁定最終 URL 與強 ETag,以 Range 加 If-Range 要求剩餘內容,讓 206 或 200 決定附加或完整取代,驗證後才原子改名。

1. 本機長度只是位移,不是身分

curl -C - 會檢查目的檔長度並要求後續位元組,但不能證明遠端仍是同一版本。把最終 URL、強 ETag、本機長度、預期總長與發布者摘要存入綁定單一輸出的旁車。

使用專用 .part 檔,不要讓多個 URL 共用一個 ETag 狀態檔。

2. 續傳前要求強驗證器

送出 Range: bytes=N- 與含已存強 ETag 的 If-Range。RFC 9110 不允許 If-Range 使用弱 ETag;沒有強驗證器時應從零下載到新檔。

--etag-compare 送出 If-None-Match,並不等於 If-Range;包裝程式需明確送出 If-Range 並擷取回應標頭。

3. 依回應選擇寫入模式

只有狀態為 206、Content-Range 從 N 開始、總長合理且驗證器一致時才附加。先寫入暫存尾檔並驗證標頭。

If-Range 不符會回傳完整 200,必須寫入全新完整暫存檔,絕不可附加;416 需要核對長度、總長與驗證器。

4. 只重試傳輸故障

只對已分類的暫時傳輸故障限次退避重試。認證失敗、重新導向改變、缺驗證器、異常狀態、錯誤 Content-Range 或摘要不符都要停止或乾淨重啟。

curl 8.5.0 夾具證明:未驗證的變更物件回傳 206 並產生混合檔;舊 ETag 的 If-Range 回傳 200 並安全取代;未變更物件回傳 206 且摘要一致。

5. 驗證後再原子晉升

完成後優先核對發布者摘要;否則至少核對總長與同一強 ETag,並承認長度不是完整性證明。可用時再跑封存或應用格式檢查。

驗收後才在同一檔案系統原子改名。保留旁車與日誌,隔離不可驗證或已混合的部分檔。

位元組位移不是內容身分。使用 Range 與 If-Range,只附加精確的 206;200 時從零重啟,並在原子取代前驗證。
原創示意圖: 遠端身分、部分檔與驗收證據保持綁定。 Watch at Ease