Revert "refactor: remove subscription TLS roots fallback"

This reverts commit 746279fa03.
This commit is contained in:
Tunglies
2026-05-28 02:42:13 +08:00
parent f916711717
commit dc094033b8
2 changed files with 97 additions and 15 deletions
-7
View File
@@ -15,13 +15,6 @@
</details>
<details>
<summary><strong> 🧹 移除变更 </strong></summary>
- 移除订阅下载 TLS 校验失败后的静态根证书回退重试
</details>
<details>
<summary><strong> 🚀 优化改进 </strong></summary>
+97 -8
View File
@@ -6,7 +6,7 @@ use reqwest::{
header::{HeaderMap, HeaderValue, USER_AGENT},
};
use smartstring::alias::String;
use std::time::Duration;
use std::{sync::Arc, time::Duration};
use sysproxy::Sysproxy;
use tauri::Url;
@@ -42,6 +42,12 @@ pub enum ProxyType {
System,
}
#[derive(Debug, Clone, Copy)]
enum TlsRootMode {
PlatformVerifier,
StaticWebpkiRoots,
}
pub struct NetworkManager;
impl Default for NetworkManager {
@@ -61,6 +67,7 @@ impl NetworkManager {
default_headers: HeaderMap,
accept_invalid_certs: bool,
timeout_secs: Option<u64>,
tls_root_mode: TlsRootMode,
) -> Result<Client> {
let mut builder = Client::builder()
.tls_backend_rustls()
@@ -69,6 +76,10 @@ impl NetworkManager {
.pool_max_idle_per_host(0)
.pool_idle_timeout(None);
if matches!(tls_root_mode, TlsRootMode::StaticWebpkiRoots) {
builder = builder.tls_backend_preconfigured(Self::build_static_webpki_tls_config()?);
}
// 设置代理
if let Some(proxy_str) = proxy_url {
let proxy = Proxy::all(proxy_str)?;
@@ -96,6 +107,44 @@ impl NetworkManager {
Ok(builder.build()?)
}
fn build_static_webpki_tls_config() -> Result<rustls::ClientConfig> {
let root_store = rustls::RootCertStore::from_iter(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
let mut config =
rustls::ClientConfig::builder_with_provider(Arc::new(rustls::crypto::ring::default_provider()))
.with_safe_default_protocol_versions()?
.with_root_certificates(root_store)
.with_no_client_auth();
config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
Ok(config)
}
fn should_retry_with_static_webpki_roots(err: &anyhow::Error) -> bool {
if err.chain().any(Self::is_legacy_tls_protocol_error) {
return false;
}
err.chain().any(|e| {
let msg = e.to_string().to_ascii_lowercase();
[
"certificate",
"cert",
"tls",
"ssl",
"rustls",
"webpki",
"revocation",
"ocsp",
"crl",
"issuer",
"unknownissuer",
]
.iter()
.any(|kw| msg.contains(kw))
})
}
fn context_reqwest_error(err: reqwest::Error, context: &'static str) -> anyhow::Error {
let legacy_tls = Self::is_legacy_tls_protocol_error(&err);
let err = anyhow::Error::new(err).context(context);
@@ -119,17 +168,24 @@ impl NetworkManager {
user_agent: Option<String>,
accept_invalid_certs: bool,
) -> Result<Client> {
self.create_request_with_tls_mode(proxy_type, timeout_secs, user_agent, accept_invalid_certs)
.await
self.create_request_with_tls_mode(
proxy_type,
timeout_secs,
user_agent,
accept_invalid_certs,
TlsRootMode::PlatformVerifier,
)
.await
}
async fn get(
async fn get_with_tls_mode(
&self,
url: &str,
proxy_type: ProxyType,
timeout_secs: Option<u64>,
user_agent: Option<String>,
accept_invalid_certs: bool,
tls_root_mode: TlsRootMode,
) -> Result<HttpResponse> {
let mut parsed = Url::parse(url)?;
let mut extra_headers = HeaderMap::new();
@@ -151,7 +207,13 @@ impl NetworkManager {
// 创建请求
let client = self
.create_request_with_tls_mode(proxy_type, timeout_secs, user_agent, accept_invalid_certs)
.create_request_with_tls_mode(
proxy_type,
timeout_secs,
user_agent,
accept_invalid_certs,
tls_root_mode,
)
.await?;
let mut request_builder = client.get(parsed);
@@ -185,6 +247,7 @@ impl NetworkManager {
timeout_secs: Option<u64>,
user_agent: Option<String>,
accept_invalid_certs: bool,
tls_root_mode: TlsRootMode,
) -> Result<Client> {
let proxy_url: Option<std::string::String> = match proxy_type {
ProxyType::None => None,
@@ -219,7 +282,7 @@ impl NetworkManager {
);
}
self.build_client(proxy_url, headers, accept_invalid_certs, timeout_secs)
self.build_client(proxy_url, headers, accept_invalid_certs, timeout_secs, tls_root_mode)
}
pub async fn get_with_interrupt(
@@ -230,7 +293,33 @@ impl NetworkManager {
user_agent: Option<String>,
accept_invalid_certs: bool,
) -> Result<HttpResponse> {
self.get(url, proxy_type, timeout_secs, user_agent, accept_invalid_certs)
.await
let platform_result = self
.get_with_tls_mode(
url,
proxy_type,
timeout_secs,
user_agent.clone(),
accept_invalid_certs,
TlsRootMode::PlatformVerifier,
)
.await;
match platform_result {
Ok(response) => Ok(response),
Err(err) if !accept_invalid_certs && Self::should_retry_with_static_webpki_roots(&err) => self
.get_with_tls_mode(
url,
proxy_type,
timeout_secs,
user_agent,
accept_invalid_certs,
TlsRootMode::StaticWebpkiRoots,
)
.await
.map_err(|fallback_err| {
fallback_err.context("static webpki roots fallback failed after platform TLS verifier failed")
}),
Err(err) => Err(err),
}
}
}