Route backend requests through the HTTP client factory (#34490)

## Why

Backend-backed features need to use the same outbound routing configuration as the rest of Codex.

## What changed

- Build the backend client on a route-aware client pool supplied by `HttpClientFactory`.
- Pass the configured factory through app-server account requests, cloud config loading, cloud tasks, and memory rate-limit checks.
- Preserve task query encoding, authentication headers, JSON request bodies, and ChatGPT cookie handling during the migration.

## Testing

- Add backend-client tests for proxy-policy propagation, task query encoding, bearer authentication, and JSON request bodies.

GitOrigin-RevId: c17d162e0dce9cec758df7cdeecf982207c6512b
This commit is contained in:
Michael Bolin authored and copyberry committed 2026-07-21 08:28:51 +00:00
1 parent d5998e7452
commit dc21b46aea
20 files changed
+365 -124

No files matched your search

@@ -538,7 +538,7 @@ impl AccountRequestProcessor {
let outgoing_clone = self.outgoing.clone();
let config_manager = self.config_manager.clone();
let thread_manager = Arc::clone(&self.thread_manager);
let chatgpt_base_url = self.config.chatgpt_base_url.clone();
let config = Arc::clone(&self.config);
let active_login = self.active_login.clone();
let auth_url = server.auth_url.clone();
tokio::spawn(async move {
@@ -560,7 +560,7 @@ impl AccountRequestProcessor {
&outgoing_clone,
config_manager,
thread_manager,
chatgpt_base_url,
config,
login_id,
success,
error_msg,
@@ -617,7 +617,7 @@ impl AccountRequestProcessor {
let outgoing_clone = self.outgoing.clone();
let config_manager = self.config_manager.clone();
let thread_manager = Arc::clone(&self.thread_manager);
let chatgpt_base_url = self.config.chatgpt_base_url.clone();
let config = Arc::clone(&self.config);
let active_login = self.active_login.clone();
tokio::spawn(async move {
let (success, error_msg) = tokio::select! {
@@ -636,7 +636,7 @@ impl AccountRequestProcessor {
&outgoing_clone,
config_manager,
thread_manager,
chatgpt_base_url,
config,
login_id,
success,
error_msg,
@@ -751,6 +751,7 @@ impl AccountRequestProcessor {
self.config_manager.replace_cloud_config_bundle_loader(
self.auth_manager.clone(),
self.config.chatgpt_base_url.clone(),
self.config.http_client_factory(),
);
self.config_manager
.sync_default_client_residency_requirement()
@@ -789,7 +790,7 @@ impl AccountRequestProcessor {
outgoing: &OutgoingMessageSender,
config_manager: ConfigManager,
thread_manager: Arc<ThreadManager>,
chatgpt_base_url: String,
config: Arc<Config>,
login_id: Uuid,
success: bool,
error_msg: Option<String>,
@@ -806,8 +807,11 @@ impl AccountRequestProcessor {
if success {
let auth_manager = thread_manager.auth_manager();
auth_manager.reload().await;
config_manager
.replace_cloud_config_bundle_loader(auth_manager.clone(), chatgpt_base_url);
config_manager.replace_cloud_config_bundle_loader(
auth_manager.clone(),
config.chatgpt_base_url.clone(),
config.http_client_factory(),
);
config_manager
.sync_default_client_residency_requirement()
.await;
@@ -1028,8 +1032,11 @@ impl AccountRequestProcessor {
));
}
let client = BackendClient::from_auth(self.config.chatgpt_base_url.clone(), &auth)
.map_err(|err| internal_error(format!("failed to construct backend client: {err}")))?;
let client = BackendClient::from_auth(
self.config.chatgpt_base_url.clone(),
&auth,
self.config.http_client_factory(),
);
let (response, detailed_rate_limit_reset_credits) = tokio::join!(
client.get_rate_limits_with_reset_credits(),
@@ -1098,8 +1105,11 @@ impl AccountRequestProcessor {
));
}
let client = BackendClient::from_auth(self.config.chatgpt_base_url.clone(), &auth)
.map_err(|err| internal_error(format!("failed to construct backend client: {err}")))?;
let client = BackendClient::from_auth(
self.config.chatgpt_base_url.clone(),
&auth,
self.config.http_client_factory(),
);
let profile = tokio::time::timeout(
ACCOUNT_TOKEN_USAGE_FETCH_TIMEOUT,
client.get_token_usage_profile(),
@@ -1125,8 +1135,11 @@ impl AccountRequestProcessor {
));
}
let client = BackendClient::from_auth(self.config.chatgpt_base_url.clone(), &auth)
.map_err(|err| internal_error(format!("failed to construct backend client: {err}")))?;
let client = BackendClient::from_auth(
self.config.chatgpt_base_url.clone(),
&auth,
self.config.http_client_factory(),
);
let messages = tokio::time::timeout(
ACCOUNT_WORKSPACE_MESSAGES_FETCH_TIMEOUT,
client.list_workspace_messages(),
@@ -1213,8 +1226,11 @@ impl AccountRequestProcessor {
));
}
let client = BackendClient::from_auth(self.config.chatgpt_base_url.clone(), &auth)
.map_err(|err| internal_error(format!("failed to construct backend client: {err}")))?;
let client = BackendClient::from_auth(
self.config.chatgpt_base_url.clone(),
&auth,
self.config.http_client_factory(),
);
match client
.send_add_credits_nudge_email(Self::backend_credit_type(params.credit_type))