Download codex-rs/exec-server/src/server/transport.rs from SaylorTwift/codex: direct link, hf CLI and curl.
- Browser
- Download file 7.26 kB
-
https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/exec-server/src/server/transport.rs
- Command line
-
hf download hf://SaylorTwift/codex/codex-rs/exec-server/src/server/transport.rs
-
curl -L -o transport.rs https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/exec-server/src/server/transport.rs
7.26 kB
| use axum::Router; | |
| use axum::body::Body; | |
| use axum::extract::ConnectInfo; | |
| use axum::extract::State; | |
| use axum::extract::ws::WebSocketUpgrade; | |
| use axum::http::Request; | |
| use axum::http::StatusCode; | |
| use axum::http::header::ORIGIN; | |
| use axum::middleware; | |
| use axum::middleware::Next; | |
| use axum::response::IntoResponse; | |
| use axum::response::Response; | |
| use axum::routing::any; | |
| use axum::routing::get; | |
| use codex_http_client::HttpClientFactory; | |
| use std::io::Write as _; | |
| use std::net::SocketAddr; | |
| use tokio::io; | |
| use tokio::io::AsyncRead; | |
| use tokio::io::AsyncWrite; | |
| use tokio::net::TcpListener; | |
| use tracing::info; | |
| use tracing::warn; | |
| use crate::ExecServerRuntimePaths; | |
| use crate::ExecServerTelemetry; | |
| use crate::connection::JsonRpcConnection; | |
| use crate::server::RequestDispatchMode; | |
| use crate::server::processor::ConnectionProcessor; | |
| use crate::telemetry::ConnectionTransport; | |
| pub const DEFAULT_LISTEN_URL: &str = "ws://127.0.0.1:0"; | |
| pub(crate) enum ExecServerListenTransport { | |
| WebSocket(SocketAddr), | |
| Stdio, | |
| } | |
| pub enum ExecServerListenUrlParseError { | |
| UnsupportedListenUrl(String), | |
| InvalidWebSocketListenUrl(String), | |
| } | |
| impl std::fmt::Display for ExecServerListenUrlParseError { | |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
| match self { | |
| ExecServerListenUrlParseError::UnsupportedListenUrl(listen_url) => write!( | |
| f, | |
| "unsupported --listen URL `{listen_url}`; expected `ws://IP:PORT` or `stdio`" | |
| ), | |
| ExecServerListenUrlParseError::InvalidWebSocketListenUrl(listen_url) => write!( | |
| f, | |
| "invalid websocket --listen URL `{listen_url}`; expected `ws://IP:PORT`" | |
| ), | |
| } | |
| } | |
| } | |
| impl std::error::Error for ExecServerListenUrlParseError {} | |
| pub(crate) fn parse_listen_url( | |
| listen_url: &str, | |
| ) -> Result<ExecServerListenTransport, ExecServerListenUrlParseError> { | |
| if matches!(listen_url, "stdio" | "stdio://") { | |
| return Ok(ExecServerListenTransport::Stdio); | |
| } | |
| if let Some(socket_addr) = listen_url.strip_prefix("ws://") { | |
| return socket_addr | |
| .parse::<SocketAddr>() | |
| .map(ExecServerListenTransport::WebSocket) | |
| .map_err(|_| { | |
| ExecServerListenUrlParseError::InvalidWebSocketListenUrl(listen_url.to_string()) | |
| }); | |
| } | |
| Err(ExecServerListenUrlParseError::UnsupportedListenUrl( | |
| listen_url.to_string(), | |
| )) | |
| } | |
| pub(crate) async fn run_transport( | |
| listen_url: &str, | |
| runtime_paths: ExecServerRuntimePaths, | |
| telemetry: ExecServerTelemetry, | |
| http_client_factory: HttpClientFactory, | |
| request_dispatch_mode: RequestDispatchMode, | |
| ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | |
| match parse_listen_url(listen_url)? { | |
| ExecServerListenTransport::WebSocket(bind_address) => { | |
| run_websocket_listener( | |
| bind_address, | |
| runtime_paths, | |
| telemetry, | |
| http_client_factory, | |
| request_dispatch_mode, | |
| ) | |
| .await | |
| } | |
| ExecServerListenTransport::Stdio => { | |
| run_stdio_connection( | |
| runtime_paths, | |
| telemetry, | |
| http_client_factory, | |
| request_dispatch_mode, | |
| ) | |
| .await | |
| } | |
| } | |
| } | |
| async fn run_stdio_connection( | |
| runtime_paths: ExecServerRuntimePaths, | |
| telemetry: ExecServerTelemetry, | |
| http_client_factory: HttpClientFactory, | |
| request_dispatch_mode: RequestDispatchMode, | |
| ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | |
| run_stdio_connection_with_io( | |
| io::stdin(), | |
| io::stdout(), | |
| runtime_paths, | |
| telemetry, | |
| http_client_factory, | |
| request_dispatch_mode, | |
| ) | |
| .await | |
| } | |
| async fn run_stdio_connection_with_io<R, W>( | |
| reader: R, | |
| writer: W, | |
| runtime_paths: ExecServerRuntimePaths, | |
| telemetry: ExecServerTelemetry, | |
| http_client_factory: HttpClientFactory, | |
| request_dispatch_mode: RequestDispatchMode, | |
| ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> | |
| where | |
| R: AsyncRead + Unpin + Send + 'static, | |
| W: AsyncWrite + Unpin + Send + 'static, | |
| { | |
| let processor = ConnectionProcessor::new_with_telemetry( | |
| runtime_paths, | |
| telemetry, | |
| http_client_factory, | |
| request_dispatch_mode, | |
| ); | |
| tracing::info!("codex-exec-server listening on stdio"); | |
| processor | |
| .run_connection( | |
| JsonRpcConnection::from_stdio(reader, writer, "exec-server stdio".to_string()), | |
| ConnectionTransport::Stdio, | |
| ) | |
| .await; | |
| // Stdio serves exactly one connection, so detached sessions cannot be resumed. | |
| processor.shutdown().await; | |
| Ok(()) | |
| } | |
| async fn run_websocket_listener( | |
| bind_address: SocketAddr, | |
| runtime_paths: ExecServerRuntimePaths, | |
| telemetry: ExecServerTelemetry, | |
| http_client_factory: HttpClientFactory, | |
| request_dispatch_mode: RequestDispatchMode, | |
| ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | |
| let listener = TcpListener::bind(bind_address).await?; | |
| let local_addr = listener.local_addr()?; | |
| let processor = ConnectionProcessor::new_with_telemetry( | |
| runtime_paths, | |
| telemetry, | |
| http_client_factory, | |
| request_dispatch_mode, | |
| ); | |
| info!("codex-exec-server listening on ws://{local_addr}"); | |
| println!("ws://{local_addr}"); | |
| std::io::stdout().flush()?; | |
| let router = Router::new() | |
| .route("/", any(websocket_upgrade_handler)) | |
| .route("/readyz", get(readiness_handler)) | |
| .layer(middleware::from_fn(reject_requests_with_origin_header)) | |
| .with_state(ExecServerWebSocketState { processor }); | |
| axum::serve( | |
| listener, | |
| router.into_make_service_with_connect_info::<SocketAddr>(), | |
| ) | |
| .await?; | |
| Ok(()) | |
| } | |
| struct ExecServerWebSocketState { | |
| processor: ConnectionProcessor, | |
| } | |
| async fn readiness_handler() -> StatusCode { | |
| StatusCode::OK | |
| } | |
| async fn reject_requests_with_origin_header( | |
| request: Request<Body>, | |
| next: Next, | |
| ) -> Result<Response, StatusCode> { | |
| if request.headers().contains_key(ORIGIN) { | |
| warn!( | |
| method = %request.method(), | |
| uri = %request.uri(), | |
| "rejecting exec-server websocket listener request with Origin header" | |
| ); | |
| Err(StatusCode::FORBIDDEN) | |
| } else { | |
| Ok(next.run(request).await) | |
| } | |
| } | |
| async fn websocket_upgrade_handler( | |
| websocket: WebSocketUpgrade, | |
| ConnectInfo(peer_addr): ConnectInfo<SocketAddr>, | |
| State(state): State<ExecServerWebSocketState>, | |
| ) -> impl IntoResponse { | |
| info!(%peer_addr, "exec-server websocket client connected"); | |
| websocket.on_upgrade(move |stream| async move { | |
| state | |
| .processor | |
| .run_connection( | |
| JsonRpcConnection::from_axum_websocket( | |
| stream, | |
| format!("exec-server websocket {peer_addr}"), | |
| ), | |
| ConnectionTransport::WebSocket, | |
| ) | |
| .await; | |
| }) | |
| } | |
| mod transport_tests; | |