Skip to content

bunjs supports#649

Open
tocha688 wants to merge 5 commits into
apify:masterfrom
tocha688:master
Open

bunjs supports#649
tocha688 wants to merge 5 commits into
apify:masterfrom
tocha688:master

Conversation

@tocha688

Copy link
Copy Markdown

bunjs supports

Copilot AI and others added 5 commits April 22, 2026 05:04
… fallback in server.ts

Agent-Logs-Url: https://github.com/tocha688/proxy-chain/sessions/5e6f77bd-e7c9-4264-bdbb-7cee28af680f

Co-authored-by: tocha688 <154045226+tocha688@users.noreply.github.com>
fix: ERR_TUNNEL_CONNECTION_FAILED — Bun.js + Node.js CONNECT tunnel compatibility
jancurn pushed a commit that referenced this pull request May 19, 2026
…as-request in server

Inspired by #649. Two changes that let proxy-chain itself run under Bun
when used as a library, independent of what the test harness can prove:

1. `src/chain.ts` no longer goes through `http.request().on('connect')`
   to reach the upstream proxy. Bun 1.3 implements http.request on top of
   fetch and (a) rejects RFC 7230 authority-form paths like `:443` with
   "fetch() URL is invalid", (b) swallows the 407/590-class upstream
   responses. We now open a raw `net` or `tls` socket, send the CONNECT
   line ourselves, parse the response header buffer, and hand the
   remaining bytes back via `socket.unshift`. `rawHeaders` is preserved
   on the synthetic IncomingMessage so `tunnelConnectResponded`
   subscribers (the anonymizeProxy listener test) keep working.

2. `Server.onRequest` falls back to `onConnect` when `request.method ===
   'CONNECT'`. Bun delivers CONNECT through the generic 'request' event
   for some client shapes; Node ignores this branch because it always
   uses the dedicated 'connect' event.
jancurn pushed a commit that referenced this pull request Jun 12, 2026
Three changes that make proxy-chain work as a library under Bun 1.3,
inspired by the approach in #649:

1. `chain.ts` no longer tunnels through `http.request().on('connect')`.
   Bun implements `http.request` on top of `fetch()`, which (a) rejects
   RFC 7230 authority-form CONNECT paths like `:443` with "fetch() URL
   is invalid" and (b) swallows 407/590-class upstream responses.
   Instead we open a raw `net`/`tls` socket, write the CONNECT request
   ourselves, parse the response headers, and `unshift` any remaining
   bytes back as tunnel payload. The synthetic response object keeps
   `rawHeaders` so `tunnelConnectResponded`/`tunnelConnectFailed`
   subscribers see the same shape as before. TLS options configured on
   `httpsAgent` (custom `ca`, client certs) are honored by re-using the
   agent's stored constructor options for the direct connection.

2. `Server.onRequest` routes `CONNECT` requests to `onConnect`: Bun
   delivers CONNECT through the generic 'request' event for some client
   shapes instead of the dedicated 'connect' event.

3. `Server.getConnectionStats` returns `undefined` under Bun. Bun does
   not populate `socket.bytesRead`/`bytesWritten` on http sockets, so
   the stats would silently read as zero — better no stats than wrong
   stats. (`connectionClosed` events consequently carry
   `stats: undefined` on Bun.)

Node behavior is unchanged: full e2e suite produces an identical
pass/fail set to master baseline (2012 passing, same 174 pre-existing
environment failures) on Node 22.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants