From cd6eb26a4124fbfef3f7b1b1432c0c75b9f42bff Mon Sep 17 00:00:00 2001 From: wonfen Date: Sun, 9 Mar 2025 02:34:57 +0800 Subject: [PATCH] feat: add icon file content check to prevent saving failed downloads --- src-tauri/src/cmd/app.rs | 74 +++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/src-tauri/src/cmd/app.rs b/src-tauri/src/cmd/app.rs index d7c1f901..0d110c2d 100644 --- a/src-tauri/src/cmd/app.rs +++ b/src-tauri/src/cmd/app.rs @@ -90,42 +90,62 @@ pub async fn download_icon_cache(url: String, name: String) -> CmdResult let temp_path = icon_cache_dir.join(format!("{}.downloading", &name)); // 下载文件到临时位置 - let response = wrap_err!(reqwest::get(url).await)?; + let response = wrap_err!(reqwest::get(&url).await)?; + + // 检查内容类型是否为图片 + let content_type = response.headers() + .get(reqwest::header::CONTENT_TYPE) + .and_then(|v| v.to_str().ok()) + .unwrap_or(""); + + let is_image = content_type.starts_with("image/"); + + // 获取响应内容 let content = wrap_err!(response.bytes().await)?; - // 写入临时文件 - { - let mut file = match std::fs::File::create(&temp_path) { - Ok(file) => file, - Err(_) => { - if icon_path.exists() { - return Ok(icon_path.to_string_lossy().to_string()); - } else { - return Err("Failed to create temporary file".into()); - } - } - }; - - wrap_err!(std::io::copy(&mut content.as_ref(), &mut file))?; - } + // 检查内容是否为HTML (针对CDN错误页面) + let is_html = content.len() > 15 && + (content.starts_with(b" {}, - Err(_) => { - let _ = std::fs::remove_file(&temp_path); - if icon_path.exists() { - return Ok(icon_path.to_string_lossy().to_string()); + // 只有当内容确实是图片时才保存 + if is_image && !is_html { + { + let mut file = match std::fs::File::create(&temp_path) { + Ok(file) => file, + Err(_) => { + if icon_path.exists() { + return Ok(icon_path.to_string_lossy().to_string()); + } else { + return Err("Failed to create temporary file".into()); + } + } + }; + + wrap_err!(std::io::copy(&mut content.as_ref(), &mut file))?; + } + + // 再次检查目标文件是否已存在,避免重命名覆盖其他线程已完成的文件 + if !icon_path.exists() { + match std::fs::rename(&temp_path, &icon_path) { + Ok(_) => {}, + Err(_) => { + let _ = std::fs::remove_file(&temp_path); + if icon_path.exists() { + return Ok(icon_path.to_string_lossy().to_string()); + } } } + } else { + let _ = std::fs::remove_file(&temp_path); } + + Ok(icon_path.to_string_lossy().to_string()) } else { let _ = std::fs::remove_file(&temp_path); + Err(format!("下载的内容不是有效图片: {}", url).into()) } - - Ok(icon_path.to_string_lossy().to_string()) } #[derive(Debug, serde::Serialize, serde::Deserialize)]