From c3b86215549bab04d93f43cff35440df4cd9af23 Mon Sep 17 00:00:00 2001 From: yuluo Date: Sat, 13 Apr 2024 14:49:19 +0800 Subject: [PATCH] add: Http proxy request client --- Cargo.toml | 4 ++-- libs/hbb_common/src/proxy.rs | 11 +++++---- src/hbbs_http.rs | 2 ++ src/hbbs_http/account.rs | 3 ++- src/hbbs_http/http_client.rs | 43 ++++++++++++++++++++++++++++++++++ src/hbbs_http/record_upload.rs | 3 ++- src/plugin/callback_msg.rs | 4 +++- 7 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 src/hbbs_http/http_client.rs diff --git a/Cargo.toml b/Cargo.toml index 9e3af62b1..6376fdb88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -132,10 +132,10 @@ wallpaper = { git = "https://github.com/21pages/wallpaper.rs" } [target.'cfg(any(target_os = "macos", target_os = "windows"))'.dependencies] # https://github.com/rustdesk/rustdesk-server-pro/issues/189, using native-tls for better tls support -reqwest = { git = "https://github.com/rustdesk-org/reqwest", features = ["blocking", "json", "native-tls", "gzip"], default-features=false } +reqwest = { git = "https://github.com/rustdesk-org/reqwest", features = ["blocking", "socks", "json", "native-tls", "gzip"], default-features=false } [target.'cfg(not(any(target_os = "macos", target_os = "windows")))'.dependencies] -reqwest = { git = "https://github.com/rustdesk-org/reqwest", features = ["blocking", "json", "rustls-tls", "rustls-tls-native-roots", "gzip"], default-features=false } +reqwest = { git = "https://github.com/rustdesk-org/reqwest", features = ["blocking", "socks", "json", "rustls-tls", "rustls-tls-native-roots", "gzip"], default-features=false } [target.'cfg(target_os = "linux")'.dependencies] psimple = { package = "libpulse-simple-binding", version = "2.27" } diff --git a/libs/hbb_common/src/proxy.rs b/libs/hbb_common/src/proxy.rs index 3418e4db1..87955e2c3 100644 --- a/libs/hbb_common/src/proxy.rs +++ b/libs/hbb_common/src/proxy.rs @@ -111,9 +111,12 @@ pub struct Auth { impl Auth { fn get_proxy_authorization(&self) -> String { + format!("Proxy-Authorization: Basic {}\r\n", self.get_basic_authorization()) + } + + pub fn get_basic_authorization(&self) -> String { let authorization = format!("{}:{}", &self.user_name, &self.password); - let authorization = general_purpose::STANDARD.encode(authorization.as_bytes()); - format!("Proxy-Authorization: Basic {}\r\n", authorization) + general_purpose::STANDARD.encode(authorization.as_bytes()) } } @@ -135,7 +138,7 @@ pub enum ProxyScheme { } impl ProxyScheme { - fn maybe_auth(&self) -> Option<&Auth> { + pub fn maybe_auth(&self) -> Option<&Auth> { match self { ProxyScheme::Http { auth, .. } | ProxyScheme::Https { auth, .. } | @@ -308,7 +311,7 @@ impl IntoProxyScheme for ProxyScheme { #[derive(Clone)] pub struct Proxy { - intercept: ProxyScheme, + pub intercept: ProxyScheme, ms_timeout: u64, } diff --git a/src/hbbs_http.rs b/src/hbbs_http.rs index 76ced87a0..6ca51b2fc 100644 --- a/src/hbbs_http.rs +++ b/src/hbbs_http.rs @@ -6,6 +6,8 @@ use serde_json::{Map, Value}; pub mod account; pub mod record_upload; pub mod sync; +mod http_client; +pub use http_client::create_client; #[derive(Debug)] pub enum HbbHttpResponse { diff --git a/src/hbbs_http/account.rs b/src/hbbs_http/account.rs index 3f1a7f1c1..997a3fa37 100644 --- a/src/hbbs_http/account.rs +++ b/src/hbbs_http/account.rs @@ -9,6 +9,7 @@ use std::{ time::{Duration, Instant}, }; use url::Url; +use crate::hbbs_http::create_client; lazy_static::lazy_static! { static ref OIDC_SESSION: Arc> = Arc::new(RwLock::new(OidcSession::new())); @@ -130,7 +131,7 @@ impl Default for UserStatus { impl OidcSession { fn new() -> Self { Self { - client: Client::new(), + client: create_client().unwrap_or(Client::new()), state_msg: REQUESTING_ACCOUNT_AUTH, failed_msg: "".to_owned(), code_url: None, diff --git a/src/hbbs_http/http_client.rs b/src/hbbs_http/http_client.rs new file mode 100644 index 000000000..93f100b67 --- /dev/null +++ b/src/hbbs_http/http_client.rs @@ -0,0 +1,43 @@ +use reqwest::blocking::Client; +use hbb_common::config::Config; +use hbb_common::log::info; +use hbb_common::proxy::{Proxy, ProxyScheme}; +use hbb_common::ResultType; + +pub fn create_client() -> ResultType { + let mut builder = Client::builder(); + if let Some(conf) = Config::get_socks() { + info!("Create an http request client with proxy forwarding"); + let proxy = Proxy::form_conf(&conf, None)?; + // 根据不同的代理类型设置代理 + match &proxy.intercept { + ProxyScheme::Http { host, .. } => { + let proxy = reqwest::Proxy::http(host)?; + builder = builder.proxy(proxy); + } + ProxyScheme::Https { host, .. } => { + let proxy = reqwest::Proxy::https(host)?; + builder = builder.proxy(proxy); + } + ProxyScheme::Socks5 { addr, .. } => { + // 使用socks5代理 + let proxy = reqwest::Proxy::all(&format!("socks5://{}", addr))?; + builder = builder.proxy(proxy); + } + } + + // 如果有认证信息,添加Basic认证头 + if let Some(auth) = proxy.intercept.maybe_auth() { + let basic_auth = format!( + "Basic {}", + auth.get_basic_authorization() + ); + builder = builder.default_headers(vec![( + reqwest::header::PROXY_AUTHORIZATION, + basic_auth.parse().unwrap(), + )].into_iter().collect()); + } + } + + Ok(builder.build()?) +} \ No newline at end of file diff --git a/src/hbbs_http/record_upload.rs b/src/hbbs_http/record_upload.rs index 79e836988..c2b5feb4b 100644 --- a/src/hbbs_http/record_upload.rs +++ b/src/hbbs_http/record_upload.rs @@ -10,6 +10,7 @@ use std::{ sync::{mpsc::Receiver, Arc, Mutex}, time::{Duration, Instant}, }; +use crate::hbbs_http::create_client; const MAX_HEADER_LEN: usize = 1024; const SHOULD_SEND_TIME: Duration = Duration::from_secs(1); @@ -25,7 +26,7 @@ pub fn is_enable() -> bool { pub fn run(rx: Receiver) { let mut uploader = RecordUploader { - client: Client::new(), + client: create_client().unwrap_or(Client::new()), api_server: crate::get_api_server( Config::get_option("api-server"), Config::get_option("custom-rendezvous-server"), diff --git a/src/plugin/callback_msg.rs b/src/plugin/callback_msg.rs index e634595e8..2d35ed5c7 100644 --- a/src/plugin/callback_msg.rs +++ b/src/plugin/callback_msg.rs @@ -13,6 +13,8 @@ use std::{ thread, time::Duration, }; +use reqwest::blocking::Client; +use crate::hbbs_http::create_client; const MSG_TO_RUSTDESK_TARGET: &str = "rustdesk"; const MSG_TO_PEER_TARGET: &str = "peer"; @@ -280,7 +282,7 @@ fn request_plugin_sign(id: String, msg_to_rustdesk: MsgToRustDesk) -> PluginRetu ); thread::spawn(move || { let sign_url = format!("{}/lic/web/api/plugin-sign", get_api_server()); - let client = reqwest::blocking::Client::new(); + let client = create_client().unwrap_or(Client::new()); let req = PluginSignReq { plugin_id: id.clone(), version: signature_data.version,