mirror of
https://github.com/clash-verge-rev/clash-verge-rev
synced 2025-05-05 00:23:45 +08:00
feat: add network manager to optimize network request handling
This commit is contained in:
parent
3ce5d3bf2d
commit
32b6821b8a
@ -30,6 +30,7 @@
|
||||
- 定时自动订阅更新也能自动回退使用代理
|
||||
- 订阅请求超时机制,防止订阅更新的时候卡死
|
||||
- 订阅卡片点击时间可切换下次自动更新时间,自动更新触发后页面有明确的成功与否提示
|
||||
- 添加网络管理器以优化网络请求处理,防止资源竞争导致的启动时 UI 卡死
|
||||
|
||||
#### 优化了:
|
||||
- 系统代理 Bypass 设置
|
||||
|
1
src-tauri/Cargo.lock
generated
1
src-tauri/Cargo.lock
generated
@ -1060,6 +1060,7 @@ dependencies = [
|
||||
"getrandom 0.3.2",
|
||||
"image",
|
||||
"imageproc",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"log4rs",
|
||||
|
@ -30,6 +30,7 @@ boa_engine = "0.20.0"
|
||||
serde_json = "1.0"
|
||||
serde_yaml = "0.9"
|
||||
once_cell = "1.21.3"
|
||||
lazy_static = "1.4.0"
|
||||
port_scanner = "0.1.5"
|
||||
delay_timer = "0.11.6"
|
||||
parking_lot = "0.12"
|
||||
|
@ -1,10 +1,10 @@
|
||||
use crate::utils::{dirs, help, resolve::VERSION, tmpl};
|
||||
use crate::utils::network::{NetworkManager, ProxyType};
|
||||
use crate::utils::{dirs, help, tmpl};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use reqwest::StatusCode;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::Mapping;
|
||||
use std::fs;
|
||||
use sysproxy::Sysproxy;
|
||||
|
||||
use super::Config;
|
||||
|
||||
@ -254,58 +254,25 @@ impl PrfItem {
|
||||
let mut proxies = opt_ref.and_then(|o| o.proxies.clone());
|
||||
let mut groups = opt_ref.and_then(|o| o.groups.clone());
|
||||
|
||||
// 设置超时时间:连接超时10秒,请求总超时使用配置时间(默认60秒)
|
||||
let mut builder = reqwest::ClientBuilder::new()
|
||||
.use_rustls_tls()
|
||||
.no_proxy()
|
||||
.connect_timeout(std::time::Duration::from_secs(10))
|
||||
.timeout(std::time::Duration::from_secs(timeout));
|
||||
|
||||
// 使用软件自己的代理
|
||||
if self_proxy {
|
||||
let port = Config::verge()
|
||||
.latest()
|
||||
.verge_mixed_port
|
||||
.unwrap_or(Config::clash().data().get_mixed_port());
|
||||
|
||||
let proxy_scheme = format!("http://127.0.0.1:{port}");
|
||||
|
||||
if let Ok(proxy) = reqwest::Proxy::http(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = reqwest::Proxy::https(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = reqwest::Proxy::all(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
}
|
||||
// 使用系统代理
|
||||
else if with_proxy {
|
||||
if let Ok(p @ Sysproxy { enable: true, .. }) = Sysproxy::get_system_proxy() {
|
||||
let proxy_scheme = format!("http://{}:{}", p.host, p.port);
|
||||
|
||||
if let Ok(proxy) = reqwest::Proxy::http(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = reqwest::Proxy::https(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = reqwest::Proxy::all(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let version = match VERSION.get() {
|
||||
Some(v) => format!("clash-verge/v{}", v),
|
||||
None => "clash-verge/unknown".to_string(),
|
||||
// 选择代理类型
|
||||
let proxy_type = if self_proxy {
|
||||
ProxyType::SelfProxy
|
||||
} else if with_proxy {
|
||||
ProxyType::SystemProxy
|
||||
} else {
|
||||
ProxyType::NoProxy
|
||||
};
|
||||
|
||||
builder = builder.danger_accept_invalid_certs(accept_invalid_certs);
|
||||
builder = builder.user_agent(user_agent.unwrap_or(version));
|
||||
|
||||
let resp = builder.build()?.get(url).send().await?;
|
||||
// 使用网络管理器发送请求
|
||||
let resp = NetworkManager::global()
|
||||
.get(
|
||||
url,
|
||||
proxy_type,
|
||||
Some(timeout),
|
||||
user_agent.clone(),
|
||||
accept_invalid_certs,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let status_code = resp.status();
|
||||
if !StatusCode::is_success(&status_code) {
|
||||
|
@ -12,7 +12,6 @@ use std::{
|
||||
process::Command as StdCommand,
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
use tokio::time::Duration;
|
||||
|
||||
// Windows only
|
||||
|
||||
@ -49,7 +48,8 @@ impl ServiceState {
|
||||
latest.service_state = Some(self.clone());
|
||||
*config.draft() = latest;
|
||||
config.apply();
|
||||
Config::verge().latest().save_file()
|
||||
let result = config.latest().save_file();
|
||||
result
|
||||
}
|
||||
|
||||
// 更新安装信息
|
||||
@ -482,13 +482,13 @@ pub async fn reinstall_service() -> Result<()> {
|
||||
|
||||
/// check the windows service status
|
||||
pub async fn check_service() -> Result<JsonResponse> {
|
||||
use crate::utils::network::{NetworkManager, ProxyType};
|
||||
|
||||
let url = format!("{SERVICE_URL}/get_clash");
|
||||
let response = reqwest::ClientBuilder::new()
|
||||
.no_proxy()
|
||||
.timeout(Duration::from_secs(3))
|
||||
.build()?
|
||||
.get(url)
|
||||
.send()
|
||||
|
||||
// 使用无代理模式和3秒超时检查服务
|
||||
let response = NetworkManager::global()
|
||||
.get(&url, ProxyType::NoProxy, Some(3), None, false)
|
||||
.await
|
||||
.context("failed to connect to the Clash Verge Service")?
|
||||
.json::<JsonResponse>()
|
||||
@ -500,13 +500,13 @@ pub async fn check_service() -> Result<JsonResponse> {
|
||||
|
||||
/// check the service version
|
||||
pub async fn check_service_version() -> Result<String> {
|
||||
use crate::utils::network::{NetworkManager, ProxyType};
|
||||
|
||||
let url = format!("{SERVICE_URL}/version");
|
||||
let response = reqwest::ClientBuilder::new()
|
||||
.no_proxy()
|
||||
.timeout(Duration::from_secs(3))
|
||||
.build()?
|
||||
.get(url)
|
||||
.send()
|
||||
|
||||
// 使用无代理模式和3秒超时检查服务版本
|
||||
let response = NetworkManager::global()
|
||||
.get(&url, ProxyType::NoProxy, Some(3), None, false)
|
||||
.await
|
||||
.context("failed to connect to the Clash Verge Service")?
|
||||
.json::<VersionJsonResponse>()
|
||||
@ -568,6 +568,8 @@ pub async fn check_service_needs_reinstall() -> bool {
|
||||
|
||||
/// 尝试使用现有服务启动核心,不进行重装
|
||||
pub(super) async fn start_with_existing_service(config_file: &PathBuf) -> Result<()> {
|
||||
use crate::utils::network::{NetworkManager, ProxyType};
|
||||
|
||||
log::info!(target:"app", "attempting to start core with existing service");
|
||||
|
||||
let clash_core = { Config::verge().latest().clash_core.clone() };
|
||||
@ -596,9 +598,10 @@ pub(super) async fn start_with_existing_service(config_file: &PathBuf) -> Result
|
||||
log::info!(target:"app", "start service: {:?}", map.clone());
|
||||
|
||||
let url = format!("{SERVICE_URL}/start_clash");
|
||||
let _ = reqwest::ClientBuilder::new()
|
||||
.no_proxy()
|
||||
.build()?
|
||||
|
||||
// 使用网络管理器发送POST请求
|
||||
let client = NetworkManager::global().get_client(ProxyType::NoProxy);
|
||||
let _ = client
|
||||
.post(url)
|
||||
.json(&map)
|
||||
.send()
|
||||
@ -710,10 +713,13 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
|
||||
|
||||
/// stop the clash by service
|
||||
pub(super) async fn stop_core_by_service() -> Result<()> {
|
||||
use crate::utils::network::{NetworkManager, ProxyType};
|
||||
|
||||
let url = format!("{SERVICE_URL}/stop_clash");
|
||||
let _ = reqwest::ClientBuilder::new()
|
||||
.no_proxy()
|
||||
.build()?
|
||||
|
||||
// 使用网络管理器发送POST请求
|
||||
let client = NetworkManager::global().get_client(ProxyType::NoProxy);
|
||||
let _ = client
|
||||
.post(url)
|
||||
.send()
|
||||
.await
|
||||
|
@ -91,36 +91,27 @@ pub fn change_clash_mode(mode: String) {
|
||||
|
||||
/// Test connection delay to a URL
|
||||
pub async fn test_delay(url: String) -> anyhow::Result<u32> {
|
||||
use tokio::time::{Duration, Instant};
|
||||
let mut builder = reqwest::ClientBuilder::new().use_rustls_tls().no_proxy();
|
||||
use crate::utils::network::{NetworkManager, ProxyType};
|
||||
use tokio::time::Instant;
|
||||
|
||||
let port = Config::verge()
|
||||
.latest()
|
||||
.verge_mixed_port
|
||||
.unwrap_or(Config::clash().data().get_mixed_port());
|
||||
let tun_mode = Config::verge().latest().enable_tun_mode.unwrap_or(false);
|
||||
|
||||
let proxy_scheme = format!("http://127.0.0.1:{port}");
|
||||
// 如果是TUN模式,不使用代理,否则使用自身代理
|
||||
let proxy_type = if !tun_mode {
|
||||
ProxyType::SelfProxy
|
||||
} else {
|
||||
ProxyType::NoProxy
|
||||
};
|
||||
|
||||
if !tun_mode {
|
||||
if let Ok(proxy) = reqwest::Proxy::http(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = reqwest::Proxy::https(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = reqwest::Proxy::all(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
}
|
||||
let user_agent = Some("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0".to_string());
|
||||
|
||||
let request = builder
|
||||
.timeout(Duration::from_millis(10000))
|
||||
.build()?
|
||||
.get(url).header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0");
|
||||
let start = Instant::now();
|
||||
|
||||
let response = request.send().await;
|
||||
// 使用网络管理器发送请求,设置10秒超时
|
||||
let response = NetworkManager::global()
|
||||
.get(&url, proxy_type, Some(10), user_agent, false)
|
||||
.await;
|
||||
|
||||
match response {
|
||||
Ok(response) => {
|
||||
log::trace!(target: "app", "test_delay response: {:#?}", response);
|
||||
@ -132,7 +123,7 @@ pub async fn test_delay(url: String) -> anyhow::Result<u32> {
|
||||
}
|
||||
Err(err) => {
|
||||
log::trace!(target: "app", "test_delay error: {:#?}", err);
|
||||
Err(err.into())
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,9 @@ impl AppHandleManager {
|
||||
|
||||
#[allow(clippy::panic)]
|
||||
pub fn run() {
|
||||
// 初始化网络管理器
|
||||
utils::network::NetworkManager::global().init();
|
||||
|
||||
// 单例检测 - 使用超时机制防止阻塞
|
||||
let app_exists: bool = AsyncHandler::block_on(move || async move {
|
||||
match timeout(Duration::from_secs(3), server::check_singleton()).await {
|
||||
|
@ -15,6 +15,7 @@ pub enum Type {
|
||||
Frontend,
|
||||
Backup,
|
||||
Lightweight,
|
||||
Network,
|
||||
}
|
||||
|
||||
impl fmt::Display for Type {
|
||||
@ -33,6 +34,7 @@ impl fmt::Display for Type {
|
||||
Type::Frontend => write!(f, "[Frontend]"),
|
||||
Type::Backup => write!(f, "[Backup]"),
|
||||
Type::Lightweight => write!(f, "[Lightweight]"),
|
||||
Type::Network => write!(f, "[Network]"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ pub mod help;
|
||||
pub mod i18n;
|
||||
pub mod init;
|
||||
pub mod logging;
|
||||
pub mod network;
|
||||
pub mod resolve;
|
||||
pub mod server;
|
||||
pub mod tmpl;
|
||||
|
271
src-tauri/src/utils/network.rs
Normal file
271
src-tauri/src/utils/network.rs
Normal file
@ -0,0 +1,271 @@
|
||||
use anyhow::{Context, Result};
|
||||
use lazy_static::lazy_static;
|
||||
use reqwest::{Client, ClientBuilder, Proxy, RequestBuilder, Response};
|
||||
use std::sync::{Arc, Mutex, Once};
|
||||
use std::time::Duration;
|
||||
use tokio::runtime::{Builder, Runtime};
|
||||
|
||||
use crate::{config::Config, logging, utils::logging::Type};
|
||||
|
||||
/// 网络管理器
|
||||
pub struct NetworkManager {
|
||||
runtime: Arc<Runtime>,
|
||||
self_proxy_client: Arc<Mutex<Option<Client>>>,
|
||||
system_proxy_client: Arc<Mutex<Option<Client>>>,
|
||||
no_proxy_client: Arc<Mutex<Option<Client>>>,
|
||||
init: Once,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref NETWORK_MANAGER: NetworkManager = NetworkManager::new();
|
||||
}
|
||||
|
||||
impl NetworkManager {
|
||||
fn new() -> Self {
|
||||
// 创建专用的异步运行时,线程数限制为4个
|
||||
let runtime = Builder::new_multi_thread()
|
||||
.worker_threads(4)
|
||||
.thread_name("clash-verge-network")
|
||||
.enable_io()
|
||||
.enable_time()
|
||||
.build()
|
||||
.expect("Failed to create network runtime");
|
||||
|
||||
NetworkManager {
|
||||
runtime: Arc::new(runtime),
|
||||
self_proxy_client: Arc::new(Mutex::new(None)),
|
||||
system_proxy_client: Arc::new(Mutex::new(None)),
|
||||
no_proxy_client: Arc::new(Mutex::new(None)),
|
||||
init: Once::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn global() -> &'static Self {
|
||||
&NETWORK_MANAGER
|
||||
}
|
||||
|
||||
/// 初始化网络客户端
|
||||
pub fn init(&self) {
|
||||
self.init.call_once(|| {
|
||||
self.runtime.spawn(async {
|
||||
logging!(info, Type::Network, true, "初始化网络管理器");
|
||||
|
||||
// 创建无代理客户端
|
||||
let no_proxy_client = ClientBuilder::new()
|
||||
.use_rustls_tls()
|
||||
.no_proxy()
|
||||
.pool_max_idle_per_host(5)
|
||||
.pool_idle_timeout(Duration::from_secs(30))
|
||||
.connect_timeout(Duration::from_secs(10))
|
||||
.timeout(Duration::from_secs(30))
|
||||
.build()
|
||||
.expect("Failed to build no_proxy client");
|
||||
|
||||
let mut no_proxy_guard = NETWORK_MANAGER.no_proxy_client.lock().unwrap();
|
||||
*no_proxy_guard = Some(no_proxy_client);
|
||||
|
||||
logging!(info, Type::Network, true, "网络管理器初始化完成");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// 获取或创建自代理客户端
|
||||
fn get_or_create_self_proxy_client(&self) -> Client {
|
||||
let mut client_guard = self.self_proxy_client.lock().unwrap();
|
||||
|
||||
if client_guard.is_none() {
|
||||
let port = Config::verge()
|
||||
.latest()
|
||||
.verge_mixed_port
|
||||
.unwrap_or(Config::clash().data().get_mixed_port());
|
||||
|
||||
let proxy_scheme = format!("http://127.0.0.1:{port}");
|
||||
|
||||
let mut builder = ClientBuilder::new()
|
||||
.use_rustls_tls()
|
||||
.pool_max_idle_per_host(5)
|
||||
.pool_idle_timeout(Duration::from_secs(30))
|
||||
.connect_timeout(Duration::from_secs(10))
|
||||
.timeout(Duration::from_secs(60));
|
||||
|
||||
// 添加所有代理类型
|
||||
if let Ok(proxy) = Proxy::http(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = Proxy::https(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = Proxy::all(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
|
||||
let client = builder.build().expect("Failed to build self_proxy client");
|
||||
*client_guard = Some(client);
|
||||
}
|
||||
|
||||
client_guard.as_ref().unwrap().clone()
|
||||
}
|
||||
|
||||
/// 获取或创建系统代理客户端
|
||||
fn get_or_create_system_proxy_client(&self) -> Client {
|
||||
let mut client_guard = self.system_proxy_client.lock().unwrap();
|
||||
|
||||
if client_guard.is_none() {
|
||||
use sysproxy::Sysproxy;
|
||||
|
||||
let mut builder = ClientBuilder::new()
|
||||
.use_rustls_tls()
|
||||
.pool_max_idle_per_host(5)
|
||||
.pool_idle_timeout(Duration::from_secs(30))
|
||||
.connect_timeout(Duration::from_secs(10))
|
||||
.timeout(Duration::from_secs(60));
|
||||
|
||||
if let Ok(p @ Sysproxy { enable: true, .. }) = Sysproxy::get_system_proxy() {
|
||||
let proxy_scheme = format!("http://{}:{}", p.host, p.port);
|
||||
|
||||
if let Ok(proxy) = Proxy::http(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = Proxy::https(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = Proxy::all(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
}
|
||||
|
||||
let client = builder
|
||||
.build()
|
||||
.expect("Failed to build system_proxy client");
|
||||
*client_guard = Some(client);
|
||||
}
|
||||
|
||||
client_guard.as_ref().unwrap().clone()
|
||||
}
|
||||
|
||||
/// 根据代理设置选择合适的客户端
|
||||
pub fn get_client(&self, proxy_type: ProxyType) -> Client {
|
||||
match proxy_type {
|
||||
ProxyType::NoProxy => {
|
||||
let client_guard = self.no_proxy_client.lock().unwrap();
|
||||
client_guard.as_ref().unwrap().clone()
|
||||
}
|
||||
ProxyType::SelfProxy => self.get_or_create_self_proxy_client(),
|
||||
ProxyType::SystemProxy => self.get_or_create_system_proxy_client(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 创建带有自定义选项的HTTP请求
|
||||
pub fn create_request(
|
||||
&self,
|
||||
url: &str,
|
||||
proxy_type: ProxyType,
|
||||
timeout_secs: Option<u64>,
|
||||
user_agent: Option<String>,
|
||||
accept_invalid_certs: bool,
|
||||
) -> RequestBuilder {
|
||||
let mut builder = ClientBuilder::new()
|
||||
.use_rustls_tls()
|
||||
.connect_timeout(Duration::from_secs(10));
|
||||
|
||||
// 超时
|
||||
if let Some(timeout) = timeout_secs {
|
||||
builder = builder.timeout(Duration::from_secs(timeout));
|
||||
} else {
|
||||
builder = builder.timeout(Duration::from_secs(60));
|
||||
}
|
||||
|
||||
// 设置代理
|
||||
match proxy_type {
|
||||
ProxyType::NoProxy => {
|
||||
builder = builder.no_proxy();
|
||||
}
|
||||
ProxyType::SelfProxy => {
|
||||
let port = Config::verge()
|
||||
.latest()
|
||||
.verge_mixed_port
|
||||
.unwrap_or(Config::clash().data().get_mixed_port());
|
||||
|
||||
let proxy_scheme = format!("http://127.0.0.1:{port}");
|
||||
|
||||
if let Ok(proxy) = Proxy::http(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = Proxy::https(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = Proxy::all(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
}
|
||||
ProxyType::SystemProxy => {
|
||||
use sysproxy::Sysproxy;
|
||||
|
||||
if let Ok(p @ Sysproxy { enable: true, .. }) = Sysproxy::get_system_proxy() {
|
||||
let proxy_scheme = format!("http://{}:{}", p.host, p.port);
|
||||
|
||||
if let Ok(proxy) = Proxy::http(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = Proxy::https(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
if let Ok(proxy) = Proxy::all(&proxy_scheme) {
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 证书验证选项
|
||||
builder = builder.danger_accept_invalid_certs(accept_invalid_certs);
|
||||
|
||||
// 用户代理
|
||||
if let Some(ua) = user_agent {
|
||||
builder = builder.user_agent(ua);
|
||||
} else {
|
||||
use crate::utils::resolve::VERSION;
|
||||
|
||||
let version = match VERSION.get() {
|
||||
Some(v) => format!("clash-verge/v{}", v),
|
||||
None => "clash-verge/unknown".to_string(),
|
||||
};
|
||||
|
||||
builder = builder.user_agent(version);
|
||||
}
|
||||
|
||||
// 构建请求
|
||||
let client = builder.build().expect("Failed to build custom HTTP client");
|
||||
|
||||
client.get(url)
|
||||
}
|
||||
|
||||
/// 执行GET请求
|
||||
pub async fn get(
|
||||
&self,
|
||||
url: &str,
|
||||
proxy_type: ProxyType,
|
||||
timeout_secs: Option<u64>,
|
||||
user_agent: Option<String>,
|
||||
accept_invalid_certs: bool,
|
||||
) -> Result<Response> {
|
||||
self.create_request(
|
||||
url,
|
||||
proxy_type,
|
||||
timeout_secs,
|
||||
user_agent,
|
||||
accept_invalid_certs,
|
||||
)
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to send HTTP request")
|
||||
}
|
||||
}
|
||||
|
||||
/// 代理类型
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ProxyType {
|
||||
NoProxy,
|
||||
SelfProxy,
|
||||
SystemProxy,
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user