Commit Graph
8 Commits
Author SHA1 Message Date
acrognale-oai 888e02db34 Enforce network policy throughout HTTP and WebSocket requests (#47389)
## Why

Destination restrictions and policy revocation must remain effective during redirects, response body reads, and established WebSocket traffic. Policy denials must also survive error handling so callers do not retry them or report a revoked operation as successful.

## What changed

- Route managed HTTP clients through a shared `RequestBuilder` and policy-aware execution, checking each redirect destination before route resolution and retaining a network permit while consuming response bodies.
- Guard WebSocket connection setup, reads, and writes with revocable permits, including independent wakeups for split readers and writers.
- Preserve `TransportError::Policy` through HTTP, SSE, and realtime error handling, and treat policy denials as non-retryable.
- Keep the supplied network policy in plugin startup HTTP requests and propagate response body failures from backend and plugin requests.

## Testing

Add regression coverage for rejection before connecting, revocation during redirect routing and streamed body reads, split WebSocket revocation, realtime writer error propagation, and revoked plugin upload responses.

GitOrigin-RevId: fba36700444c98a8364c09b4dc5452c4d78a90fb
2026-09-22 23:37:39 +00:00
Celia Chen 142360dac8 Honor configured proxies for realtime WebSocket connections (#47101)
## Why

Realtime WebSockets connected directly, bypassing the configured proxy policy for Voice's WebRTC sideband.

## What changed

Pass the configured `HttpClientFactory` into `RealtimeWebsocketClient` and connect through the shared `WebSocketConnector`. Add support for supplying an existing Rustls configuration to preserve custom CA handling and Windows platform trust.

## Testing

Add an integration test that enables `respect_system_proxy`, starts a WebRTC conversation, and verifies that the sideband establishes its session through an HTTP `CONNECT` proxy and closes successfully.

GitOrigin-RevId: d974c9275d7fe29f388d56a9d5d8ce0c483eb8d0
2026-09-21 20:05:21 +00:00
jif 12acac2a66 Share ChatGPT cookies between HTTP and WebSocket transports (#46506)
## Why

WebSocket handshakes did not reuse the HTTP cookie store or retain response cookies, so routing cookies such as `__oailb` were unavailable to subsequent connections.

## What changed

- Reuse the HTTP factory's ChatGPT cookies for secure WebSocket handshakes, preserving explicit `Cookie` headers and marking generated headers sensitive.
- Retain allowlisted infrastructure cookies from both successful and rejected upgrades. Keep configured cookies scoped to their factory and exclude account and session cookies from the shared store.
- Apply HTTPS cookie scope to `wss` requests, preserving host and path restrictions and excluding insecure `ws` requests and non-ChatGPT hosts.

## Testing

Add HTTP/WebSocket cookie-sharing coverage and local TLS handshake tests for routing-cookie reuse across connectors, rejected-upgrade refreshes, explicit header precedence, cookie scope, session-cookie exclusion, and deletion.

GitOrigin-RevId: 6bd6afe16e97cf9758ca7ba207a4e88c969497a4
2026-09-18 23:17:17 +00:00
ostepanian 801ca0d0d1 Support trusted headers for remote exec WebSockets (#42606)
## What changed

- Add `RemoteEnvironmentOptions` and `upsert_environment_with_options` so embedding hosts can attach trusted HTTP headers to remote exec-server WebSocket handshakes.
- Preserve the headers across session reconnects while redacting them from debug output.
- Reject invalid, duplicate, and WebSocket-controlled headers, and require `wss://` for non-loopback destinations.
- Connect header-bearing loopback WebSockets directly, with DNS results restricted to loopback addresses.

## Testing

- Cover header validation and redaction, delivery on initial connections and reconnects, and loopback destination enforcement.

GitOrigin-RevId: f2e2b0456c8e33c13fd8ab4ee040a8b5c15e885d
2026-09-03 20:01:07 +00:00
jif 9bf673718a Box the WebSocket dial future (#39726)
## What changed

Box `dialer::connect` before awaiting it in `WebSocketConnector::connect`,
erasing the dialer's concrete future type at the connector boundary.

GitOrigin-RevId: 617a2e4fd5bd61a408281973452e7b71b104bff2
2026-08-20 14:55:08 +00:00
Celia Chen 94ebae725e Route exec-server WebSockets through configured proxies (#35056)
## Why

Remote environment connections need to honor Codex's effective outbound proxy policy, including when a rendezvous connection reconnects.

## What changed

- Pass the configured `HttpClientFactory` into remote environment transports and use `WebSocketConnector` for exec-server and rendezvous WebSockets.
- Resolve proxy routes asynchronously so these connections can use the configured system proxy.
- Add connector options that preserve Tungstenite's default TLS behavior and enable `TCP_NODELAY` for latency-sensitive rendezvous traffic.

## Testing

- Verify prepared remote environments connect through a configured system proxy.
- Verify initial and reconnected encrypted relay peers use the system proxy.
- Cover default TLS selection and opt-in `TCP_NODELAY` behavior in the WebSocket client.

GitOrigin-RevId: 8a8da2116e37cb3a891269d0c0b037986fecdd3c
2026-07-24 00:16:42 +00:00
Michael Bolin c9ef7eff00 Resolve outbound proxy routes explicitly (#34435)
## Why

System proxy discovery can block, and delegating fallback to each transport can repeat discovery or apply inconsistent environment proxy behavior.

## What changed

- Resolve unavailable system proxy decisions to an explicit environment proxy or direct route, including `NO_PROXY` settings and WebSocket-specific fallbacks.
- Add asynchronous system proxy resolution that uses cached decisions first and serializes blocking platform lookups on Windows and macOS.
- Preserve `NO_PROXY` handling for WebSocket connections, including HTTP and HTTPS proxies, and hash proxy cache keys on every platform.

## Testing

- Add coverage for explicit environment fallback, cached asynchronous resolution, and proxied or bypassed WebSocket connections.

GitOrigin-RevId: 3b7cf170dcfe639eec53c3c1514f92bfcf13e7e9
2026-07-21 00:33:04 +00:00
Michael Bolin 2780bd588f websocket-client: add proxy-aware connector (#31622)
## Why

The route-aware WebSocket connection setup in #31441 is transport
infrastructure rather than Responses API protocol logic. Landing it
first in a dedicated crate keeps `codex-api` focused on request and
response behavior and makes the transport reusable by future WebSocket
clients.

WebSockets must also apply the same effective outbound proxy and
custom-CA policy as HTTP without disabling the lower-latency WebSocket
path. Requiring an `HttpClientFactory` when constructing the connector
makes proxy-policy resolution part of the API instead of an optional
call-site convention.

This PR is an independent prerequisite based directly on `main`. After
it merges, #31441 can rebase onto it and replace its in-crate connector
with this API.

## What changed

- Add a new `codex-websocket-client` workspace crate with a
`WebSocketConnector` constructed from the effective `HttpClientFactory`.
- Resolve every destination through that factory before connecting, then
support direct connections, transport-default routing, HTTP proxies, and
TLS-encrypted HTTPS proxies.
- Preserve custom-CA trust for proxy and target TLS handshakes and
preserve Happy Eyeballs fallback for explicit direct and proxy routes.
- Expose an established `WebSocketConnection` as a uniform `Stream` and
`Sink`, hiding route-specific transport types from protocol clients.
- Add focused integration-style coverage for the public connector and
message stream, real WSS over direct and CONNECT routes, implicit and
explicit HTTPS proxy ports, and stalled-address-family fallback.

## Review guide

1. `codex-rs/websocket-client/src/lib.rs` defines the small public API
and the factory-required policy invariant.
2. `codex-rs/websocket-client/src/dialer.rs` contains DNS, TCP, proxy
tunneling, TLS, and WebSocket handshake setup.
3. `codex-rs/websocket-client/src/dialer_tests.rs` verifies the public
stream, direct and proxied WSS paths, HTTPS port preservation, and Happy
Eyeballs timing.
4. There is intentionally no consumer migration here; #31441 will become
the first consumer after this prerequisite merges.

## Test plan

- `cargo check -p codex-websocket-client --tests`
- `just test -p codex-websocket-client`
- `cargo shear`
- `just bazel-lock-check`
2026-07-08 12:57:27 -07:00