refactor: streamline clash delay test and improve API interactions

This commit is contained in:
Tunglies 2025-03-09 00:04:48 +08:00
parent 634ed9cb46
commit 364fb16b7b
3 changed files with 56 additions and 73 deletions

View File

@ -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<Option<String>> {
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<String>,
timeout: i32,
) -> CmdResult<clash_api::DelayRes> {
match clash_api::get_proxy_delay(name, url, timeout).await {
Ok(res) => Ok(res),
Err(err) => Err(err.to_string()),
}
) -> CmdResult<serde_json::Value> {
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::<serde_yaml::Mapping>(&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<bool> {
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<bool> {
pub async fn get_dns_config_content() -> CmdResult<String> {
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)
}

View File

@ -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<String>,
timeout: i32,
) -> Result<DelayRes> {
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::<DelayRes>().await?)
}
/// 根据clash info获取clash服务地址和请求头
pub fn clash_client_info() -> Result<(String, HeaderMap)> {
let client = { Config::clash().data().get_client_info() };

View File

@ -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<String>,
timeout: i32,
) -> Result<serde_json::Value, String> {
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);
}
}