mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
Use the shared HTTP client for TUI network checks (#35821)
## Why TUI update checks and local OSS provider detection constructed their own HTTP clients instead of using Codex's shared client behavior. ## What changed - Route update requests through the configured route-aware client pool while retaining the existing default headers and custom CA fallback. - Probe the hardcoded LM Studio and Ollama loopback endpoints with a shared direct client and a per-request timeout. - Limit the legacy invalid-custom-CA fallback to the default routing policy so system-proxy routing still reports certificate configuration errors. ## Testing Add coverage for local provider probes with invalid `CODEX_CA_CERTIFICATE` and `SSL_CERT_FILE` values, and for custom CA fallback under both routing policies. GitOrigin-RevId: b5c230b61e8964b3f1af3395052361ff716d6ce1
This commit is contained in:
@@ -65,6 +65,81 @@ async fn streams_request_bodies_without_exposing_reqwest_body() {
|
||||
assert!(requests[0].ends_with("\r\n\r\nhello"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn legacy_custom_ca_fallback_is_limited_to_reqwest_default() {
|
||||
const CHILD_POLICY_ENV: &str = "CODEX_HTTP_CLIENT_POOL_INVALID_CA_TEST_POLICY";
|
||||
|
||||
let Ok(policy_name) = std::env::var(CHILD_POLICY_ENV) else {
|
||||
let temp_dir = tempfile::tempdir().expect("temporary directory should be created");
|
||||
let invalid_ca_path = temp_dir.path().join("invalid-ca.pem");
|
||||
std::fs::write(&invalid_ca_path, "not a PEM certificate")
|
||||
.expect("invalid CA fixture should be written");
|
||||
|
||||
for ca_env in ["CODEX_CA_CERTIFICATE", "SSL_CERT_FILE"] {
|
||||
for policy_name in ["reqwest-default", "respect-system-proxy"] {
|
||||
let output = std::process::Command::new(
|
||||
std::env::current_exe().expect("test executable should be available"),
|
||||
)
|
||||
.arg("--exact")
|
||||
.arg("route_aware_client_pool::tests::legacy_custom_ca_fallback_is_limited_to_reqwest_default")
|
||||
.arg("--nocapture")
|
||||
.env_remove("CODEX_CA_CERTIFICATE")
|
||||
.env_remove("SSL_CERT_FILE")
|
||||
.env(ca_env, &invalid_ca_path)
|
||||
.env(CHILD_POLICY_ENV, policy_name)
|
||||
.output()
|
||||
.expect("isolated CA subprocess should run");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"{policy_name} failed with invalid {ca_env}\nstdout:\n{}\nstderr:\n{}",
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
);
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
let outbound_proxy_policy = match policy_name.as_str() {
|
||||
"reqwest-default" => OutboundProxyPolicy::ReqwestDefault,
|
||||
"respect-system-proxy" => OutboundProxyPolicy::RespectSystemProxy,
|
||||
_ => panic!("unexpected test proxy policy: {policy_name}"),
|
||||
};
|
||||
let pool = RouteAwareClientPool::with_chatgpt_cloudflare_cookies(
|
||||
HttpClientFactory::new(outbound_proxy_policy),
|
||||
ClientRouteClass::Other,
|
||||
)
|
||||
.with_legacy_custom_ca_fallback();
|
||||
|
||||
match outbound_proxy_policy {
|
||||
OutboundProxyPolicy::ReqwestDefault => {
|
||||
let (address, server) = spawn_response_server(vec![
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 0\r\nConnection: close\r\n\r\n".to_string(),
|
||||
]);
|
||||
let response = pool
|
||||
.get(format!("http://{address}/update"))
|
||||
.send()
|
||||
.await
|
||||
.expect("default-routed request should fall back to system roots");
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
let requests = server.join().expect("response server should finish");
|
||||
assert_eq!(requests.len(), 1);
|
||||
}
|
||||
OutboundProxyPolicy::RespectSystemProxy => {
|
||||
let error = pool
|
||||
.client_for_url_with_resolver("http://127.0.0.1/update", |_| async {
|
||||
Ok(OutboundProxyRoute::Direct)
|
||||
})
|
||||
.await
|
||||
.expect_err("system-proxy routes should reject invalid custom CAs");
|
||||
|
||||
assert!(matches!(error, RouteAwareClientPoolError::Build(_)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn without_url_redacts_transport_error_urls() {
|
||||
let listener = TcpListener::bind(("127.0.0.1", 0)).expect("listener should bind");
|
||||
|
||||
Reference in New Issue
Block a user