mirror of
https://github.com/nimbold/Firelink.git
synced 2026-08-07 09:53:17 +00:00
feat(torrents): add peer discovery controls
This commit is contained in:
@@ -14,6 +14,22 @@ fn default_sidebar_position() -> String {
|
||||
"auto".to_string()
|
||||
}
|
||||
|
||||
fn default_torrent_enable_dht() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_torrent_enable_dht6() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn default_torrent_enable_pex() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_torrent_enable_lpd() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[ts(export, export_to = "../../src/bindings/")]
|
||||
@@ -408,6 +424,14 @@ pub struct PersistedSettings {
|
||||
pub proxy_mode: ProxyMode,
|
||||
pub proxy_host: String,
|
||||
pub proxy_port: u16,
|
||||
#[serde(default = "default_torrent_enable_dht")]
|
||||
pub torrent_enable_dht: bool,
|
||||
#[serde(default = "default_torrent_enable_dht6")]
|
||||
pub torrent_enable_dht6: bool,
|
||||
#[serde(default = "default_torrent_enable_pex")]
|
||||
pub torrent_enable_pex: bool,
|
||||
#[serde(default = "default_torrent_enable_lpd")]
|
||||
pub torrent_enable_lpd: bool,
|
||||
pub custom_user_agent: String,
|
||||
pub ask_where_to_save_each_file: bool,
|
||||
pub remember_last_used_download_directory: bool,
|
||||
|
||||
@@ -6324,6 +6324,23 @@ pub(crate) fn normalize_speed_limit_for_aria2(limit: &str) -> Option<String> {
|
||||
})
|
||||
}
|
||||
|
||||
fn apply_aria2_torrent_peer_discovery_options(
|
||||
command: &mut std::process::Command,
|
||||
enable_dht: bool,
|
||||
enable_dht6: bool,
|
||||
enable_pex: bool,
|
||||
enable_lpd: bool,
|
||||
) {
|
||||
// These are daemon-global BitTorrent options. Keep them explicit at
|
||||
// launch so Firelink does not silently inherit a different aria2
|
||||
// configuration from the host or a future bundled-engine default.
|
||||
command
|
||||
.arg(format!("--enable-dht={enable_dht}"))
|
||||
.arg(format!("--enable-dht6={enable_dht6}"))
|
||||
.arg(format!("--enable-peer-exchange={enable_pex}"))
|
||||
.arg(format!("--bt-enable-lpd={enable_lpd}"));
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn set_global_speed_limit(
|
||||
state: tauri::State<'_, AppState>,
|
||||
@@ -7400,6 +7417,7 @@ mod tests {
|
||||
cookie_scope_for_url, metadata_authentication_error, metadata_cookie_header_present,
|
||||
metadata_headers, metadata_response_error,
|
||||
normalize_speed_limit_for_aria2,
|
||||
apply_aria2_torrent_peer_discovery_options,
|
||||
parse_firelink_deep_link, parse_ffmpeg_version, parse_media_progress_line,
|
||||
redact_log_line, redact_log_line_for_output, sanitize_ytdlp_config_value,
|
||||
has_resumable_download_assets, is_media_artifact_name,
|
||||
@@ -7429,6 +7447,25 @@ mod tests {
|
||||
assert!(validate_keychain_grant_request_id(&"x".repeat(129)).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn aria2_torrent_peer_discovery_options_are_explicit_and_launch_scoped() {
|
||||
let mut command = std::process::Command::new("aria2c");
|
||||
apply_aria2_torrent_peer_discovery_options(&mut command, false, true, false, true);
|
||||
let args = command
|
||||
.get_args()
|
||||
.map(|arg| arg.to_string_lossy().into_owned())
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(
|
||||
args,
|
||||
vec![
|
||||
"--enable-dht=false",
|
||||
"--enable-dht6=true",
|
||||
"--enable-peer-exchange=false",
|
||||
"--bt-enable-lpd=true",
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn aria2_active_connection_count_uses_only_nonnegative_daemon_values() {
|
||||
assert_eq!(
|
||||
@@ -10033,6 +10070,17 @@ pub fn run() {
|
||||
.as_ref()
|
||||
.map(|settings| settings.global_speed_limit.clone())
|
||||
.unwrap_or_default();
|
||||
let torrent_peer_discovery = persisted_settings
|
||||
.as_ref()
|
||||
.map(|settings| {
|
||||
(
|
||||
settings.torrent_enable_dht,
|
||||
settings.torrent_enable_dht6,
|
||||
settings.torrent_enable_pex,
|
||||
settings.torrent_enable_lpd,
|
||||
)
|
||||
})
|
||||
.unwrap_or((true, false, true, false));
|
||||
|
||||
let aria2_secret_clone = aria2_secret.clone();
|
||||
let app_handle_bg = app.handle().clone();
|
||||
@@ -10067,6 +10115,14 @@ pub fn run() {
|
||||
.arg("--check-certificate=true")
|
||||
.arg(format!("--stop-with-process={}", std::process::id()));
|
||||
|
||||
apply_aria2_torrent_peer_discovery_options(
|
||||
&mut cmd,
|
||||
torrent_peer_discovery.0,
|
||||
torrent_peer_discovery.1,
|
||||
torrent_peer_discovery.2,
|
||||
torrent_peer_discovery.3,
|
||||
);
|
||||
|
||||
if let Some(limit) = normalize_speed_limit_for_aria2(&global_speed_limit) {
|
||||
cmd.arg(format!("--max-overall-download-limit={}", limit));
|
||||
}
|
||||
|
||||
@@ -188,6 +188,14 @@ fn sanitize_persisted_setting_values(state: &mut Value) {
|
||||
sanitize_integer_setting(state, "maxConcurrentDownloads", |value| value.as_u64().is_some());
|
||||
sanitize_integer_setting(state, "perServerConnections", |value| value.as_i64().is_some());
|
||||
sanitize_integer_setting(state, "maxAutomaticRetries", |value| value.as_i64().is_some());
|
||||
for key in [
|
||||
"torrentEnableDht",
|
||||
"torrentEnableDht6",
|
||||
"torrentEnablePex",
|
||||
"torrentEnableLpd",
|
||||
] {
|
||||
sanitize_boolean_setting(state, key);
|
||||
}
|
||||
sanitize_allowed_string(
|
||||
state,
|
||||
"theme",
|
||||
@@ -273,6 +281,12 @@ fn sanitize_integer_setting(
|
||||
}
|
||||
}
|
||||
|
||||
fn sanitize_boolean_setting(state: &mut serde_json::Map<String, Value>, key: &str) {
|
||||
if state.get(key).is_some_and(|value| !value.is_boolean()) {
|
||||
state.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
fn sanitize_allowed_string(
|
||||
state: &mut serde_json::Map<String, Value>,
|
||||
key: &str,
|
||||
@@ -482,6 +496,10 @@ fn default_settings() -> PersistedSettings {
|
||||
proxy_mode: ProxyMode::None,
|
||||
proxy_host: String::new(),
|
||||
proxy_port: 8080,
|
||||
torrent_enable_dht: true,
|
||||
torrent_enable_dht6: false,
|
||||
torrent_enable_pex: true,
|
||||
torrent_enable_lpd: false,
|
||||
custom_user_agent: String::new(),
|
||||
ask_where_to_save_each_file: false,
|
||||
remember_last_used_download_directory: false,
|
||||
@@ -770,6 +788,10 @@ mod tests {
|
||||
"maxConcurrentDownloads": "not-a-number",
|
||||
"perServerConnections": 5,
|
||||
"showNotifications": "yes",
|
||||
"torrentEnableDht": "yes",
|
||||
"torrentEnableDht6": 1,
|
||||
"torrentEnablePex": null,
|
||||
"torrentEnableLpd": [],
|
||||
"theme": "not-a-theme",
|
||||
"calendarPreference": "lunar",
|
||||
"siteLogins": [{"id": "valid", "urlPattern": "example.com", "username": "user"}, {"id": 3}]
|
||||
@@ -783,6 +805,10 @@ mod tests {
|
||||
assert_eq!(settings.max_concurrent_downloads, 3);
|
||||
assert_eq!(settings.per_server_connections, 5);
|
||||
assert!(settings.show_notifications);
|
||||
assert!(settings.torrent_enable_dht);
|
||||
assert!(!settings.torrent_enable_dht6);
|
||||
assert!(settings.torrent_enable_pex);
|
||||
assert!(!settings.torrent_enable_lpd);
|
||||
assert!(matches!(settings.theme, crate::ipc::Theme::System));
|
||||
assert!(matches!(
|
||||
settings.calendar_preference,
|
||||
|
||||
Reference in New Issue
Block a user