mirror of
https://github.com/openai/codex.git
synced 2026-11-10 16:44:38 +00:00
Add rustls fallback for local MCP HTTP requests (#38436)
## Why Local MCP requests can fail when the platform TLS backend cannot negotiate a protocol version with an HTTPS endpoint. ## What changed - Retry replayable local MCP requests once with rustls after a recognized TLS protocol-version negotiation failure. Keep certificate, timeout, and unrelated connection failures on the existing error path. - Remember successful fallback per HTTPS origin and outbound route, while keeping the platform TLS backend as the default for other destinations. - Share the fallback-enabled client across local MCP resolution, CLI login, and OAuth discovery while preserving remote environment HTTP clients. ## Testing Added coverage for platform-specific error detection, request replay, cached fallback reuse and isolation, non-replayable requests, redirects, and remote MCP client selection. GitOrigin-RevId: 39a2d96fdb2ea0e51df14f652ba2a953d24e69a1
This commit is contained in:
1 parent
93327c852a
commit
b87327f4e5
10 files changed
+1204
-30
No files matched your search
@@ -9,6 +9,8 @@ use http::HeaderMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use codex_utils_rustls_provider::ensure_rustls_crypto_provider;
|
||||
|
||||
use crate::BuildCustomCaTransportError;
|
||||
use crate::BuildRouteAwareHttpClientError;
|
||||
use crate::ClientRouteClass;
|
||||
@@ -33,6 +35,14 @@ pub struct HttpClientBuilder {
|
||||
chatgpt_cloudflare_cookie_store: bool,
|
||||
chatgpt_cookie_store: Option<Arc<ChatGptCookieStore>>,
|
||||
request_logging: RequestLogging,
|
||||
tls_backend: TlsBackend,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||
enum TlsBackend {
|
||||
#[default]
|
||||
TransportDefault,
|
||||
Rustls,
|
||||
}
|
||||
|
||||
impl HttpClientFactory {
|
||||
@@ -85,6 +95,11 @@ impl HttpClientBuilder {
|
||||
self.follow_redirects
|
||||
}
|
||||
|
||||
pub(crate) fn with_rustls_tls(mut self) -> Self {
|
||||
self.tls_backend = TlsBackend::Rustls;
|
||||
self
|
||||
}
|
||||
|
||||
/// Limits only connection establishment, not the request as a whole.
|
||||
pub fn connect_timeout(mut self, timeout: Duration) -> Self {
|
||||
self.connect_timeout = Some(timeout);
|
||||
@@ -260,6 +275,10 @@ impl HttpClientBuilder {
|
||||
|
||||
fn base_reqwest_builder(self) -> reqwest::ClientBuilder {
|
||||
let mut builder = reqwest::Client::builder();
|
||||
if self.tls_backend == TlsBackend::Rustls {
|
||||
ensure_rustls_crypto_provider();
|
||||
builder = builder.use_rustls_tls();
|
||||
}
|
||||
if let Some(default_headers) = self.default_headers {
|
||||
builder = builder.default_headers(default_headers);
|
||||
}
|
||||
@@ -288,6 +307,7 @@ impl Default for HttpClientBuilder {
|
||||
chatgpt_cloudflare_cookie_store: false,
|
||||
chatgpt_cookie_store: None,
|
||||
request_logging: RequestLogging::Enabled,
|
||||
tls_backend: TlsBackend::TransportDefault,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user