diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-23 21:34:24 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-23 21:34:24 +0900 |
| commit | 8cf8c04ab9b5a1f5bc7a8eb3230698f07fb7c204 (patch) | |
| tree | 28cb3494817e912000a30636f63002f714041fde /crates | |
| parent | b8da2bec0f4622dc761ccb9a5f686f30dcd039e7 (diff) | |
| download | php-shirabe-8cf8c04ab9b5a1f5bc7a8eb3230698f07fb7c204.tar.gz php-shirabe-8cf8c04ab9b5a1f5bc7a8eb3230698f07fb7c204.tar.zst php-shirabe-8cf8c04ab9b5a1f5bc7a8eb3230698f07fb7c204.zip | |
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) <noreply@anthropic.com>
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/shirabe/src/util/http/curl_downloader.rs | 8 |
1 files changed, 7 insertions, 1 deletions
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), }) } |
