mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-08-06 11:18:47 +02:00
refactor: stricter proxy cleanup
This commit is contained in:
@@ -659,6 +659,56 @@ impl CamoufoxManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write explicit proxy prefs to user.js so Firefox always uses the local
|
||||||
|
// donut-proxy and never falls back to stale proxy settings baked into prefs.js
|
||||||
|
// from a previous session. user.js values override prefs.js on every launch.
|
||||||
|
if let Some(proxy_str) = &config.proxy {
|
||||||
|
let user_js_path = profile_path.join("user.js");
|
||||||
|
let mut prefs = String::new();
|
||||||
|
|
||||||
|
// Preserve existing user.js content (ephemeral prefs, etc.)
|
||||||
|
if let Ok(existing) = std::fs::read_to_string(&user_js_path) {
|
||||||
|
// Strip old proxy prefs so we don't duplicate
|
||||||
|
for line in existing.lines() {
|
||||||
|
if !line.contains("network.proxy.") {
|
||||||
|
prefs.push_str(line);
|
||||||
|
prefs.push('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(parsed) = url::Url::parse(proxy_str) {
|
||||||
|
let host = parsed.host_str().unwrap_or("127.0.0.1");
|
||||||
|
let port = parsed.port().unwrap_or(8080);
|
||||||
|
let scheme = parsed.scheme();
|
||||||
|
|
||||||
|
if scheme == "socks5" || scheme == "socks4" {
|
||||||
|
prefs.push_str(&format!(
|
||||||
|
"user_pref(\"network.proxy.type\", 1);\n\
|
||||||
|
user_pref(\"network.proxy.socks\", \"{host}\");\n\
|
||||||
|
user_pref(\"network.proxy.socks_port\", {port});\n\
|
||||||
|
user_pref(\"network.proxy.socks_version\", {});\n\
|
||||||
|
user_pref(\"network.proxy.socks_remote_dns\", true);\n",
|
||||||
|
if scheme == "socks5" { 5 } else { 4 }
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
// HTTP/HTTPS proxy
|
||||||
|
prefs.push_str(&format!(
|
||||||
|
"user_pref(\"network.proxy.type\", 1);\n\
|
||||||
|
user_pref(\"network.proxy.http\", \"{host}\");\n\
|
||||||
|
user_pref(\"network.proxy.http_port\", {port});\n\
|
||||||
|
user_pref(\"network.proxy.ssl\", \"{host}\");\n\
|
||||||
|
user_pref(\"network.proxy.ssl_port\", {port});\n\
|
||||||
|
user_pref(\"network.proxy.no_proxies_on\", \"\");\n"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(e) = std::fs::write(&user_js_path, prefs) {
|
||||||
|
log::warn!("Failed to write proxy prefs to user.js: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
.launch_camoufox(
|
.launch_camoufox(
|
||||||
&app_handle,
|
&app_handle,
|
||||||
|
|||||||
@@ -1005,7 +1005,19 @@ impl ProxyManager {
|
|||||||
Ok(proxy_config) => {
|
Ok(proxy_config) => {
|
||||||
let local_url = format!("http://127.0.0.1:{}", proxy_config.local_port.unwrap_or(0));
|
let local_url = format!("http://127.0.0.1:{}", proxy_config.local_port.unwrap_or(0));
|
||||||
let config_id = proxy_config.id.clone();
|
let config_id = proxy_config.id.clone();
|
||||||
let result = ip_utils::fetch_public_ip(Some(&local_url)).await;
|
// Wrap in a timeout so the check worker doesn't stay alive indefinitely
|
||||||
|
// if the upstream is slow or unreachable.
|
||||||
|
let result = tokio::time::timeout(
|
||||||
|
std::time::Duration::from_secs(30),
|
||||||
|
ip_utils::fetch_public_ip(Some(&local_url)),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap_or_else(|_| {
|
||||||
|
Err(ip_utils::IpError::Network(
|
||||||
|
"Proxy check timed out after 30s".to_string(),
|
||||||
|
))
|
||||||
|
});
|
||||||
|
// Always stop the worker — even if the check failed or timed out
|
||||||
let _ = crate::proxy_runner::stop_proxy_process(&config_id).await;
|
let _ = crate::proxy_runner::stop_proxy_process(&config_id).await;
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@@ -1996,11 +2008,58 @@ impl ProxyManager {
|
|||||||
"Cleaning up orphaned proxy config: {} (proxy process is dead)",
|
"Cleaning up orphaned proxy config: {} (proxy process is dead)",
|
||||||
config.id
|
config.id
|
||||||
);
|
);
|
||||||
// Just delete the config file - the process is already dead
|
|
||||||
use crate::proxy_storage::delete_proxy_config;
|
use crate::proxy_storage::delete_proxy_config;
|
||||||
delete_proxy_config(&config.id);
|
delete_proxy_config(&config.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Kill stale profileless proxy workers — these are check workers
|
||||||
|
// (from check_proxy_validity or similar) that were never cleaned up.
|
||||||
|
// Profile-associated proxies are left alone to avoid the regression
|
||||||
|
// where killing proxies for "dead" browsers on Linux also killed
|
||||||
|
// proxies for running browsers (due to launcher-vs-browser PID mismatch).
|
||||||
|
{
|
||||||
|
use crate::proxy_storage::{is_process_running, list_proxy_configs};
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
|
let now = SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs();
|
||||||
|
|
||||||
|
let all_configs = list_proxy_configs();
|
||||||
|
for config in all_configs {
|
||||||
|
// Only target proxies WITHOUT a profile_id (check workers)
|
||||||
|
if config.profile_id.is_some() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must have a running process to kill
|
||||||
|
let Some(pid) = config.pid else { continue };
|
||||||
|
if !is_process_running(pid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check age: only kill if older than 5 minutes
|
||||||
|
let proxy_age = config
|
||||||
|
.id
|
||||||
|
.strip_prefix("proxy_")
|
||||||
|
.and_then(|s| s.split('_').next())
|
||||||
|
.and_then(|s| s.parse::<u64>().ok())
|
||||||
|
.map(|created_at| now.saturating_sub(created_at))
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
if proxy_age > 300 {
|
||||||
|
log::info!(
|
||||||
|
"Killing stale profileless proxy {} (PID {}, age {}s)",
|
||||||
|
config.id,
|
||||||
|
pid,
|
||||||
|
proxy_age
|
||||||
|
);
|
||||||
|
let _ = crate::proxy_runner::stop_proxy_process(&config.id).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up orphaned VPN worker configs where the worker process is dead
|
// Clean up orphaned VPN worker configs where the worker process is dead
|
||||||
{
|
{
|
||||||
use crate::proxy_storage::is_process_running;
|
use crate::proxy_storage::is_process_running;
|
||||||
|
|||||||
Reference in New Issue
Block a user