From 364fb16b7b92adb81db0331336b182076efe3bac Mon Sep 17 00:00:00 2001 From: Tunglies Date: Sun, 9 Mar 2025 00:04:48 +0800 Subject: [PATCH] refactor: streamline clash delay test and improve API interactions --- src-tauri/src/cmd/clash.rs | 80 ++++++++++++----------- src-tauri/src/core/clash_api.rs | 31 --------- src-tauri/src/crate_mihomo_api/src/lib.rs | 18 ++++- 3 files changed, 56 insertions(+), 73 deletions(-) diff --git a/src-tauri/src/cmd/clash.rs b/src-tauri/src/cmd/clash.rs index 8302c73f..ad1e8c61 100644 --- a/src-tauri/src/cmd/clash.rs +++ b/src-tauri/src/cmd/clash.rs @@ -1,10 +1,5 @@ -use crate::{ - config::*, - core::*, - feat, - wrap_err, -}; use super::CmdResult; +use crate::{config::*, core::*, feat, module::mihomo::MihomoManager, wrap_err}; use serde_yaml::Mapping; /// 复制Clash环境变量 @@ -36,8 +31,11 @@ pub async fn patch_clash_mode(payload: String) -> CmdResult { #[tauri::command] pub async fn change_clash_core(clash_core: String) -> CmdResult> { log::info!(target: "app", "changing core to {clash_core}"); - - match CoreManager::global().change_core(Some(clash_core.clone())).await { + + match CoreManager::global() + .change_core(Some(clash_core.clone())) + .await + { Ok(_) => { log::info!(target: "app", "core changed to {clash_core}"); handle::Handle::notice_message("config_core::change_success", &clash_core); @@ -65,11 +63,10 @@ pub async fn clash_api_get_proxy_delay( name: String, url: Option, timeout: i32, -) -> CmdResult { - match clash_api::get_proxy_delay(name, url, timeout).await { - Ok(res) => Ok(res), - Err(err) => Err(err.to_string()), - } +) -> CmdResult { + MihomoManager::global() + .test_proxy_delay(&name, url, timeout) + .await } /// 测试URL延迟 @@ -84,25 +81,26 @@ pub async fn save_dns_config(dns_config: Mapping) -> CmdResult { use crate::utils::dirs; use serde_yaml; use std::fs; - + // 获取DNS配置文件路径 - let dns_path = dirs::app_home_dir().map_err(|e| e.to_string())? + let dns_path = dirs::app_home_dir() + .map_err(|e| e.to_string())? .join("dns_config.yaml"); - + // 保存DNS配置到文件 let yaml_str = serde_yaml::to_string(&dns_config).map_err(|e| e.to_string())?; fs::write(&dns_path, yaml_str).map_err(|e| e.to_string())?; log::info!(target: "app", "DNS config saved to {:?}", dns_path); - + Ok(()) } /// 应用或撤销DNS配置 #[tauri::command] pub fn apply_dns_config(apply: bool) -> CmdResult { - use crate::utils::dirs; - use crate::core::{handle, CoreManager}; use crate::config::Config; + use crate::core::{handle, CoreManager}; + use crate::utils::dirs; use tauri::async_runtime; // 使用spawn来处理异步操作 @@ -116,12 +114,12 @@ pub fn apply_dns_config(apply: bool) -> CmdResult { return; } }; - + if !dns_path.exists() { log::warn!(target: "app", "DNS config file not found"); return; } - + let dns_yaml = match std::fs::read_to_string(&dns_path) { Ok(content) => content, Err(e) => { @@ -129,32 +127,34 @@ pub fn apply_dns_config(apply: bool) -> CmdResult { return; } }; - + // 解析DNS配置并创建patch let patch_config = match serde_yaml::from_str::(&dns_yaml) { Ok(config) => { let mut patch = serde_yaml::Mapping::new(); patch.insert("dns".into(), config.into()); patch - }, + } Err(e) => { log::error!(target: "app", "Failed to parse DNS config: {}", e); return; } }; - + log::info!(target: "app", "Applying DNS config from file"); - + // 重新生成配置,确保DNS配置被正确应用 // 这里不调用patch_clash以避免将DNS配置写入config.yaml - Config::runtime().latest().patch_config(patch_config.clone()); - + Config::runtime() + .latest() + .patch_config(patch_config.clone()); + // 首先重新生成配置 if let Err(err) = Config::generate().await { log::error!(target: "app", "Failed to regenerate config with DNS: {}", err); return; } - + // 然后应用新配置 if let Err(err) = CoreManager::global().update_config().await { log::error!(target: "app", "Failed to apply config with DNS: {}", err); @@ -166,26 +166,26 @@ pub fn apply_dns_config(apply: bool) -> CmdResult { // 当关闭DNS设置时,不需要对配置进行任何修改 // 直接重新生成配置,让enhance函数自动跳过DNS配置的加载 log::info!(target: "app", "DNS settings disabled, regenerating config"); - + // 重新生成配置 if let Err(err) = Config::generate().await { log::error!(target: "app", "Failed to regenerate config: {}", err); return; } - + // 应用新配置 match CoreManager::global().update_config().await { Ok(_) => { log::info!(target: "app", "Config regenerated successfully"); handle::Handle::refresh_clash(); - }, + } Err(err) => { log::error!(target: "app", "Failed to apply regenerated config: {}", err); } } } }); - + Ok(()) } @@ -193,10 +193,11 @@ pub fn apply_dns_config(apply: bool) -> CmdResult { #[tauri::command] pub fn check_dns_config_exists() -> CmdResult { use crate::utils::dirs; - - let dns_path = dirs::app_home_dir().map_err(|e| e.to_string())? + + let dns_path = dirs::app_home_dir() + .map_err(|e| e.to_string())? .join("dns_config.yaml"); - + Ok(dns_path.exists()) } @@ -205,14 +206,15 @@ pub fn check_dns_config_exists() -> CmdResult { pub async fn get_dns_config_content() -> CmdResult { use crate::utils::dirs; use std::fs; - - let dns_path = dirs::app_home_dir().map_err(|e| e.to_string())? + + let dns_path = dirs::app_home_dir() + .map_err(|e| e.to_string())? .join("dns_config.yaml"); - + if !dns_path.exists() { return Err("DNS config file not found".into()); } - + let content = fs::read_to_string(&dns_path).map_err(|e| e.to_string())?; Ok(content) } diff --git a/src-tauri/src/core/clash_api.rs b/src-tauri/src/core/clash_api.rs index dd085dd0..8d39a9d4 100644 --- a/src-tauri/src/core/clash_api.rs +++ b/src-tauri/src/core/clash_api.rs @@ -1,7 +1,6 @@ use crate::config::Config; use anyhow::Result; use reqwest::header::HeaderMap; -use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Default, PartialEq)] pub struct Rate { @@ -9,36 +8,6 @@ pub struct Rate { pub down: u64, } -#[derive(Default, Debug, Clone, Deserialize, Serialize)] -pub struct DelayRes { - delay: u64, -} - -/// GET /proxies/{name}/delay -/// 获取代理延迟 -pub async fn get_proxy_delay( - name: String, - test_url: Option, - timeout: i32, -) -> Result { - let (url, headers) = clash_client_info()?; - let url = format!("{url}/proxies/{name}/delay"); - - let default_url = "http://cp.cloudflare.com/generate_204"; - let test_url = test_url - .map(|s| if s.is_empty() { default_url.into() } else { s }) - .unwrap_or(default_url.into()); - - let client = reqwest::ClientBuilder::new().no_proxy().build()?; - let builder = client - .get(&url) - .headers(headers) - .query(&[("timeout", &format!("{timeout}")), ("url", &test_url)]); - let response = builder.send().await?; - - Ok(response.json::().await?) -} - /// 根据clash info获取clash服务地址和请求头 pub fn clash_client_info() -> Result<(String, HeaderMap)> { let client = { Config::clash().data().get_client_info() }; diff --git a/src-tauri/src/crate_mihomo_api/src/lib.rs b/src-tauri/src/crate_mihomo_api/src/lib.rs index 5f98da92..03fd819f 100644 --- a/src-tauri/src/crate_mihomo_api/src/lib.rs +++ b/src-tauri/src/crate_mihomo_api/src/lib.rs @@ -96,7 +96,7 @@ impl MihomoManager { let payload = serde_json::json!({ "path": clash_config_path, }); - let response = self.send_request("PUT", url, Some(payload)).await.unwrap(); + let response = self.send_request("PUT", url, Some(payload)).await?; if response["code"] == 204 { Ok(()) } else { @@ -109,7 +109,7 @@ impl MihomoManager { pub async fn patch_configs(&self, config: serde_json::Value) -> Result<(), String> { let url = format!("{}/configs", self.mihomo_server); - let response = self.send_request("PATCH", url, Some(config)).await.unwrap(); + let response = self.send_request("PATCH", url, Some(config)).await?; if response["code"] == 204 { Ok(()) } else { @@ -119,4 +119,16 @@ impl MihomoManager { .to_string()) } } -} + + pub async fn test_proxy_delay( + &self, + name: &str, + test_url: Option, + timeout: i32, + ) -> Result { + let test_url = test_url.unwrap_or("http://cp.cloudflare.com/generate_204".to_string()); + let url = format!("{}/proxies/{}/delay?url={}&timeout={}", self.mihomo_server, name, test_url, timeout); + let response = self.send_request("GET", url, None).await?; + return Ok(response); + } +} \ No newline at end of file