From 137ef7705cda9b2e6f51e86c6a100b089d9060ff Mon Sep 17 00:00:00 2001 From: Naz Date: Tue, 5 Aug 2025 14:10:43 +0100 Subject: =?UTF-8?q?=F0=9F=90=9Bfix:=20download=20to=20a=20temporary=20path?= =?UTF-8?q?=20that=20will=20be=20removed=20on=20failure=20or=20renamed=20o?= =?UTF-8?q?n=20success?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/downloader.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/downloader.rs') diff --git a/src/downloader.rs b/src/downloader.rs index e40d5d1..f402c4e 100644 --- a/src/downloader.rs +++ b/src/downloader.rs @@ -60,6 +60,8 @@ impl Downloader { pub async fn download_with_progress(&self, url: &str, path: &PathBuf) -> Result<()> { fs::create_dir_all(&appimages_dir()?).await?; + let temp_path = PathBuf::from(format!("{}.part", path.display())); + let resp = reqwest::get(&url.to_string()) .await .map_err(|source| Error::Download { @@ -72,15 +74,21 @@ impl Downloader { let total_size = resp.content_length().unwrap_or(0); let bar = make_progress_bar(total_size)?; - let mut out = tokio::fs::File::create(&path).await?; + let mut out = tokio::fs::File::create(&temp_path).await?; // Stream download with progress updates let mut stream = resp.bytes_stream(); while let Some(chunk) = stream.next().await { - let chunk = chunk.map_err(|source| Error::Download { - url: url.to_string(), - source, - })?; + let chunk = match chunk { + Ok(chunk) => chunk, + Err(source) => { + fs::remove_file(temp_path).await?; + return Err(Error::Download { + url: url.to_string(), + source, + }); + } + }; let len = chunk.len() as u64; out.write_all(&chunk).await?; bar.inc(len); @@ -88,6 +96,8 @@ impl Downloader { bar.finish_with_message("Download complete!"); + fs::rename(temp_path, path).await?; + // Make executable #[cfg(unix)] { -- cgit v1.2.3