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 super::CmdResult;
use crate::{config::*, core::*, feat, module::mihomo::MihomoManager, wrap_err};
use serde_yaml::Mapping; use serde_yaml::Mapping;
/// 复制Clash环境变量 /// 复制Clash环境变量
@ -37,7 +32,10 @@ pub async fn patch_clash_mode(payload: String) -> CmdResult {
pub async fn change_clash_core(clash_core: String) -> CmdResult<Option<String>> { pub async fn change_clash_core(clash_core: String) -> CmdResult<Option<String>> {
log::info!(target: "app", "changing core to {clash_core}"); 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(_) => { Ok(_) => {
log::info!(target: "app", "core changed to {clash_core}"); log::info!(target: "app", "core changed to {clash_core}");
handle::Handle::notice_message("config_core::change_success", &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, name: String,
url: Option<String>, url: Option<String>,
timeout: i32, timeout: i32,
) -> CmdResult<clash_api::DelayRes> { ) -> CmdResult<serde_json::Value> {
match clash_api::get_proxy_delay(name, url, timeout).await { MihomoManager::global()
Ok(res) => Ok(res), .test_proxy_delay(&name, url, timeout)
Err(err) => Err(err.to_string()), .await
}
} }
/// 测试URL延迟 /// 测试URL延迟
@ -86,7 +83,8 @@ pub async fn save_dns_config(dns_config: Mapping) -> CmdResult {
use std::fs; use std::fs;
// 获取DNS配置文件路径 // 获取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"); .join("dns_config.yaml");
// 保存DNS配置到文件 // 保存DNS配置到文件
@ -100,9 +98,9 @@ pub async fn save_dns_config(dns_config: Mapping) -> CmdResult {
/// 应用或撤销DNS配置 /// 应用或撤销DNS配置
#[tauri::command] #[tauri::command]
pub fn apply_dns_config(apply: bool) -> CmdResult { pub fn apply_dns_config(apply: bool) -> CmdResult {
use crate::utils::dirs;
use crate::core::{handle, CoreManager};
use crate::config::Config; use crate::config::Config;
use crate::core::{handle, CoreManager};
use crate::utils::dirs;
use tauri::async_runtime; use tauri::async_runtime;
// 使用spawn来处理异步操作 // 使用spawn来处理异步操作
@ -136,7 +134,7 @@ pub fn apply_dns_config(apply: bool) -> CmdResult {
let mut patch = serde_yaml::Mapping::new(); let mut patch = serde_yaml::Mapping::new();
patch.insert("dns".into(), config.into()); patch.insert("dns".into(), config.into());
patch patch
}, }
Err(e) => { Err(e) => {
log::error!(target: "app", "Failed to parse DNS config: {}", e); log::error!(target: "app", "Failed to parse DNS config: {}", e);
return; return;
@ -147,7 +145,9 @@ pub fn apply_dns_config(apply: bool) -> CmdResult {
// 重新生成配置确保DNS配置被正确应用 // 重新生成配置确保DNS配置被正确应用
// 这里不调用patch_clash以避免将DNS配置写入config.yaml // 这里不调用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 { if let Err(err) = Config::generate().await {
@ -178,7 +178,7 @@ pub fn apply_dns_config(apply: bool) -> CmdResult {
Ok(_) => { Ok(_) => {
log::info!(target: "app", "Config regenerated successfully"); log::info!(target: "app", "Config regenerated successfully");
handle::Handle::refresh_clash(); handle::Handle::refresh_clash();
}, }
Err(err) => { Err(err) => {
log::error!(target: "app", "Failed to apply regenerated config: {}", err); log::error!(target: "app", "Failed to apply regenerated config: {}", err);
} }
@ -194,7 +194,8 @@ pub fn apply_dns_config(apply: bool) -> CmdResult {
pub fn check_dns_config_exists() -> CmdResult<bool> { pub fn check_dns_config_exists() -> CmdResult<bool> {
use crate::utils::dirs; 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"); .join("dns_config.yaml");
Ok(dns_path.exists()) Ok(dns_path.exists())
@ -206,7 +207,8 @@ pub async fn get_dns_config_content() -> CmdResult<String> {
use crate::utils::dirs; use crate::utils::dirs;
use std::fs; 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"); .join("dns_config.yaml");
if !dns_path.exists() { if !dns_path.exists() {

View File

@ -1,7 +1,6 @@
use crate::config::Config; use crate::config::Config;
use anyhow::Result; use anyhow::Result;
use reqwest::header::HeaderMap; use reqwest::header::HeaderMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, PartialEq)] #[derive(Debug, Clone, Default, PartialEq)]
pub struct Rate { pub struct Rate {
@ -9,36 +8,6 @@ pub struct Rate {
pub down: u64, 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服务地址和请求头 /// 根据clash info获取clash服务地址和请求头
pub fn clash_client_info() -> Result<(String, HeaderMap)> { pub fn clash_client_info() -> Result<(String, HeaderMap)> {
let client = { Config::clash().data().get_client_info() }; let client = { Config::clash().data().get_client_info() };

View File

@ -96,7 +96,7 @@ impl MihomoManager {
let payload = serde_json::json!({ let payload = serde_json::json!({
"path": clash_config_path, "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 { if response["code"] == 204 {
Ok(()) Ok(())
} else { } else {
@ -109,7 +109,7 @@ impl MihomoManager {
pub async fn patch_configs(&self, config: serde_json::Value) -> Result<(), String> { pub async fn patch_configs(&self, config: serde_json::Value) -> Result<(), String> {
let url = format!("{}/configs", self.mihomo_server); 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 { if response["code"] == 204 {
Ok(()) Ok(())
} else { } else {
@ -119,4 +119,16 @@ impl MihomoManager {
.to_string()) .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);
}
} }