* chore(deps): update cargo dependencies * fix: sysinfo crate use limit features * fix: update headers-core dependency and kode-bridge version; enhance system monitor status validation * fix: extend overall_status type in ISystemMonitorOverview to include 'healthy' * refactor: update URL encoding strategy in IpcManager and cmdGetProxyDelay function * fix: resolve speed test functionality issue after IPC migration * fix: resolve speed test functionality issue after IPC migration #4221, #4218 --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
02e19bb132
commit
4905b44c8a
@@ -41,6 +41,7 @@
|
||||
- 改进核心启动/停止/重启后的状态刷新机制
|
||||
- 修复 `Windows` 安装器删除用户自启问题
|
||||
- 修复 `Windows` 安装器参数使用错误问题
|
||||
- 修复 `IPC` 迁移后测速功能异常
|
||||
|
||||
### 🔧 技术改进
|
||||
|
||||
|
||||
75
src-tauri/Cargo.lock
generated
75
src-tauri/Cargo.lock
generated
@@ -888,21 +888,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bzip2"
|
||||
version = "0.5.2"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47"
|
||||
checksum = "bea8dcd42434048e4f7a304411d9273a411f647446c1234a65ce0554923f4cff"
|
||||
dependencies = [
|
||||
"bzip2-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bzip2-sys"
|
||||
version = "0.1.13+1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
"libbz2-rs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2833,28 +2823,13 @@ checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"headers-core 0.2.0",
|
||||
"headers-core",
|
||||
"http 0.2.12",
|
||||
"httpdate",
|
||||
"mime",
|
||||
"sha1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"headers-core 0.3.0",
|
||||
"http 1.3.1",
|
||||
"httpdate",
|
||||
"mime",
|
||||
"sha1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers-core"
|
||||
version = "0.2.0"
|
||||
@@ -2864,15 +2839,6 @@ dependencies = [
|
||||
"http 0.2.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers-core"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
|
||||
dependencies = [
|
||||
"http 1.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
@@ -3745,22 +3711,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kode-bridge"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6-rc"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "971cfb2bdf5db3721fc822240b4e6e05b5d3aa8c85eb5f7ad4dc25ed0a3ad7e0"
|
||||
checksum = "11bf66a2690fdac4a30e3e60c5bb7e4479db318f2cd6eb95a353acf79d35855a"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
"headers 0.4.1",
|
||||
"http 1.3.1",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"httparse",
|
||||
"hyper 1.6.0",
|
||||
"interprocess",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.12",
|
||||
@@ -3819,6 +3781,12 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libbz2-rs-sys"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "775bf80d5878ab7c2b1080b5351a48b2f737d9f6f8b383574eebcc22be0dfccb"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.174"
|
||||
@@ -5381,6 +5349,12 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "ppmd-rust"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c834641d8ad1b348c9ee86dec3b9840d805acd5f24daa5f90c788951a52ff59b"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.21"
|
||||
@@ -6940,9 +6914,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.35.2"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c3ffa3e4ff2b324a57f7aeb3c349656c7b127c3c189520251a648102a92496e"
|
||||
checksum = "252800745060e7b9ffb7b2badbd8b31cfa4aa2e61af879d0a3bf2a317c20217d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"memchr",
|
||||
@@ -8549,7 +8523,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"headers 0.3.9",
|
||||
"headers",
|
||||
"http 0.2.12",
|
||||
"hyper 0.14.32",
|
||||
"log",
|
||||
@@ -9839,9 +9813,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "4.2.0"
|
||||
version = "4.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95ab361742de920c5535880f89bbd611ee62002bf11341d16a5f057bb8ba6899"
|
||||
checksum = "9aed4ac33e8eb078c89e6cbb1d5c4c7703ec6d299fc3e7c3695af8f8b423468b"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"arbitrary",
|
||||
@@ -9856,6 +9830,7 @@ dependencies = [
|
||||
"liblzma",
|
||||
"memchr",
|
||||
"pbkdf2",
|
||||
"ppmd-rust",
|
||||
"sha1",
|
||||
"time",
|
||||
"zeroize",
|
||||
|
||||
@@ -13,7 +13,7 @@ build = "build.rs"
|
||||
identifier = "io.github.clash-verge-rev.clash-verge-rev"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2.3.0", features = [] }
|
||||
tauri-build = { version = "2.3.1", features = [] }
|
||||
|
||||
[dependencies]
|
||||
warp = "0.3.7"
|
||||
@@ -25,9 +25,9 @@ dunce = "1.0.5"
|
||||
log4rs = "1.3.0"
|
||||
nanoid = "0.4"
|
||||
chrono = "0.4.41"
|
||||
sysinfo = "=0.35.2"
|
||||
sysinfo = { version = "0.36.1", features = ["network", "system"] }
|
||||
boa_engine = "0.20.0"
|
||||
serde_json = "1.0.140"
|
||||
serde_json = "1.0.141"
|
||||
serde_yaml = "0.9.34"
|
||||
once_cell = "1.21.3"
|
||||
lazy_static = "1.5.0"
|
||||
@@ -47,23 +47,23 @@ reqwest = { version = "0.12.22", features = ["json", "rustls-tls", "cookies"] }
|
||||
regex = "1.11.1"
|
||||
sysproxy = { git = "https://github.com/clash-verge-rev/sysproxy-rs" }
|
||||
image = "0.25.6"
|
||||
tauri = { version = "2.6.2", features = [
|
||||
tauri = { version = "2.7.0", features = [
|
||||
"protocol-asset",
|
||||
"devtools",
|
||||
"tray-icon",
|
||||
"image-ico",
|
||||
"image-png",
|
||||
] }
|
||||
network-interface = { version = "2.0.1", features = ["serde"] }
|
||||
network-interface = { version = "2.0.2", features = ["serde"] }
|
||||
tauri-plugin-shell = "2.3.0"
|
||||
tauri-plugin-dialog = "2.3.0"
|
||||
tauri-plugin-fs = "2.4.0"
|
||||
tauri-plugin-dialog = "2.3.1"
|
||||
tauri-plugin-fs = "2.4.1"
|
||||
tauri-plugin-process = "2.3.0"
|
||||
tauri-plugin-clipboard-manager = "2.3.0"
|
||||
tauri-plugin-deep-link = "2.4.0"
|
||||
tauri-plugin-deep-link = "2.4.1"
|
||||
tauri-plugin-devtools = "2.0.0"
|
||||
tauri-plugin-window-state = "2.3.0"
|
||||
zip = "=4.2.0"
|
||||
tauri-plugin-window-state = "2.4.0"
|
||||
zip = "4.3.0"
|
||||
reqwest_dav = "0.2.1"
|
||||
aes-gcm = { version = "0.10.3", features = ["std"] }
|
||||
base64 = "0.22.1"
|
||||
@@ -77,7 +77,7 @@ hmac = "0.12.1"
|
||||
sha2 = "0.10.9"
|
||||
hex = "0.4.3"
|
||||
scopeguard = "1.2.0"
|
||||
kode-bridge = "0.1.5"
|
||||
kode-bridge = "0.1.6-rc"
|
||||
dashmap = "6.1.0"
|
||||
tauri-plugin-notification = "2.3.0"
|
||||
|
||||
|
||||
@@ -2,9 +2,18 @@ use kode_bridge::{
|
||||
errors::{AnyError, AnyResult},
|
||||
IpcHttpClient, LegacyResponse,
|
||||
};
|
||||
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
|
||||
use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
|
||||
use std::sync::OnceLock;
|
||||
|
||||
// 定义用于URL路径的编码集合,只编码真正必要的字符
|
||||
const URL_PATH_ENCODE_SET: &AsciiSet = &CONTROLS
|
||||
.add(b' ') // 空格
|
||||
.add(b'/') // 斜杠
|
||||
.add(b'?') // 问号
|
||||
.add(b'#') // 井号
|
||||
.add(b'&') // 和号
|
||||
.add(b'%'); // 百分号
|
||||
|
||||
use crate::{
|
||||
logging,
|
||||
utils::{dirs::ipc_path, logging::Type},
|
||||
@@ -108,7 +117,7 @@ impl IpcManager {
|
||||
}
|
||||
|
||||
pub async fn delete_connection(&self, id: &str) -> AnyResult<()> {
|
||||
let encoded_id = utf8_percent_encode(id, NON_ALPHANUMERIC).to_string();
|
||||
let encoded_id = utf8_percent_encode(id, URL_PATH_ENCODE_SET).to_string();
|
||||
let url = format!("/connections/{encoded_id}");
|
||||
let response = self.send_request("DELETE", &url, None).await?;
|
||||
if response["code"] == 204 {
|
||||
@@ -176,11 +185,13 @@ impl IpcManager {
|
||||
) -> AnyResult<serde_json::Value> {
|
||||
let test_url =
|
||||
test_url.unwrap_or_else(|| "https://cp.cloudflare.com/generate_204".to_string());
|
||||
let encoded_name = utf8_percent_encode(name, NON_ALPHANUMERIC).to_string();
|
||||
let encoded_test_url = utf8_percent_encode(&test_url, NON_ALPHANUMERIC).to_string();
|
||||
let url = format!("/proxies/{encoded_name}/delay?url={encoded_test_url}&timeout={timeout}");
|
||||
let response = self.send_request("GET", &url, None).await?;
|
||||
Ok(response)
|
||||
|
||||
let encoded_name = utf8_percent_encode(name, URL_PATH_ENCODE_SET).to_string();
|
||||
// 测速URL不再编码,直接传递
|
||||
let url = format!("/proxies/{encoded_name}/delay?url={test_url}&timeout={timeout}");
|
||||
|
||||
let response = self.send_request("GET", &url, None).await;
|
||||
response
|
||||
}
|
||||
|
||||
// 版本和配置相关
|
||||
@@ -236,7 +247,7 @@ impl IpcManager {
|
||||
}
|
||||
|
||||
pub async fn update_rule_provider(&self, name: &str) -> AnyResult<()> {
|
||||
let encoded_name = utf8_percent_encode(name, NON_ALPHANUMERIC).to_string();
|
||||
let encoded_name = utf8_percent_encode(name, URL_PATH_ENCODE_SET).to_string();
|
||||
let url = format!("/providers/rules/{encoded_name}");
|
||||
let response = self.send_request("PUT", &url, None).await?;
|
||||
if response["code"] == 204 {
|
||||
@@ -254,7 +265,7 @@ impl IpcManager {
|
||||
// 代理相关
|
||||
pub async fn update_proxy(&self, group: &str, proxy: &str) -> AnyResult<()> {
|
||||
// 使用 percent-encoding 进行正确的 URL 编码
|
||||
let encoded_group = utf8_percent_encode(group, NON_ALPHANUMERIC).to_string();
|
||||
let encoded_group = utf8_percent_encode(group, URL_PATH_ENCODE_SET).to_string();
|
||||
let url = format!("/proxies/{encoded_group}");
|
||||
let payload = serde_json::json!({
|
||||
"name": proxy
|
||||
@@ -299,7 +310,7 @@ impl IpcManager {
|
||||
}
|
||||
|
||||
pub async fn proxy_provider_health_check(&self, name: &str) -> AnyResult<()> {
|
||||
let encoded_name = utf8_percent_encode(name, NON_ALPHANUMERIC).to_string();
|
||||
let encoded_name = utf8_percent_encode(name, URL_PATH_ENCODE_SET).to_string();
|
||||
let url = format!("/providers/proxies/{encoded_name}/healthcheck");
|
||||
let response = self.send_request("GET", &url, None).await?;
|
||||
if response["code"] == 204 {
|
||||
@@ -315,7 +326,7 @@ impl IpcManager {
|
||||
}
|
||||
|
||||
pub async fn update_proxy_provider(&self, name: &str) -> AnyResult<()> {
|
||||
let encoded_name = utf8_percent_encode(name, NON_ALPHANUMERIC).to_string();
|
||||
let encoded_name = utf8_percent_encode(name, URL_PATH_ENCODE_SET).to_string();
|
||||
let url = format!("/providers/proxies/{encoded_name}");
|
||||
let response = self.send_request("PUT", &url, None).await?;
|
||||
if response["code"] == 204 {
|
||||
@@ -338,11 +349,13 @@ impl IpcManager {
|
||||
timeout: i32,
|
||||
) -> AnyResult<serde_json::Value> {
|
||||
let test_url = url.unwrap_or_else(|| "https://cp.cloudflare.com/generate_204".to_string());
|
||||
let encoded_group_name = utf8_percent_encode(group_name, NON_ALPHANUMERIC).to_string();
|
||||
let encoded_test_url = utf8_percent_encode(&test_url, NON_ALPHANUMERIC).to_string();
|
||||
let url =
|
||||
format!("/group/{encoded_group_name}/delay?url={encoded_test_url}&timeout={timeout}");
|
||||
self.send_request("GET", &url, None).await
|
||||
|
||||
let encoded_group_name = utf8_percent_encode(group_name, URL_PATH_ENCODE_SET).to_string();
|
||||
// 测速URL不再编码,直接传递
|
||||
let url = format!("/group/{encoded_group_name}/delay?url={test_url}&timeout={timeout}");
|
||||
|
||||
let response = self.send_request("GET", &url, None).await;
|
||||
response
|
||||
}
|
||||
|
||||
// 调试相关
|
||||
|
||||
@@ -512,12 +512,9 @@ export async function cmdGetProxyDelay(
|
||||
) {
|
||||
// 确保URL不为空
|
||||
const testUrl = url || "https://cp.cloudflare.com/generate_204";
|
||||
console.log(
|
||||
`[API] 调用延迟测试API,代理: ${name}, 超时: ${timeout}ms, URL: ${testUrl}`,
|
||||
);
|
||||
|
||||
try {
|
||||
name = encodeURIComponent(name);
|
||||
// 不再在前端编码代理名称,由后端统一处理编码
|
||||
const result = await invoke<{ delay: number }>(
|
||||
"clash_api_get_proxy_delay",
|
||||
{
|
||||
@@ -529,20 +526,12 @@ export async function cmdGetProxyDelay(
|
||||
|
||||
// 验证返回结果中是否有delay字段,并且值是一个有效的数字
|
||||
if (result && typeof result.delay === "number") {
|
||||
console.log(
|
||||
`[API] 延迟测试API调用成功,代理: ${name}, 延迟: ${result.delay}ms`,
|
||||
);
|
||||
return result;
|
||||
} else {
|
||||
console.error(
|
||||
`[API] 延迟测试API返回无效结果,代理: ${name}, 结果:`,
|
||||
result,
|
||||
);
|
||||
// 返回一个有效的结果对象,但标记为超时
|
||||
return { delay: 1e6 };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[API] 延迟测试API调用失败,代理: ${name}`, error);
|
||||
// 返回一个有效的结果对象,但标记为错误
|
||||
return { delay: 1e6 };
|
||||
}
|
||||
|
||||
2
src/services/types.d.ts
vendored
2
src/services/types.d.ts
vendored
@@ -181,7 +181,7 @@ interface ISystemMonitorOverview {
|
||||
};
|
||||
is_fresh: boolean;
|
||||
};
|
||||
overall_status: "active" | "inactive" | "error" | "unknown";
|
||||
overall_status: "active" | "inactive" | "error" | "unknown" | "healthy";
|
||||
}
|
||||
|
||||
// 类型安全的数据验证器
|
||||
|
||||
@@ -138,7 +138,7 @@ export class SystemMonitorValidator implements ISystemMonitorOverviewValidator {
|
||||
private validateOverallStatus(status: any): boolean {
|
||||
return (
|
||||
typeof status === "string" &&
|
||||
["active", "inactive", "error", "unknown"].includes(status)
|
||||
["active", "inactive", "error", "unknown", "healthy"].includes(status)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -190,12 +190,12 @@ export class SystemMonitorValidator implements ISystemMonitorOverviewValidator {
|
||||
|
||||
private sanitizeOverallStatus(
|
||||
status: any,
|
||||
): "active" | "inactive" | "error" | "unknown" {
|
||||
): "active" | "inactive" | "error" | "unknown" | "healthy" {
|
||||
if (
|
||||
typeof status === "string" &&
|
||||
["active", "inactive", "error", "unknown"].includes(status)
|
||||
["active", "inactive", "error", "unknown", "healthy"].includes(status)
|
||||
) {
|
||||
return status as "active" | "inactive" | "error" | "unknown";
|
||||
return status as "active" | "inactive" | "error" | "unknown" | "healthy";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user