fix: disable permessage-deflate in the app-server protocol probe - #112
Open
Ghost-LZW wants to merge 1 commit into
Open
fix: disable permessage-deflate in the app-server protocol probe#112Ghost-LZW wants to merge 1 commit into
Ghost-LZW wants to merge 1 commit into
Conversation
probeWebSocket() constructed its ws client with the library default, so the handshake offered 'Sec-WebSocket-Extensions: permessage-deflate'. The stock codex app-server uses tokio-tungstenite, which supports no extension and aborts the upgrade without writing an HTTP response rather than replying 101 with the extension omitted. The client then waited out its own 5s timeout, so both the direct probe and the 'codex app-server proxy' fallback returned state 'unknown' and 'codexhost remote start' failed with 'Remote Host protocol probe timed out'. createRemoteOfficialAppServerConnection() already documented this exact constraint; hoist its options into APP_SERVER_WEBSOCKET_CLIENT_OPTIONS so every client that talks to an app-server listener shares one handshake.
|
To use Codex here, create an environment for this repo. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
codexhost remote startalways fails on a host where a stock codex app-server isalready listening:
codexhost remote statusreports the same and exits 1, even though theinstallation is
"state": "ready", "issues": []and the app-server is listeningand responding normally.
Root cause
probeWebSocket()inremote-host-lifecycle.tsconstructed itswsclient withthe library default:
wsenables permessage-deflate by default, so the handshake offersSec-WebSocket-Extensions: permessage-deflate; client_max_window_bits. The stockcodex app-server uses tokio-tungstenite, which supports no extension and aborts
the upgrade without writing an HTTP response at all, rather than replying 101
with the extension omitted. The client waits out its own 5s timeout, so both the
direct probe and the
codex app-server proxyfallback returnstate: "unknown",and
startRemoteHost()aborts before it can terminate the stock listener and takeover.
createRemoteOfficialAppServerConnection()already documented this exactconstraint and passed
perMessageDeflate: false—probeWebSocket()just missedthe flag.
Change
APP_SERVER_WEBSOCKET_CLIENT_OPTIONS(maxPayload+perMessageDeflate: false)as the single handshake used by every client that talks to an app-server listener.
probeWebSocket()(the fix) and increateRemoteOfficialAppServerConnection()(replacing its local literal), so a third call site can't reintroduce this.
any upgrade offering an extension, and asserts the probe still classifies it as
stock-codex.Validation
Reproduced against a live stock codex app-server listener (
codex-cli0.152.0,@codexhost/cli0.4.0, Node v24.14.0, Linux x86_64). Raw handshakes against thesocket, varying only the extensions header:
Sec-WebSocket-ExtensionsHTTP/1.1 101 Switching Protocolspermessage-deflate; client_max_window_bitsSame A/B through a real
wsclient against that listener:The
deflate=falseresponse is exactly the shapeclassifyRemoteHostProbeResponse()expects for thestock-codexconflict branch,so once the handshake succeeds the classifier works as designed. Patching the
shipped runtime in place turned the reported
"state": "unknown"into:which is the state
startRemoteHost()needs in order to replace the stock listener.Checks run on this branch:
npm run lint— passnpm run typecheck— passnpm run build:typescript— passnpm run format:check(on changed files) — passpackages/host-runtimetests — 28 files, 277 passed / 2 skippedunknown) and passes with it.Full
npm run test:typescripthas 6 failures intools/dev-desktop/run.test.mjsandpackages/adapters/claude-code/test/command.test.ts;I confirmed these are pre-existing on a clean
mainand unrelated to this change.npm run test:rustwas not run.The new test is skipped on Windows, which has no unix-socket listener path here.