feat: sysproxy guard can detect and recover from unexpected changes

This commit is contained in:
wonfen 2025-04-24 09:09:23 +08:00
parent 65ed9cb5b2
commit 0bb042e085
2 changed files with 121 additions and 75 deletions

View File

@ -25,6 +25,7 @@
- Webdav 支持目录重定向 - Webdav 支持目录重定向
- 移除 Webdav 跨平台备份恢复限制 - 移除 Webdav 跨平台备份恢复限制
- 增强 Webdav 备份目录检查和文件上传重试机制 - 增强 Webdav 备份目录检查和文件上传重试机制
- 系统代理守卫可检查意外设置变更并恢复
#### 优化了: #### 优化了:
- 系统代理 Bypass 设置 - 系统代理 Bypass 设置

View File

@ -333,45 +333,36 @@ impl Sysopt {
log::debug!(target: "app", "try to guard the system proxy"); log::debug!(target: "app", "try to guard the system proxy");
let sysproxy = Sysproxy::get_system_proxy(); // 获取期望的代理端口
let autoproxy = Autoproxy::get_auto_proxy(); let port = Config::verge()
if sysproxy.is_err() || autoproxy.is_err() {
log::error!(target: "app", "failed to get the system proxy");
continue;
}
let sysproxy_enable = sysproxy.ok().map(|s| s.enable).unwrap_or(false);
let autoproxy_enable = autoproxy.ok().map(|s| s.enable).unwrap_or(false);
if sysproxy_enable || autoproxy_enable {
continue;
}
let port = {
Config::verge()
.latest() .latest()
.verge_mixed_port .verge_mixed_port
.unwrap_or(Config::clash().data().get_mixed_port()) .unwrap_or(Config::clash().data().get_mixed_port());
};
let pac_port = IVerge::get_singleton_port(); let pac_port = IVerge::get_singleton_port();
#[cfg(not(target_os = "windows"))] let bypass = get_bypass();
{
// 检查系统代理配置
if pac { if pac {
let autoproxy = Autoproxy { // 检查 PAC 代理设置
enable: true, let expected_url = format!("http://{}:{}/commands/pac", proxy_host, pac_port);
url: format!("http://{}:{}/commands/pac", proxy_host, pac_port), let autoproxy = match Autoproxy::get_auto_proxy() {
}; Ok(ap) => ap,
logging_error!(Type::System, true, autoproxy.set_auto_proxy()); Err(e) => {
} else { log::error!(target: "app", "failed to get the auto proxy: {}", e);
let sysproxy = Sysproxy { continue;
enable: true, }
host: proxy_host,
port,
bypass: get_bypass(),
}; };
logging_error!(Type::System, true, sysproxy.set_system_proxy()); // 检查自动代理是否启用且URL是否正确
} if !autoproxy.enable || autoproxy.url != expected_url {
log::info!(target: "app", "auto proxy settings changed, restoring...");
#[cfg(not(target_os = "windows"))]
{
let new_autoproxy = Autoproxy {
enable: true,
url: expected_url,
};
logging_error!(Type::System, true, new_autoproxy.set_auto_proxy());
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@ -380,38 +371,92 @@ impl Sysopt {
use tauri_plugin_shell::ShellExt; use tauri_plugin_shell::ShellExt;
let app_handle = Handle::global().app_handle().unwrap(); let app_handle = Handle::global().app_handle().unwrap();
let binary_path = match dirs::service_path() {
Ok(path) => path,
Err(e) => {
log::error!(target: "app", "failed to get service path: {}", e);
continue;
}
};
let binary_path = dirs::service_path().unwrap();
let sysproxy_exe = binary_path.with_file_name("sysproxy.exe"); let sysproxy_exe = binary_path.with_file_name("sysproxy.exe");
if !sysproxy_exe.exists() { if !sysproxy_exe.exists() {
break; log::error!(target: "app", "sysproxy.exe not found");
continue;
} }
let shell = app_handle.shell(); let shell = app_handle.shell();
let output = if pac { let output = shell
let address = format!("http://{}:{}/commands/pac", proxy_host, pac_port);
shell
.command(sysproxy_exe.as_path().to_str().unwrap()) .command(sysproxy_exe.as_path().to_str().unwrap())
.args(["pac", address.as_str()]) .args(["pac", expected_url.as_str()])
.output() .output()
.await .await
.unwrap() .unwrap();
} else {
let address = format!("{}:{}", proxy_host, port);
let bypass = get_bypass();
shell if !output.status.success() {
log::error!(target: "app", "failed to set auto proxy");
}
}
}
} else {
// 检查常规系统代理设置
let sysproxy = match Sysproxy::get_system_proxy() {
Ok(sp) => sp,
Err(e) => {
log::error!(target: "app", "failed to get the system proxy: {}", e);
continue;
}
};
// 检查系统代理是否启用且配置是否匹配
if !sysproxy.enable || sysproxy.host != proxy_host || sysproxy.port != port {
log::info!(target: "app", "system proxy settings changed, restoring...");
#[cfg(not(target_os = "windows"))]
{
let new_sysproxy = Sysproxy {
enable: true,
host: proxy_host.clone(),
port,
bypass: bypass.clone(),
};
logging_error!(Type::System, true, new_sysproxy.set_system_proxy());
}
#[cfg(target_os = "windows")]
{
use crate::{core::handle::Handle, utils::dirs};
use tauri_plugin_shell::ShellExt;
let app_handle = Handle::global().app_handle().unwrap();
let binary_path = match dirs::service_path() {
Ok(path) => path,
Err(e) => {
log::error!(target: "app", "failed to get service path: {}", e);
continue;
}
};
let sysproxy_exe = binary_path.with_file_name("sysproxy.exe");
if !sysproxy_exe.exists() {
log::error!(target: "app", "sysproxy.exe not found");
continue;
}
let address = format!("{}:{}", proxy_host, port);
let shell = app_handle.shell();
let output = shell
.command(sysproxy_exe.as_path().to_str().unwrap()) .command(sysproxy_exe.as_path().to_str().unwrap())
.args(["global", address.as_str(), bypass.as_ref()]) .args(["global", address.as_str(), bypass.as_ref()])
.output() .output()
.await .await
.unwrap() .unwrap();
};
if !output.status.success() { if !output.status.success() {
break; log::error!(target: "app", "failed to set system proxy");
}
}
}
} }
};
} }
}); });
} }