Repository navigation
Answer 502 when an upstream sends an invalid status code - #660
Merged
Merged
Conversation
An upstream response head that writeHead rejects (for example "HTTP/1.1 099 x") made writeHead throw inside the response callback. The exception was uncaught and ended the proxy process. Relay the upstream response head through one guarded helper, relayResponseHead, at all four relay sites: the direct, parent-proxy and MITM-socket paths in http-proxy.ts, and the TLS-terminated path in tls-terminate-proxy.ts. If writeHead throws (an invalid status, or a header name or value it refuses), the upstream response is destroyed and not piped. The client gets 502 Bad Gateway if nothing was sent yet, with any partly set headers cleared, or its response is destroyed if headers already went out. The proxy keeps serving. The new test calls the helper directly with invalid heads, and sends status 099 and 000 end to end through the direct and TLS-terminated paths.
ant-kurt
force-pushed
the
fix/invalid-upstream-status
branch
from
October 6, 2026 23:20
5527e48 to
da70dc2
Compare
ant-kurt
enabled auto-merge
October 6, 2026 23:21
shawnm-anthropic
approved these changes
Oct 6, 2026
Merged
ronleizrowice-ant
added a commit
that referenced
this pull request
Oct 7, 2026
New to the bundle: #655, #660 and the version. #643, #639 and #630 come as squashes of what it held; in the one block git marks, the workflow's, it keeps its own side, which has the checksummed bun as well. Two cases of #655 compare two wrapped commands. Here a wrap that names mount points names a manifest of its own (#584), so the cases take that name out before they compare.
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.
What was wrong
When an upstream answered with a response head that Node's
res.writeHeadrefuses (for exampleHTTP/1.1 099 x), the proxy's response callback threwRangeError [ERR_HTTP_INVALID_STATUS_CODE]. Nothing caught it, so the process running the proxy exited. Every connection through it was dropped, and the sandboxed command lost network access. Any upstream the sandbox is allowed to reach could trigger this. The defect is in the latest release, 0.0.78.Fix
A new helper,
relayResponseHead(res, upstreamRes)insrc/sandbox/parent-proxy.ts, writes the upstream status and headers inside atry. All four relay sites now use it: the MITM-socket, parent-proxy and direct paths inhttp-proxy.ts, and the TLS-terminated path intls-terminate-proxy.ts. IfwriteHeadthrows:502 Bad Gateway;Valid responses are relayed exactly as before. There is no API or configuration change. Opaque CONNECT tunnels are not affected.
Tests
test/sandbox/invalid-upstream-response.test.tshas two groups.The
relayResponseHeadcases call the helper inside a realnode:httpserver with a stub upstream, so they exercise thewriteHeadfailure directly. Bun'swriteHeadthrows on these heads just as Node's does. Status99and1000, a control character in a header value, and an invalid header name each give the client a 502 with no upstream header, including one accepted before the rejected one. The upstream is destroyed and the helper returns false. If a head was already sent, the client response is cut off instead. A valid head is relayed. With thetry/catchremoved, the five failure cases fail.The end-to-end cases send status
099and000through the plain HTTP (direct) and TLS-terminated paths. Each checks that the client gets 502 with no upstream header or body bytes, and that a following normal request through the same proxy succeeds. Under Bun, whichbun testuses, the HTTP client itself rejects these status lines, so these requests take the existing request-error path and never reachwriteHead. They pin the 502 outcome and that the proxy keeps serving. The parent-proxy and MITM-socket paths have no end-to-end case. Under Node, the direct and parent-proxy paths were checked by hand: before this change the proxy crashes withInvalid status code: 99. After it, the client getsHTTP/1.1 502 Bad Gateway.bun test test/sandbox/invalid-upstream-response.test.tsGenerated by Claude Code