diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 5392668..fb410e2 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -2061,13 +2061,10 @@ const MEDIA_METADATA_TIMEOUT: Duration = Duration::from_secs(55); const MEDIA_METADATA_CACHE_MAX_ENTRIES: usize = 128; const FILE_METADATA_TIMEOUT: Duration = Duration::from_secs(20); const MAX_SHELL_OUTPUT_BYTES: usize = 32 * 1024 * 1024; -const MEDIA_CONNECTIONS_MIN: i32 = 1; -const MEDIA_CONNECTIONS_MAX: i32 = 16; - fn normalize_media_connections(connections: Option) -> i32 { - connections - .unwrap_or(MEDIA_CONNECTIONS_MAX) - .clamp(MEDIA_CONNECTIONS_MIN, MEDIA_CONNECTIONS_MAX) + crate::queue::clamp_download_connections( + connections.unwrap_or(crate::queue::DOWNLOAD_CONNECTIONS_MAX), + ) } struct ShellCommandOutput { diff --git a/src-tauri/src/queue.rs b/src-tauri/src/queue.rs index fc8f089..c3d954a 100644 --- a/src-tauri/src/queue.rs +++ b/src-tauri/src/queue.rs @@ -15,6 +15,12 @@ use ts_rs::TS; /// Default capacity when no setting is read yet. pub const DEFAULT_MAX_CONCURRENT: usize = 3; pub const MEDIA_RUN_CANCELLED: &str = "__firelink_media_run_cancelled__"; +pub const DOWNLOAD_CONNECTIONS_MIN: i32 = 1; +pub const DOWNLOAD_CONNECTIONS_MAX: i32 = 16; + +pub fn clamp_download_connections(connections: i32) -> i32 { + connections.clamp(DOWNLOAD_CONNECTIONS_MIN, DOWNLOAD_CONNECTIONS_MAX) +} type Aria2ControlLocks = Arc>>>>; @@ -481,6 +487,7 @@ impl QueueManager { .await .get(id) .and_then(|payload| payload.connections) + .map(clamp_download_connections) } pub fn set_aria2_global_speed_limit(&self, limit: Option) { @@ -1670,7 +1677,11 @@ enum BoundedRangeSupport { } async fn effective_aria2_connections(id: &str, payload: &SpawnPayload) -> i32 { - let requested = payload.connections.unwrap_or(1).max(1); + let requested = clamp_download_connections( + payload + .connections + .unwrap_or(DOWNLOAD_CONNECTIONS_MIN), + ); if requested <= 1 { return requested; } @@ -1876,7 +1887,7 @@ fn apply_aria2_connection_options( options: &mut serde_json::Map, connections: i32, ) { - let connections = connections.max(1); + let connections = clamp_download_connections(connections); options.insert( "split".to_string(), serde_json::json!(connections.to_string()), @@ -2275,6 +2286,19 @@ mod tests { ); } + #[test] + fn aria2_connection_options_clamp_untrusted_connection_counts() { + let mut options = serde_json::Map::new(); + + apply_aria2_connection_options(&mut options, i32::MAX); + + assert_eq!(options.get("split"), Some(&serde_json::json!("16"))); + assert_eq!( + options.get("max-connection-per-server"), + Some(&serde_json::json!("16")) + ); + } + #[test] fn bounded_range_probe_accepts_exact_requested_byte() { assert_eq!(