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

科技 · 實用指南

curl 錯誤 18?重試或續傳前先證明缺失位元組

CURLE_PARTIAL_FILE 表示實際收到的大小與對端先前宣告的大小不一致。先保留殘缺檔案、回應標頭與追蹤,再區分訊息分幀、協定和中介層,最後決定重新下載或綁定驗證器的續傳。

終端顯示傳輸中斷、旁邊是網路設備的原創編輯圖片。
原創插畫:修改重試或協定前,先保留殘缺檔案與第一次追蹤。 Watch at Ease

curl 錯誤 18 是傳輸大小不一致的證據,不是單一網路故障的最終診斷。curl 專案把 CURLE_PARTIAL_FILE 定義為實際傳輸比先前回報的大小更短或更長。

不要立刻覆蓋第一次殘缺檔案,也不要先開啟自動重試。先記錄回應分幀、收到的位元組與表示物件身分,再逐一驗證伺服器、代理、協定或客戶端路徑。

1. 凍結第一次失敗證據

把残缺输出移到唯一命名的證據檔案,不要直接覆盖;記錄位元組数和摘要。同時儲存 curl 版本與功能、去除秘密後的命令、起止時间、退出码、远端 URL、代理路徑以及是否由包装器或 CI 调用。

只做一次新的證據采集:回應头单独儲存,時间戳跟踪中刪除 Authorization、Cookie、签名查询和客户端證書。重試可能命中不同後端或新對象,所以第一次跟踪尤其重要。

2. 先讀分幀,再判斷網路

HTTP/1.1 中,若最终 Transfer-Encoding 為 chunked,必須讀到零長度终止块;若没有 Transfer-Encoding 且 Content-Length 有效,該十進制值就是预期正文長度。連接在达到該值前關闭,RFC 9112 將其视為不完整。

内容编码與傳输编码必須分開。gzip 或 br 描述表示對象编码,chunked 描述消息分帧。改變 Accept-Encoding 或强制 HTTP/1.0 只能用于隔离分支,不能自动修复錯誤長度、源程序截斷或中间層故障。

3. 每次只改變一個邊界

每次寫入新的输出,只改變一個条件:直連源站與代理/CDN、有效的 IPv4 與 IPv6、HTTP/1.1 與 HTTP/2/3、壓縮與 identity。逐次記錄狀態、最终 URL、協定、声明長度、下载位元組、退出码和摘要。

某一路徑成功并不證明另一路徑安全。源站成功而代理截斷時,保留兩份跟踪交给中间層负责人;所有路徑都停在同一位元組時,應檢查源應用、上游超時、Content-Length 生成和存储讀取錯誤。

4. 判斷殘缺位元組是否可用

不能只看 200 狀態。至少要求 curl 退出码為 0、位元組数或分帧完成,并通過發布方校验和、签名、壓縮包测試或應用解析器等對象級完整性信號。二進制檔案名下的 HTML 錯誤頁仍是失败。

API 還要验證回應结构和预期副作用。非幂等 POST 可能已在伺服器提交,只是回應被截斷;重試前先查幂等键、事务编號或狀態接口。

5. 只在契約明確時續傳

只有伺服器支持所需位元組范围且远端表示對象未變化時才能續傳。儲存 ETag 或 Last-Modified,在流程支持時使用条件范围请求,并确認伺服器返回预期部分狀態和范围,而不是新的完整正文。

驗證器缺失、過弱或已變化時,必須寫入全新目标,绝不盲目追加。只有退出码、分帧、位元組数和完整性全部通過,并且故障路徑已修复或移出生产,才算關闭問题。

工程師比對 HTTP 回應標頭、位元組數和校驗和的原創編輯圖片。
原創插畫:接受或續傳前,核對分幀、收到的位元組與表示物件身分。 Watch at Ease