mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-28 21:44:38 +00:00
fix(windows): make pnpm dev:app:win work behind TLS-inspecting proxies (#2449)
This commit is contained in:
+4
-3
@@ -78,10 +78,11 @@ fn build_backend_reqwest_client() -> Result<Client> {
|
||||
);
|
||||
}
|
||||
|
||||
// Force rustls for consistent cross-platform TLS behavior.
|
||||
Client::builder()
|
||||
// Platform-appropriate TLS backend: Windows → schannel (honors the OS
|
||||
// cert store, required for corporate TLS-inspection proxies); macOS /
|
||||
// Linux → rustls. See [`crate::openhuman::tls::tls_client_builder`].
|
||||
crate::openhuman::tls::tls_client_builder()
|
||||
.default_headers(default_headers)
|
||||
.use_rustls_tls()
|
||||
.http1_only()
|
||||
.timeout(Duration::from_secs(120))
|
||||
.connect_timeout(Duration::from_secs(15))
|
||||
|
||||
@@ -263,8 +263,8 @@ fn save_stored_app_state(config: &Config, state: &StoredAppState) -> Result<(),
|
||||
}
|
||||
|
||||
fn build_client() -> Result<Client, String> {
|
||||
Client::builder()
|
||||
.use_rustls_tls()
|
||||
// Platform-appropriate TLS backend — see [`crate::openhuman::tls`].
|
||||
crate::openhuman::tls::tls_client_builder()
|
||||
.http1_only()
|
||||
.timeout(Duration::from_secs(30))
|
||||
.connect_timeout(Duration::from_secs(10))
|
||||
|
||||
@@ -455,11 +455,10 @@ impl ComposioClient {
|
||||
// from `IntegrationClient`, which we intentionally avoid so the
|
||||
// public surface of that type doesn't widen for one caller.
|
||||
//
|
||||
// Mirror the TLS settings of the shared client
|
||||
// (`use_rustls_tls + http1_only`) so this path has the same
|
||||
// connection behaviour as the other backend calls.
|
||||
let http_client = reqwest::Client::builder()
|
||||
.use_rustls_tls()
|
||||
// Mirror the TLS settings of the shared client so this path has the
|
||||
// same connection behaviour as the other backend calls.
|
||||
// Platform-appropriate TLS backend — see [`crate::openhuman::tls`].
|
||||
let http_client = crate::openhuman::tls::tls_client_builder()
|
||||
.http1_only()
|
||||
.timeout(std::time::Duration::from_secs(60))
|
||||
.connect_timeout(std::time::Duration::from_secs(15))
|
||||
|
||||
@@ -441,10 +441,15 @@ pub fn build_runtime_proxy_client(service_key: &str) -> reqwest::Client {
|
||||
return client;
|
||||
}
|
||||
|
||||
let builder = apply_runtime_proxy_to_builder(reqwest::Client::builder(), service_key);
|
||||
// Platform-appropriate TLS backend — see [`crate::openhuman::tls`].
|
||||
let builder =
|
||||
apply_runtime_proxy_to_builder(crate::openhuman::tls::tls_client_builder(), service_key);
|
||||
let client = builder.build().unwrap_or_else(|error| {
|
||||
tracing::warn!(service_key, "Failed to build proxied client: {error}");
|
||||
reqwest::Client::new()
|
||||
// Apply the same platform TLS selection on the fallback path so the
|
||||
// error-path client also honors the Windows cert store.
|
||||
let fb = crate::openhuman::tls::tls_client_builder();
|
||||
fb.build().unwrap_or_default()
|
||||
});
|
||||
set_runtime_proxy_cached_client(cache_key, client.clone());
|
||||
client
|
||||
@@ -461,16 +466,23 @@ pub fn build_runtime_proxy_client_with_timeouts(
|
||||
return client;
|
||||
}
|
||||
|
||||
let builder = reqwest::Client::builder()
|
||||
// Platform-appropriate TLS backend — see [`crate::openhuman::tls`].
|
||||
let raw = crate::openhuman::tls::tls_client_builder()
|
||||
.timeout(std::time::Duration::from_secs(timeout_secs))
|
||||
.connect_timeout(std::time::Duration::from_secs(connect_timeout_secs));
|
||||
let builder = apply_runtime_proxy_to_builder(builder, service_key);
|
||||
let builder = apply_runtime_proxy_to_builder(raw, service_key);
|
||||
let client = builder.build().unwrap_or_else(|error| {
|
||||
tracing::warn!(
|
||||
service_key,
|
||||
"Failed to build proxied timeout client: {error}"
|
||||
);
|
||||
reqwest::Client::new()
|
||||
// Apply the same platform TLS selection and timeouts on the fallback
|
||||
// path so the error-path client also honors the Windows cert store
|
||||
// and remains bounded.
|
||||
let fb = crate::openhuman::tls::tls_client_builder()
|
||||
.timeout(std::time::Duration::from_secs(timeout_secs))
|
||||
.connect_timeout(std::time::Duration::from_secs(connect_timeout_secs));
|
||||
fb.build().unwrap_or_default()
|
||||
});
|
||||
set_runtime_proxy_cached_client(cache_key, client.clone());
|
||||
client
|
||||
|
||||
@@ -278,8 +278,8 @@ impl OpenAiCompatibleProvider {
|
||||
headers.insert(USER_AGENT, value);
|
||||
}
|
||||
|
||||
let builder = Client::builder()
|
||||
.use_rustls_tls()
|
||||
// Platform-appropriate TLS backend — see [`crate::openhuman::tls`].
|
||||
let builder = crate::openhuman::tls::tls_client_builder()
|
||||
.timeout(std::time::Duration::from_secs(120))
|
||||
.connect_timeout(std::time::Duration::from_secs(10))
|
||||
.default_headers(headers);
|
||||
@@ -290,12 +290,14 @@ impl OpenAiCompatibleProvider {
|
||||
|
||||
return builder.build().unwrap_or_else(|error| {
|
||||
tracing::warn!("Failed to build proxied timeout client with user-agent: {error}");
|
||||
Client::new()
|
||||
crate::openhuman::tls::tls_client_builder()
|
||||
.build()
|
||||
.unwrap_or_default()
|
||||
});
|
||||
}
|
||||
|
||||
let builder = Client::builder()
|
||||
.use_rustls_tls()
|
||||
// Platform-appropriate TLS backend — see [`crate::openhuman::tls`].
|
||||
let builder = crate::openhuman::tls::tls_client_builder()
|
||||
.timeout(std::time::Duration::from_secs(120))
|
||||
.connect_timeout(std::time::Duration::from_secs(10));
|
||||
let builder = crate::openhuman::config::apply_runtime_proxy_to_builder(
|
||||
@@ -304,7 +306,9 @@ impl OpenAiCompatibleProvider {
|
||||
);
|
||||
builder.build().unwrap_or_else(|error| {
|
||||
tracing::warn!("Failed to build proxied timeout client: {error}");
|
||||
Client::new()
|
||||
crate::openhuman::tls::tls_client_builder()
|
||||
.build()
|
||||
.unwrap_or_default()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -92,16 +92,11 @@ impl IntegrationClient {
|
||||
// to fix up the input so the regression is observable in logs.
|
||||
let backend_url = sanitize_backend_url(&backend_url);
|
||||
|
||||
// Match the TLS config used by `BackendOAuthClient` in
|
||||
// `src/api/rest.rs`: force rustls + HTTP/1.1 so we get the same
|
||||
// consistent cross-platform behaviour every other backend-proxied
|
||||
// domain (billing, team, webhooks, referral, …) already relies
|
||||
// on. The default builder picks up native-tls on macOS, which
|
||||
// has historically failed on staging TLS handshakes while
|
||||
// rustls succeeds — so the integrations client was the odd one
|
||||
// out with raw "error sending request" failures.
|
||||
let http_client = reqwest::Client::builder()
|
||||
.use_rustls_tls()
|
||||
// Platform-appropriate TLS backend — see [`crate::openhuman::tls`].
|
||||
// Windows uses schannel (native-tls) to honor the OS cert store;
|
||||
// macOS / Linux keep rustls which avoids the OpenSSL runtime dep and
|
||||
// has historically been more reliable on staging TLS handshakes.
|
||||
let http_client = crate::openhuman::tls::tls_client_builder()
|
||||
.http1_only()
|
||||
.timeout(Duration::from_secs(60))
|
||||
.connect_timeout(Duration::from_secs(15))
|
||||
|
||||
@@ -23,8 +23,8 @@ fn shared_http_client() -> reqwest::Client {
|
||||
SHARED_HTTP_CLIENT
|
||||
.get_or_init(|| {
|
||||
tracing::debug!("[searxng] initializing shared HTTP client");
|
||||
reqwest::Client::builder()
|
||||
.use_rustls_tls()
|
||||
// Platform-appropriate TLS backend — see [`crate::openhuman::tls`].
|
||||
crate::openhuman::tls::tls_client_builder()
|
||||
.build()
|
||||
.expect("failed to build shared SearXNG HTTP client")
|
||||
})
|
||||
|
||||
@@ -64,8 +64,8 @@ impl SeltzSearchTool {
|
||||
timeout_secs: u64,
|
||||
) -> Self {
|
||||
let timeout = timeout_secs.max(1);
|
||||
let http_client = reqwest::Client::builder()
|
||||
.use_rustls_tls()
|
||||
// Platform-appropriate TLS backend — see [`crate::openhuman::tls`].
|
||||
let http_client = crate::openhuman::tls::tls_client_builder()
|
||||
.http1_only()
|
||||
.timeout(Duration::from_secs(timeout))
|
||||
.connect_timeout(Duration::from_secs(10))
|
||||
|
||||
@@ -74,6 +74,7 @@ pub mod team;
|
||||
pub mod test_support;
|
||||
pub mod text_input;
|
||||
pub mod threads;
|
||||
pub mod tls;
|
||||
pub mod todos;
|
||||
pub mod tokenjuice;
|
||||
pub mod tool_registry;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//! Platform-conditional TLS backend selection for reqwest clients.
|
||||
//!
|
||||
//! Centralises the `#[cfg(target_os = "windows")]` / `#[cfg(not(target_os = "windows"))]`
|
||||
//! guard so every HTTP-client construction site stays at one line and future
|
||||
//! policy changes (e.g. adding native-tls on macOS) only require editing this file.
|
||||
//!
|
||||
//! # Policy
|
||||
//! - **Windows**: `native-tls` (schannel) — honors the Windows certificate store,
|
||||
//! including any corporate CA installed by AV / TLS-inspecting proxies that
|
||||
//! re-sign certificates with a private root. `rustls` + webpki-roots only knows
|
||||
//! Mozilla CAs and fails such environments with `UnknownIssuer`.
|
||||
//! - **macOS / Linux**: `rustls` + webpki-roots — avoids the OpenSSL runtime
|
||||
//! dependency on Linux and has historically been more reliable on macOS staging
|
||||
//! TLS handshakes than `native-tls`.
|
||||
|
||||
/// Return a `reqwest::ClientBuilder` pre-configured with the platform-appropriate
|
||||
/// TLS backend.
|
||||
///
|
||||
/// Use this as the starting point for every client that needs to reach external
|
||||
/// HTTPS endpoints:
|
||||
/// ```rust,ignore
|
||||
/// let client = tls_client_builder()
|
||||
/// .http1_only()
|
||||
/// .timeout(Duration::from_secs(30))
|
||||
/// .build()?;
|
||||
/// ```
|
||||
pub fn tls_client_builder() -> reqwest::ClientBuilder {
|
||||
let b = reqwest::Client::builder();
|
||||
#[cfg(target_os = "windows")]
|
||||
let b = b.use_native_tls();
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let b = b.use_rustls_tls();
|
||||
b
|
||||
}
|
||||
Reference in New Issue
Block a user