From d0c57739e8324d7fd773650a9d8d87e3aa149ce8 Mon Sep 17 00:00:00 2001 From: chuan Date: Thu, 30 Apr 2026 16:11:15 +0800 Subject: [PATCH] feat: refactor HTTP client usage and add new dependencies for improved functionality --- Cargo.lock | 44 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 +- src/http_client.rs | 11 +++++++++++ src/main.rs | 1 + src/oauth.rs | 2 +- src/quota.rs | 2 +- src/sync_client.rs | 6 +++--- src/token.rs | 2 +- 8 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 src/http_client.rs diff --git a/Cargo.lock b/Cargo.lock index 3d0e55a..60a5abe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -358,6 +358,16 @@ version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc14f565cf027a105f7a44ccf9e5b424348421a1d8952a8fc9d499d313107789" +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -717,9 +727,11 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2", + "system-configuration", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] @@ -1528,6 +1540,27 @@ dependencies = [ "syn", ] +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -2030,6 +2063,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + [[package]] name = "windows-result" version = "0.4.1" diff --git a/Cargo.toml b/Cargo.toml index 53c2881..9bdf3d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ clap = { version = "4.5", features = ["derive"] } dirs = "5" hex = "0.4" rand = "0.8" -reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls", "gzip", "brotli", "deflate", "zstd"] } +reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls", "system-proxy", "gzip", "brotli", "deflate", "zstd"] } rusqlite = { version = "0.32", features = ["bundled"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/src/http_client.rs b/src/http_client.rs new file mode 100644 index 0000000..63da82d --- /dev/null +++ b/src/http_client.rs @@ -0,0 +1,11 @@ +use std::time::Duration; + +use anyhow::{Context, Result}; + +pub fn client() -> Result { + reqwest::Client::builder() + .connect_timeout(Duration::from_secs(15)) + .timeout(Duration::from_secs(60)) + .build() + .context("创建 HTTP client 失败") +} diff --git a/src/main.rs b/src/main.rs index 204587a..9553fd1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ mod atomic; mod auth_file; mod cli; mod config_store; +mod http_client; mod jwt; mod oauth; mod paths; diff --git a/src/oauth.rs b/src/oauth.rs index 6c8d36f..dd74f29 100644 --- a/src/oauth.rs +++ b/src/oauth.rs @@ -154,7 +154,7 @@ async fn exchange_code_for_token(code: &str, code_verifier: &str, port: u16) -> // Store the refresh token when the provider returns one so cdxs can refresh // access tokens before switch/run/quota operations. let redirect_uri = format!("http://localhost:{port}/auth/callback"); - let response = reqwest::Client::new() + let response = crate::http_client::client()? .post(TOKEN_ENDPOINT) .form(&[ ("grant_type", "authorization_code"), diff --git a/src/quota.rs b/src/quota.rs index 94b6ae1..64f9c47 100644 --- a/src/quota.rs +++ b/src/quota.rs @@ -346,7 +346,7 @@ async fn fetch_quota(access_token: &str, account_id: Option<&str>) -> Result Result<()> { if server.is_empty() { return Err(anyhow!("server URL 不能为空")); } - let response = reqwest::Client::new() + let response = crate::http_client::client()? .post(format!("{server}/v1/login")) .json(&LoginRequest { username: user, @@ -105,7 +105,7 @@ pub async fn push(force: bool) -> Result<()> { accounts: local.accounts.clone(), }, }; - let response = reqwest::Client::new() + let response = crate::http_client::client()? .put(format!("{server}/v1/state")) .headers(auth_headers(&token)?) .json(&payload) @@ -250,7 +250,7 @@ fn auth_headers(token: &str) -> Result { } async fn fetch_remote_state(server: &str, token: &str) -> Result { - let remote = reqwest::Client::new() + let remote = crate::http_client::client()? .get(format!("{server}/v1/state")) .headers(auth_headers(token)?) .send() diff --git a/src/token.rs b/src/token.rs index 78e5e31..62e369b 100644 --- a/src/token.rs +++ b/src/token.rs @@ -100,7 +100,7 @@ pub async fn refresh_access_token( ) -> Result { // Some refresh responses omit id_token; keep the previous one when possible // because it still contains useful local metadata. - let response = reqwest::Client::new() + let response = crate::http_client::client()? .post(TOKEN_ENDPOINT) .form(&[ ("grant_type", "refresh_token"),