diff --git a/codex-rs/codex-client/src/chatgpt_hosts.rs b/codex-rs/codex-client/src/chatgpt_hosts.rs index 7ab6819e79..dd0b99589c 100644 --- a/codex-rs/codex-client/src/chatgpt_hosts.rs +++ b/codex-rs/codex-client/src/chatgpt_hosts.rs @@ -10,18 +10,6 @@ pub fn is_allowed_chatgpt_host(host: &str) -> bool { .any(|suffix| host.ends_with(suffix)) } -/// Returns whether `url` is an HTTPS or secure WebSocket ChatGPT URL that Codex -/// may treat as first-party traffic. -pub fn is_allowed_chatgpt_request_url(url: &str) -> bool { - let Ok(url) = reqwest::Url::parse(url) else { - return false; - }; - if !matches!(url.scheme(), "https" | "wss") { - return false; - } - url.host_str().is_some_and(is_allowed_chatgpt_host) -} - #[cfg(test)] mod tests { use super::*; @@ -48,25 +36,4 @@ mod tests { assert!(!is_allowed_chatgpt_host(host)); } } - - #[test] - fn recognizes_secure_chatgpt_request_urls() { - for url in [ - "https://chatgpt.com/backend-api/codex/responses", - "https://preview.chatgpt.com/backend-api/codex/models", - "wss://chatgpt-staging.com/backend-api/codex/responses", - ] { - assert!(is_allowed_chatgpt_request_url(url)); - } - - for url in [ - "http://chatgpt.com/backend-api/codex/responses", - "ws://chatgpt.com/backend-api/codex/responses", - "https://api.openai.com/v1/responses", - "https://chatgpt.com.evil.example/backend-api", - "not a url", - ] { - assert!(!is_allowed_chatgpt_request_url(url)); - } - } } diff --git a/codex-rs/codex-client/src/lib.rs b/codex-rs/codex-client/src/lib.rs index 520132e0e0..0f503fb3e2 100644 --- a/codex-rs/codex-client/src/lib.rs +++ b/codex-rs/codex-client/src/lib.rs @@ -11,7 +11,6 @@ mod transport; pub use crate::chatgpt_cloudflare_cookies::with_chatgpt_cloudflare_cookie_store; pub use crate::chatgpt_hosts::is_allowed_chatgpt_host; -pub use crate::chatgpt_hosts::is_allowed_chatgpt_request_url; pub use crate::custom_ca::BuildCustomCaTransportError; /// Test-only subprocess hook for custom CA coverage. /// @@ -26,8 +25,6 @@ pub use crate::default_client::CodexHttpClient; pub use crate::default_client::CodexRequestBuilder; pub use crate::error::StreamError; pub use crate::error::TransportError; -pub const INTEGRITY_STATE_HEADER_NAME: &str = "X-OAI-IS"; -pub const INTEGRITY_STATE_UPDATE_HEADER_NAME: &str = "X-OAI-IS-Update"; pub use crate::request::PreparedRequestBody; pub use crate::request::Request; pub use crate::request::RequestBody; diff --git a/codex-rs/http-state/src/lib.rs b/codex-rs/http-state/src/lib.rs index c045f53d97..7c6d3600e9 100644 --- a/codex-rs/http-state/src/lib.rs +++ b/codex-rs/http-state/src/lib.rs @@ -29,18 +29,23 @@ pub enum HttpStateSurface { } impl HttpStateSurface { - pub fn from_app_server_client_name(client_name: &str) -> Self { + pub fn try_from_app_server_client_name(client_name: &str) -> Option { match client_name { - "codex-tui" => Self::CodexTui, - "codex_exec" => Self::CodexExec, - "codex_vscode" => Self::CodexVscode, - "codex_desktop" => Self::CodexDesktop, - "codex_desktop_ssh" => Self::CodexDesktopSsh, - "codex_remote_control" => Self::CodexRemoteControl, - _ => Self::CodexCli, + "codex_cli" => Some(Self::CodexCli), + "codex-tui" => Some(Self::CodexTui), + "codex_exec" => Some(Self::CodexExec), + "codex_vscode" => Some(Self::CodexVscode), + "codex_desktop" => Some(Self::CodexDesktop), + "codex_desktop_ssh" => Some(Self::CodexDesktopSsh), + "codex_remote_control" => Some(Self::CodexRemoteControl), + _ => None, } } + pub fn from_app_server_client_name(client_name: &str) -> Self { + Self::try_from_app_server_client_name(client_name).unwrap_or(Self::CodexCli) + } + pub const fn as_str(self) -> &'static str { match self { Self::CodexCli => "codex_cli", diff --git a/codex-rs/http-state/src/tests.rs b/codex-rs/http-state/src/tests.rs index 56bc12a6ff..03af2f4660 100644 --- a/codex-rs/http-state/src/tests.rs +++ b/codex-rs/http-state/src/tests.rs @@ -2,13 +2,14 @@ use super::*; use pretty_assertions::assert_eq; use tempfile::TempDir; -const STATE_N: &str = "ois1.a.b.c"; -const STATE_N_PLUS_ONE: &str = "ois1.d.e.f"; +const STATE_N: &str = "state-n"; +const STATE_N_PLUS_ONE: &str = "state-n-plus-one"; #[test] fn maps_app_server_client_names_to_bounded_surfaces() { assert_eq!( [ + "codex_cli", "codex-tui", "codex_exec", "codex_vscode", @@ -19,6 +20,7 @@ fn maps_app_server_client_names_to_bounded_surfaces() { ] .map(HttpStateSurface::from_app_server_client_name), [ + HttpStateSurface::CodexCli, HttpStateSurface::CodexTui, HttpStateSurface::CodexExec, HttpStateSurface::CodexVscode, @@ -28,6 +30,10 @@ fn maps_app_server_client_names_to_bounded_surfaces() { HttpStateSurface::CodexCli, ] ); + assert_eq!( + HttpStateSurface::try_from_app_server_client_name("third_party_client"), + None + ); } #[test] @@ -83,7 +89,7 @@ fn compare_and_set_rejects_a_stale_prior_value() { !store .compare_and_set( HttpStateSurface::CodexCli, - "ois1.stale.state.value", + "stale-state", STATE_N_PLUS_ONE.to_string(), ) .expect("compare should succeed")