Add Bun, Deno, and Node weather adapter examples#3
Conversation
commit: |
| }, | ||
| }); | ||
| egressTunnel?.[Symbol.dispose](); | ||
| egressTunnel = tunnel; |
There was a problem hiding this comment.
Deno tunnel assignment races with incoming requests
Low Severity
The egressTunnel variable is assigned inside the asynchronous "open" event listener, creating a window where an incoming /weather request could arrive before the tunnel is set. Unlike the Bun adapter (which sets egressTunnel synchronously and uses an internal promise to await the connection) and the Node adapter (which sets egressTunnel synchronously in the handleUpgrade callback), the Deno example defers assignment. If a request arrives before "open" fires, egressFetch falls through to the real fetch, bypassing the tunnel entirely.
Reviewed by Cursor Bugbot for commit 52b3fdf. Configure here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5a87409. Configure here.
| diff |= left[i] ^ right[i]; | ||
| } | ||
| return diff === 0; | ||
| } |
There was a problem hiding this comment.
Native constant-time comparison replaced with JS implementation
Medium Severity
The native crypto.subtle.timingSafeEqual (a Cloudflare Workers API providing hardware-backed constant-time comparison) was replaced with a custom JavaScript loop to fix a typecheck conflict. JavaScript provides no constant-time execution guarantees — V8's JIT may optimize the XOR/OR loop in data-dependent ways, making the comparison potentially vulnerable to timing side-channel attacks on the CAPTUN_SECRET authorization check. The type already exists in worker-configuration.d.ts; a type assertion or scoped tsconfig would preserve both type safety and the native constant-time guarantee.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 5a87409. Configure here.


Summary
Adds runtime-specific server adapter entry points so Captun can accept egress tunnel WebSocket connections outside Cloudflare Workers:
captun/bunexposescreateCaptunBunTunnelHandler()forBun.serve({ fetch, websocket }).captun/nodeexposesacceptCaptunNodeTunnel(socket)for Node HTTP upgrade handlers backed byws; the example uses@whatwg-node/serverfor normal HTTP Fetch handling.captun/denoexposesacceptCaptunDenoTunnel(socket)forDeno.upgradeWebSocket(request).The examples are intentionally repetitive: each runtime folder has a self-contained weather server plus its own Vitest test helper, so a reviewer can open one folder and see the complete runtime shape without following a shared app module or fixture module.
This is now aligned with PR #12's consolidated public API:
captunstays as the root client/Cloudflare entry point, runtime adapters live undercaptun/bun,captun/deno, andcaptun/node, and there is no separate publictypes.tssurface or boilerplate tunnel-handle interface export.Example Shapes
Bun
Node
Deno
Cloudflare
Verification
pnpm run checkpnpm run buildpnpm testpnpm pack --pack-destination /tmp/captun-pack-ignoremenpx --yes --package @arethetypeswrong/cli@0.18.2 --package fflate@0.8.2 attw /tmp/captun-pack-ignoreme/captun-0.0.1.tgz --profile esm-only