From f3f50a818f65df52628a64cc16bca96cc7117947 Mon Sep 17 00:00:00 2001 From: zyycn Date: Sun, 2 Aug 2026 02:20:28 +0800 Subject: [PATCH] fix(openai): install ring crypto provider before rustls use rustls 0.23 compiles both ring and aws-lc-rs in this workspace (aws-sdk-s3 pulls aws-lc-rs), so the process-level CryptoProvider cannot be auto-selected and any TLS use panics inside spawned tasks - which made the websocket idle timeout test hang forever. Install the pinned ring provider once before the first TLS use, with a startup call in the gateway binary as a fallback. Co-authored-by: Codex --- backend/apps/gateway/src/main.rs | 3 +++ .../providers/openai/src/transport/tls.rs | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/backend/apps/gateway/src/main.rs b/backend/apps/gateway/src/main.rs index a1a79f653..6b7d4b15c 100644 --- a/backend/apps/gateway/src/main.rs +++ b/backend/apps/gateway/src/main.rs @@ -1,6 +1,9 @@ use std::{env, error::Error, io}; +use provider_openai::transport::tls::ensure_rustls_provider; + fn main() -> Result<(), Box> { + ensure_rustls_provider(); let mut arguments = env::args_os().skip(1); match arguments.next().as_deref().and_then(|value| value.to_str()) { None | Some("serve") => { diff --git a/backend/crates/providers/openai/src/transport/tls.rs b/backend/crates/providers/openai/src/transport/tls.rs index e9300ac59..43de4de61 100644 --- a/backend/crates/providers/openai/src/transport/tls.rs +++ b/backend/crates/providers/openai/src/transport/tls.rs @@ -1,4 +1,8 @@ -use std::{env, fs, io, path::PathBuf, sync::Arc}; +use std::{ + env, fs, io, + path::PathBuf, + sync::{Arc, OnceLock}, +}; use rustls::{ClientConfig, RootCertStore}; use rustls_pki_types::{ @@ -11,6 +15,16 @@ const CA_CERT_HINT: &str = "If you set CODEX_CA_CERTIFICATE or SSL_CERT_FILE, en type PemSection = (SectionKind, Vec); +/// rustls 0.23 在同时编译 `ring` 与 `aws-lc-rs` 时无法自动选择进程级 +/// CryptoProvider;本工程固定使用 ring(与官方 Codex Desktop JA3 一致), +/// 因此在首次 TLS 使用前显式安装一次。重复安装会被 rustls 忽略。 +pub fn ensure_rustls_provider() { + static INSTALL: OnceLock<()> = OnceLock::new(); + INSTALL.get_or_init(|| { + let _ = rustls::crypto::ring::default_provider().install_default(); + }); +} + /// 自定义 CA 证书环境变量名。 pub const CODEX_CA_CERT_ENV: &str = "CODEX_CA_CERTIFICATE"; /// 系统 CA 文件环境变量名。 @@ -111,6 +125,7 @@ fn build_reqwest_client_with_env( env_source: &dyn EnvSource, mut builder: reqwest::ClientBuilder, ) -> CustomCaResult { + ensure_rustls_provider(); let Some(bundle) = env_source.configured_ca_bundle() else { return builder .build() @@ -142,6 +157,7 @@ fn build_reqwest_client_with_env( fn maybe_build_rustls_client_config_with_env( env_source: &dyn EnvSource, ) -> CustomCaResult>> { + ensure_rustls_provider(); let Some(bundle) = env_source.configured_ca_bundle() else { return Ok(None); };