Download codex-rs/exec-server/src/remote/direct.rs from SaylorTwift/codex: direct link, hf CLI and curl.
- Browser
- Download file 10 kB
-
https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/exec-server/src/remote/direct.rs
- Command line
-
hf download hf://SaylorTwift/codex/codex-rs/exec-server/src/remote/direct.rs
-
curl -L -o direct.rs https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/exec-server/src/remote/direct.rs
10 kB
| use std::time::Instant; | |
| use codex_api::AuthError; | |
| use codex_api::AuthProvider; | |
| use codex_http_client::Request; | |
| use codex_websocket_client::WebSocketConnection; | |
| use codex_websocket_client::WebSocketConnector; | |
| use http::Method; | |
| use http::StatusCode; | |
| use serde::Deserialize; | |
| use serde::Serialize; | |
| use tokio::time::sleep; | |
| use tokio_tungstenite::tungstenite::client::IntoClientRequest; | |
| use tracing::info; | |
| use tracing::warn; | |
| use super::EnvironmentRegistryClient; | |
| use super::RemoteEnvironmentConfig; | |
| use crate::ExecServerError; | |
| use crate::client::is_retryable_recovery_error; | |
| use crate::client::registry_recovery_retry_delay; | |
| use crate::client_api::DEFAULT_REMOTE_EXEC_SERVER_CONNECT_TIMEOUT; | |
| use crate::client_transport::authenticate_websocket_request; | |
| use crate::client_transport::connect_websocket_request; | |
| use crate::connection::JsonRpcConnection; | |
| use crate::server::ConnectionProcessor; | |
| use crate::telemetry::ConnectionTransport; | |
| use crate::trace_context::current_trace_context_headers; | |
| const DIRECT_TRANSPORT: &str = "direct_jsonrpc_v1"; | |
| struct DirectRegistrationRequest { | |
| transport: &'static str, | |
| } | |
| struct DirectRegistrationResponse { | |
| environment_id: String, | |
| transport: String, | |
| registration_id: String, | |
| url: String, | |
| } | |
| impl EnvironmentRegistryClient { | |
| async fn register_direct_environment( | |
| &self, | |
| environment_id: &str, | |
| ) -> Result<DirectRegistrationResponse, ExecServerError> { | |
| let started_at = Instant::now(); | |
| let response = async { | |
| let url = super::endpoint_url( | |
| &self.base_url, | |
| &format!("/cloud/environment/{environment_id}/direct/register"), | |
| ); | |
| let request = Request::new(Method::POST, url) | |
| .with_json(&DirectRegistrationRequest { | |
| transport: DIRECT_TRANSPORT, | |
| }) | |
| .into_prepared() | |
| .map_err(ExecServerError::EnvironmentRegistryConfig)?; | |
| let request = self | |
| .auth_provider | |
| .apply_auth(request) | |
| .await | |
| .map_err(direct_auth_error)?; | |
| let prepared = request | |
| .prepare_body_for_send() | |
| .map_err(ExecServerError::EnvironmentRegistryConfig)?; | |
| let response = self | |
| .http | |
| .request(request.method, request.url) | |
| .headers(prepared.headers) | |
| .headers(current_trace_context_headers()) | |
| .body(prepared.body.unwrap_or_default()) | |
| .timeout(self.connect_timeout) | |
| .send() | |
| .await?; | |
| let response: DirectRegistrationResponse = self.parse_json_response(response).await?; | |
| if response.environment_id != environment_id { | |
| return Err(ExecServerError::Protocol( | |
| "environment registry returned a different environment id".to_string(), | |
| )); | |
| } | |
| if response.transport != DIRECT_TRANSPORT { | |
| return Err(ExecServerError::Protocol(format!( | |
| "environment registry returned unsupported direct transport `{}`", | |
| response.transport | |
| ))); | |
| } | |
| if response.registration_id.trim().is_empty() || response.url.trim().is_empty() { | |
| return Err(ExecServerError::Protocol( | |
| "environment registry returned incomplete direct connection data".to_string(), | |
| )); | |
| } | |
| require_tls_or_loopback(&response.url, "wss")?; | |
| Ok(response) | |
| } | |
| .await; | |
| let result = if response.is_ok() { "success" } else { "error" }; | |
| tracing::Span::current().record("result", result); | |
| self.telemetry | |
| .remote_registration_completed(result, started_at.elapsed()); | |
| response | |
| } | |
| } | |
| pub(super) async fn run_direct_environment( | |
| config: RemoteEnvironmentConfig, | |
| client: EnvironmentRegistryClient, | |
| processor: ConnectionProcessor, | |
| ) -> Result<(), ExecServerError> { | |
| require_tls_or_loopback(&config.base_url, "https")?; | |
| let mut retry_attempt = 0; | |
| let mut registration = client | |
| .register_direct_environment(&config.environment_id) | |
| .await?; | |
| loop { | |
| match connect_direct( | |
| ®istration.url, | |
| config.auth_provider.as_ref(), | |
| &config.http_client_factory, | |
| ) | |
| .await | |
| { | |
| Ok(websocket) => { | |
| retry_attempt = 0; | |
| info!( | |
| environment_id = registration.environment_id, | |
| registration_id = registration.registration_id, | |
| "direct exec-server connected" | |
| ); | |
| processor | |
| .run_connection( | |
| JsonRpcConnection::from_websocket( | |
| websocket, | |
| format!( | |
| "direct exec-server websocket {}", | |
| websocket_diagnostic_url(®istration.url) | |
| ), | |
| ), | |
| ConnectionTransport::WebSocket, | |
| ) | |
| .await; | |
| config.telemetry.remote_reconnect("disconnected"); | |
| } | |
| Err(error) | |
| if is_retryable_recovery_error(&error) | |
| && !matches!( | |
| &error, | |
| ExecServerError::WebSocketConnect { | |
| source: tokio_tungstenite::tungstenite::Error::Http(response), | |
| .. | |
| } if response.status().is_client_error() | |
| && !matches!( | |
| response.status(), | |
| StatusCode::REQUEST_TIMEOUT | |
| | StatusCode::CONFLICT | |
| | StatusCode::TOO_MANY_REQUESTS | |
| ) | |
| ) => | |
| { | |
| // A handshake conflict rejects this registration; other transient failures | |
| // reconnect using the existing URL. | |
| if matches!( | |
| &error, | |
| ExecServerError::WebSocketConnect { | |
| source: tokio_tungstenite::tungstenite::Error::Http(response), | |
| .. | |
| } if response.status() == StatusCode::CONFLICT | |
| ) { | |
| registration = client | |
| .register_direct_environment(&config.environment_id) | |
| .await?; | |
| } | |
| warn!("direct exec-server connection failed; retrying"); | |
| config.telemetry.remote_reconnect("connect_failed"); | |
| } | |
| Err(error) => return Err(error), | |
| } | |
| sleep(registry_recovery_retry_delay( | |
| &config.environment_id, | |
| retry_attempt, | |
| )) | |
| .await; | |
| retry_attempt = retry_attempt.saturating_add(1); | |
| } | |
| } | |
| async fn connect_direct( | |
| url: &str, | |
| auth_provider: &dyn AuthProvider, | |
| http_client_factory: &codex_http_client::HttpClientFactory, | |
| ) -> Result<WebSocketConnection, ExecServerError> { | |
| let mut request = | |
| url.into_client_request() | |
| .map_err(|source| ExecServerError::WebSocketConnect { | |
| url: websocket_diagnostic_url(url), | |
| source, | |
| })?; | |
| request | |
| .headers_mut() | |
| .extend(current_trace_context_headers()); | |
| authenticate_websocket_request(&mut request, auth_provider) | |
| .await | |
| .map_err(direct_auth_error)?; | |
| let authenticated_url = request.uri().to_string(); | |
| require_tls_or_loopback(&authenticated_url, "wss")?; | |
| let connector = WebSocketConnector::new(http_client_factory) | |
| .map_err(|error| ExecServerError::WebSocketConfiguration(error.to_string()))? | |
| .with_tcp_nodelay(); | |
| connect_websocket_request( | |
| request, | |
| websocket_diagnostic_url(&authenticated_url), | |
| connector, | |
| DEFAULT_REMOTE_EXEC_SERVER_CONNECT_TIMEOUT, | |
| /*use_loopback_direct*/ false, | |
| ) | |
| .await | |
| } | |
| pub(super) fn require_tls_or_loopback( | |
| url: &str, | |
| secure_scheme: &str, | |
| ) -> Result<(), ExecServerError> { | |
| let parsed = url::Url::parse(url).map_err(|error| { | |
| ExecServerError::EnvironmentRegistryConfig(format!("invalid remote endpoint URL: {error}")) | |
| })?; | |
| if parsed.scheme() == secure_scheme { | |
| return Ok(()); | |
| } | |
| let loopback = match parsed.host() { | |
| Some(url::Host::Domain(host)) => host.eq_ignore_ascii_case("localhost"), | |
| Some(url::Host::Ipv4(host)) => host.is_loopback(), | |
| Some(url::Host::Ipv6(host)) => host.is_loopback(), | |
| None => false, | |
| }; | |
| if loopback | |
| && secure_scheme | |
| .strip_suffix('s') | |
| .is_some_and(|scheme| parsed.scheme() == scheme) | |
| { | |
| return Ok(()); | |
| } | |
| Err(ExecServerError::EnvironmentRegistryConfig(format!( | |
| "remote transport requires {secure_scheme} for non-loopback endpoints" | |
| ))) | |
| } | |
| fn websocket_diagnostic_url(url: &str) -> String { | |
| url.split(['?', '#']).next().unwrap_or(url).to_string() | |
| } | |
| fn direct_auth_error(error: AuthError) -> ExecServerError { | |
| let message = format!("failed to resolve environment registry authentication: {error}"); | |
| match error { | |
| AuthError::Build(_) => ExecServerError::EnvironmentRegistryAuth(message), | |
| AuthError::Transient(_) => ExecServerError::Disconnected(message), | |
| } | |
| } | |
| mod tests; | |