From 8cf8c04ab9b5a1f5bc7a8eb3230698f07fb7c204 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 23 Aug 2026 21:34:24 +0900 Subject: fix(curl-downloader): flush a downloaded file before it is read back tokio's File returns from write_all once the blocking write is queued, so the tail of the response body was still in flight when the download future resolved. The caller then renamed the file, stat'd it and copied it into the cache, so a package could land in the file cache truncated. The first run still extracted the complete file and only a later run reading that cache entry failed with "End-of-central-directory signature not found". Flushing also surfaces the last write's error, which used to be dropped. Co-Authored-By: Claude Opus 5 (1M context) --- crates/shirabe/src/util/http/curl_downloader.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'crates/shirabe/src') diff --git a/crates/shirabe/src/util/http/curl_downloader.rs b/crates/shirabe/src/util/http/curl_downloader.rs index 049b77b9..04c4753f 100644 --- a/crates/shirabe/src/util/http/curl_downloader.rs +++ b/crates/shirabe/src/util/http/curl_downloader.rs @@ -642,7 +642,13 @@ impl CurlDownloader { } Ok(match sink { - Sink::File(_) => Body::File, + Sink::File(mut f) => { + // tokio's File returns from write_all once the blocking write is queued, so the + // tail of the body can still be in flight after the loop above. flush waits for it + // and reports its error; without it the caller renames and copies a short file. + f.flush().await.map_err(|e| (e.to_string(), false))?; + Body::File + } Sink::Memory(buf) => Body::Memory(buf), }) } -- cgit v1.3.1-4-g156e