diff options
| author | 2026-01-14 05:12:31 +0100 | |
|---|---|---|
| committer | 2026-01-14 05:12:31 +0100 | |
| commit | f093d2a310627aa3ee5a2820339f8a18bd251e81 (patch) | |
| tree | c3d1cdda9f1b8fed6adb5f0dfd17bfa5c81ecb36 /src-tauri/src/core/downloader.rs | |
| parent | f1babdf9a625ddbb661f4e0678e6258511347656 (diff) | |
| download | DropOut-f093d2a310627aa3ee5a2820339f8a18bd251e81.tar.gz DropOut-f093d2a310627aa3ee5a2820339f8a18bd251e81.zip | |
feat(java): integrate Adoptium API for Java runtime download
Add automatic Java (Temurin) download and installation feature:
- Add Adoptium API v3 integration to fetch latest Java releases
- Support JRE and JDK image types with version selection (8/11/17/21)
- Implement platform detection for macOS, Linux, and Windows
- Add SHA256 checksum verification for downloaded archives
- Add tar.gz extraction support with Unix permission preservation
- Handle macOS-specific Java path structure (Contents/Home/bin)
- Add frontend UI with version selector and download progress
- Register Tauri commands: fetch_adoptium_java, download_adoptium_java,
fetch_available_java_versions
Dependencies added: sha2, flate2, tar, dirs
Diffstat (limited to 'src-tauri/src/core/downloader.rs')
| -rw-r--r-- | src-tauri/src/core/downloader.rs | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/src-tauri/src/core/downloader.rs b/src-tauri/src/core/downloader.rs index 5f6ec80..09101c9 100644 --- a/src-tauri/src/core/downloader.rs +++ b/src-tauri/src/core/downloader.rs @@ -1,5 +1,6 @@ use futures::StreamExt; use serde::{Deserialize, Serialize}; +use sha1::Digest as Sha1Digest; use std::path::PathBuf; use std::sync::Arc; use tauri::{Emitter, Window}; @@ -10,7 +11,10 @@ use tokio::sync::Semaphore; pub struct DownloadTask { pub url: String, pub path: PathBuf, + #[serde(default)] pub sha1: Option<String>, + #[serde(default)] + pub sha256: Option<String>, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -21,6 +25,32 @@ pub struct ProgressEvent { pub status: String, // "Downloading", "Verifying", "Finished", "Error" } +/// calculate SHA256 hash of data +pub fn compute_sha256(data: &[u8]) -> String { + let mut hasher = sha2::Sha256::new(); + hasher.update(data); + hex::encode(hasher.finalize()) +} + +/// calculate SHA1 hash of data +pub fn compute_sha1(data: &[u8]) -> String { + let mut hasher = sha1::Sha1::new(); + hasher.update(data); + hex::encode(hasher.finalize()) +} + +/// verify file checksum, prefer SHA256, fallback to SHA1 +pub fn verify_checksum(data: &[u8], sha256: Option<&str>, sha1: Option<&str>) -> bool { + if let Some(expected) = sha256 { + return compute_sha256(data) == expected; + } + if let Some(expected) = sha1 { + return compute_sha1(data) == expected; + } + // No checksum provided, default to true + true +} + pub async fn download_files(window: Window, tasks: Vec<DownloadTask>) -> Result<(), String> { let client = reqwest::Client::new(); let semaphore = Arc::new(Semaphore::new(10)); // Max 10 concurrent downloads @@ -37,7 +67,7 @@ pub async fn download_files(window: Window, tasks: Vec<DownloadTask>) -> Result< let _permit = semaphore.acquire().await.unwrap(); let file_name = task.path.file_name().unwrap().to_string_lossy().to_string(); - // 1. Check if file exists and verify SHA1 + // 1. Check if file exists and verify checksum if task.path.exists() { let _ = window.emit( "download-progress", @@ -49,13 +79,13 @@ pub async fn download_files(window: Window, tasks: Vec<DownloadTask>) -> Result< }, ); - if let Some(expected_sha1) = &task.sha1 { + if task.sha256.is_some() || task.sha1.is_some() { if let Ok(data) = tokio::fs::read(&task.path).await { - let mut hasher = sha1::Sha1::new(); - use sha1::Digest; - hasher.update(&data); - let result = hex::encode(hasher.finalize()); - if &result == expected_sha1 { + if verify_checksum( + &data, + task.sha256.as_deref(), + task.sha1.as_deref(), + ) { // Already valid let _ = window.emit( "download-progress", |