Ver código fonte

chore: Optimize service path

MystiPanda 1 ano atrás
pai
commit
8a608c3c3e

+ 87 - 0
src-tauri/Cargo.lock

@@ -1954,6 +1954,20 @@ dependencies = [
  "want",
 ]
 
+[[package]]
+name = "hyper-rustls"
+version = "0.24.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
+dependencies = [
+ "futures-util",
+ "http",
+ "hyper",
+ "rustls",
+ "tokio",
+ "tokio-rustls",
+]
+
 [[package]]
 name = "hyper-tls"
 version = "0.5.0"
@@ -3602,6 +3616,7 @@ dependencies = [
  "http",
  "http-body",
  "hyper",
+ "hyper-rustls",
  "hyper-tls",
  "ipnet",
  "js-sys",
@@ -3611,12 +3626,15 @@ dependencies = [
  "once_cell",
  "percent-encoding",
  "pin-project-lite",
+ "rustls",
+ "rustls-pemfile",
  "serde",
  "serde_json",
  "serde_urlencoded",
  "system-configuration",
  "tokio",
  "tokio-native-tls",
+ "tokio-rustls",
  "tokio-util",
  "tower-service",
  "url",
@@ -3624,6 +3642,7 @@ dependencies = [
  "wasm-bindgen-futures",
  "wasm-streams",
  "web-sys",
+ "webpki-roots",
  "winreg 0.50.0",
 ]
 
@@ -3651,6 +3670,20 @@ dependencies = [
  "windows 0.37.0",
 ]
 
+[[package]]
+name = "ring"
+version = "0.17.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74"
+dependencies = [
+ "cc",
+ "getrandom 0.2.11",
+ "libc",
+ "spin",
+ "untrusted",
+ "windows-sys 0.48.0",
+]
+
 [[package]]
 name = "rquickjs"
 version = "0.3.1"
@@ -3745,6 +3778,18 @@ dependencies = [
  "windows-sys 0.52.0",
 ]
 
+[[package]]
+name = "rustls"
+version = "0.21.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9"
+dependencies = [
+ "log 0.4.20",
+ "ring",
+ "rustls-webpki",
+ "sct",
+]
+
 [[package]]
 name = "rustls-pemfile"
 version = "1.0.4"
@@ -3754,6 +3799,16 @@ dependencies = [
  "base64 0.21.5",
 ]
 
+[[package]]
+name = "rustls-webpki"
+version = "0.101.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
 [[package]]
 name = "rustversion"
 version = "1.0.14"
@@ -3802,6 +3857,16 @@ version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 
+[[package]]
+name = "sct"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
 [[package]]
 name = "security-framework"
 version = "2.9.2"
@@ -4862,6 +4927,16 @@ dependencies = [
  "tokio",
 ]
 
+[[package]]
+name = "tokio-rustls"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
+dependencies = [
+ "rustls",
+ "tokio",
+]
+
 [[package]]
 name = "tokio-stream"
 version = "0.1.14"
@@ -5147,6 +5222,12 @@ version = "0.2.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa"
 
+[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
 [[package]]
 name = "url"
 version = "2.5.0"
@@ -5449,6 +5530,12 @@ dependencies = [
  "system-deps 6.2.0",
 ]
 
+[[package]]
+name = "webpki-roots"
+version = "0.25.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10"
+
 [[package]]
 name = "webview2-com"
 version = "0.19.1"

+ 1 - 1
src-tauri/Cargo.toml

@@ -37,7 +37,7 @@ percent-encoding = "2.3.1"
 window-shadows = { version = "0.2" }
 tokio = { version = "1", features = ["full"] }
 serde = { version = "1.0", features = ["derive"] }
-reqwest = { version = "0.11", features = ["json"] }
+reqwest = { version = "0.11", features = ["json", "rustls-tls"] }
 sysproxy = { git="https://github.com/zzzgydi/sysproxy-rs", branch = "main" }
 tauri = { version = "1.5", features = ["icon-png", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all"] }
 

+ 2 - 3
src-tauri/src/config/prfitem.rs

@@ -190,7 +190,7 @@ impl PrfItem {
         let self_proxy = opt_ref.map_or(false, |o| o.self_proxy.unwrap_or(false));
         let user_agent = opt_ref.map_or(None, |o| o.user_agent.clone());
 
-        let mut builder = reqwest::ClientBuilder::new().no_proxy();
+        let mut builder = reqwest::ClientBuilder::new().use_rustls_tls().no_proxy();
 
         // 使用软件自己的代理
         if self_proxy {
@@ -231,8 +231,7 @@ impl PrfItem {
             };
         }
 
-        let version = unsafe { dirs::APP_VERSION };
-        let version = format!("clash-verge/{version}");
+        let version = format!("clash-verge-rev");
         builder = builder.user_agent(user_agent.unwrap_or(version));
 
         let resp = builder.build()?.get(url).send().await?;

+ 4 - 5
src-tauri/src/core/win_uwp.rs

@@ -7,8 +7,8 @@ use runas::Command as RunasCommand;
 use std::process::Command as StdCommand;
 
 pub async fn invoke_uwptools() -> Result<()> {
-    let binary_path = dirs::service_path()?;
-    let tool_path = binary_path.with_file_name("enableLoopback.exe");
+    let resource_dir = dirs::app_resources_dir()?;
+    let tool_path = resource_dir.join("enableLoopback.exe");
 
     if !tool_path.exists() {
         bail!("enableLoopback exe not found");
@@ -17,10 +17,9 @@ pub async fn invoke_uwptools() -> Result<()> {
     let token = Token::with_current_process()?;
     let level = token.privilege_level()?;
 
-   match level {
+    match level {
         PrivilegeLevel::NotPrivileged => RunasCommand::new(tool_path).status()?,
-        _ => StdCommand::new(tool_path)
-            .status()?,
+        _ => StdCommand::new(tool_path).status()?,
     };
 
     Ok(())

+ 23 - 61
src-tauri/src/utils/dirs.rs

@@ -1,8 +1,9 @@
+use crate::core::handle;
 use anyhow::Result;
 use std::path::PathBuf;
 use tauri::{
     api::path::{data_dir, resource_dir},
-    Env, PackageInfo,
+    Env,
 };
 
 #[cfg(not(feature = "verge-dev"))]
@@ -14,73 +15,38 @@ static CLASH_CONFIG: &str = "config.yaml";
 static VERGE_CONFIG: &str = "verge.yaml";
 static PROFILE_YAML: &str = "profiles.yaml";
 
-static mut RESOURCE_DIR: Option<PathBuf> = None;
-
-/// portable flag
-#[allow(unused)]
-static mut PORTABLE_FLAG: bool = false;
-
-pub static mut APP_VERSION: &str = "v1.2.0";
-
-/// initialize portable flag
-#[cfg(target_os = "windows")]
-pub unsafe fn init_portable_flag() -> Result<()> {
+/// get the verge app home dir
+pub fn app_home_dir() -> Result<PathBuf> {
     use tauri::utils::platform::current_exe;
 
-    let exe = current_exe()?;
-
-    if let Some(dir) = exe.parent() {
+    let app_exe = current_exe()?;
+    if let Some(dir) = app_exe.parent() {
         let dir = PathBuf::from(dir).join(".config/PORTABLE");
 
         if dir.exists() {
-            PORTABLE_FLAG = true;
-        }
-    }
-
-    Ok(())
-}
-
-/// get the verge app home dir
-pub fn app_home_dir() -> Result<PathBuf> {
-    #[cfg(target_os = "windows")]
-    unsafe {
-        use tauri::utils::platform::current_exe;
-
-        if !PORTABLE_FLAG {
-            Ok(data_dir()
-                .ok_or(anyhow::anyhow!("failed to get app home dir"))?
-                .join(APP_ID))
-        } else {
-            let app_exe = current_exe()?;
             let app_exe = dunce::canonicalize(app_exe)?;
             let app_dir = app_exe
                 .parent()
                 .ok_or(anyhow::anyhow!("failed to get the portable app dir"))?;
-            Ok(PathBuf::from(app_dir).join(".config").join(APP_ID))
+            return Ok(PathBuf::from(app_dir).join(".config").join(APP_ID));
         }
     }
-
-    #[cfg(not(target_os = "windows"))]
     Ok(data_dir()
         .ok_or(anyhow::anyhow!("failed to get app home dir"))?
         .join(APP_ID))
 }
 
 /// get the resources dir
-pub fn app_resources_dir(package_info: &PackageInfo) -> Result<PathBuf> {
-    let res_dir = resource_dir(package_info, &Env::default())
-        .ok_or(anyhow::anyhow!("failed to get the resource dir"))?
-        .join("resources");
-
-    unsafe {
-        RESOURCE_DIR = Some(res_dir.clone());
-
-        let ver = package_info.version.to_string();
-        let ver_str = format!("v{ver}");
-        APP_VERSION = Box::leak(Box::new(ver_str));
-    }
-
-    Ok(res_dir)
+pub fn app_resources_dir() -> Result<PathBuf> {
+    let handle = handle::Handle::global();
+    let app_handle = handle.app_handle.lock();
+    if let Some(app_handle) = app_handle.as_ref() {
+        let res_dir = resource_dir(app_handle.package_info(), &Env::default())
+            .ok_or(anyhow::anyhow!("failed to get the resource dir"))?
+            .join("resources");
+        return Ok(res_dir);
+    };
+    Err(anyhow::anyhow!("failed to get the resource dir"))
 }
 
 /// profiles dir
@@ -105,22 +71,18 @@ pub fn profiles_path() -> Result<PathBuf> {
     Ok(app_home_dir()?.join(PROFILE_YAML))
 }
 
-#[allow(unused)]
-pub fn app_res_dir() -> Result<PathBuf> {
-    unsafe {
-        Ok(RESOURCE_DIR
-            .clone()
-            .ok_or(anyhow::anyhow!("failed to get the resource dir"))?)
-    }
-}
-
 pub fn clash_pid_path() -> Result<PathBuf> {
     Ok(app_home_dir()?.join("clash.pid"))
 }
 
+#[cfg(windows)]
+pub fn service_dir() -> Result<PathBuf> {
+    Ok(app_home_dir()?.join("service"))
+}
+
 #[cfg(windows)]
 pub fn service_path() -> Result<PathBuf> {
-    Ok(app_home_dir()?.join("clash-verge-service.exe"))
+    Ok(service_dir()?.join("clash-verge-service.exe"))
 }
 
 #[cfg(windows)]

+ 62 - 14
src-tauri/src/utils/init.rs

@@ -9,7 +9,6 @@ use log4rs::config::{Appender, Logger, Root};
 use log4rs::encode::pattern::PatternEncoder;
 use std::fs::{self, DirEntry};
 use std::str::FromStr;
-use tauri::PackageInfo;
 
 /// initialize this instance's log file
 fn init_log() -> Result<()> {
@@ -142,11 +141,6 @@ pub fn delete_log() -> Result<()> {
 /// Initialize all the config files
 /// before tauri setup
 pub fn init_config() -> Result<()> {
-    #[cfg(target_os = "windows")]
-    unsafe {
-        let _ = dirs::init_portable_flag();
-    }
-
     let _ = init_log();
     let _ = delete_log();
 
@@ -188,9 +182,9 @@ pub fn init_config() -> Result<()> {
 
 /// initialize app resources
 /// after tauri setup
-pub fn init_resources(package_info: &PackageInfo) -> Result<()> {
+pub fn init_resources() -> Result<()> {
     let app_dir = dirs::app_home_dir()?;
-    let res_dir = dirs::app_resources_dir(package_info)?;
+    let res_dir = dirs::app_resources_dir()?;
 
     if !app_dir.exists() {
         let _ = fs::create_dir_all(&app_dir);
@@ -200,22 +194,76 @@ pub fn init_resources(package_info: &PackageInfo) -> Result<()> {
     }
 
     #[cfg(target_os = "windows")]
+    let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat"];
+    #[cfg(not(target_os = "windows"))]
+    let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat"];
+
+    // copy the resource file
+    // if the source file is newer than the destination file, copy it over
+    for file in file_list.iter() {
+        let src_path = res_dir.join(file);
+        let dest_path = app_dir.join(file);
+
+        let handle_copy = || {
+            match fs::copy(&src_path, &dest_path) {
+                Ok(_) => log::debug!(target: "app", "resources copied '{file}'"),
+                Err(err) => {
+                    log::error!(target: "app", "failed to copy resources '{file}', {err}")
+                }
+            };
+        };
+
+        if src_path.exists() && !dest_path.exists() {
+            handle_copy();
+            continue;
+        }
+
+        let src_modified = fs::metadata(&src_path).and_then(|m| m.modified());
+        let dest_modified = fs::metadata(&dest_path).and_then(|m| m.modified());
+
+        match (src_modified, dest_modified) {
+            (Ok(src_modified), Ok(dest_modified)) => {
+                if src_modified > dest_modified {
+                    handle_copy();
+                } else {
+                    log::debug!(target: "app", "skipping resource copy '{file}'");
+                }
+            }
+            _ => {
+                log::debug!(target: "app", "failed to get modified '{file}'");
+                handle_copy();
+            }
+        };
+    }
+
+    Ok(())
+}
+
+/// initialize service resources
+/// after tauri setup
+#[cfg(target_os = "windows")]
+pub fn init_service() -> Result<()> {
+    let service_dir = dirs::service_dir()?;
+    let res_dir = dirs::app_resources_dir()?;
+
+    if !service_dir.exists() {
+        let _ = fs::create_dir_all(&service_dir);
+    }
+    if !res_dir.exists() {
+        let _ = fs::create_dir_all(&res_dir);
+    }
+
     let file_list = [
-        "Country.mmdb",
-        "geoip.dat",
-        "geosite.dat",
         "clash-verge-service.exe",
         "install-service.exe",
         "uninstall-service.exe",
     ];
-    #[cfg(not(target_os = "windows"))]
-    let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat"];
 
     // copy the resource file
     // if the source file is newer than the destination file, copy it over
     for file in file_list.iter() {
         let src_path = res_dir.join(file);
-        let dest_path = app_dir.join(file);
+        let dest_path = service_dir.join(file);
 
         let handle_copy = || {
             match fs::copy(&src_path, &dest_path) {

+ 3 - 2
src-tauri/src/utils/resolve.rs

@@ -30,8 +30,9 @@ pub fn resolve_setup(app: &mut App) {
 
     handle::Handle::global().init(app.app_handle());
 
-    log_err!(init::init_resources(app.package_info()));
-
+    log_err!(init::init_resources());
+    #[cfg(target_os = "windows")]
+    log_err!(init::init_service());
     // 处理随机端口
     let enable_random_port = Config::verge().latest().enable_random_port.unwrap_or(false);
 

+ 1 - 1
src/components/profile/profile-viewer.tsx

@@ -209,7 +209,7 @@ export const ProfileViewer = forwardRef<ProfileViewerRef, Props>(
                 <TextField
                   {...text}
                   {...field}
-                  placeholder={`clash-verge/v${version}`}
+                  placeholder={`clash-verge-rev`}
                   label="User Agent"
                 />
               )}