proxyTo(upstream: string): Promise<Proxy>
A WebSocket the DevTools frontend is allowed to open, piped to the one Chrome will accept.
Chrome answers 403 to a debugger connection carrying an Origin header — which a browser
always sends — unless it was started with --remote-allow-origins. The value that flag would
need is the port Chrome chose for itself, which is not known until after it has started, so the
only spelling available at launch is *: every origin, including any page that happens to be
open in your own browser. That is precisely the hole the check exists to close.
Node sends no Origin. So the frontend connects here, and this connects onward from Node, and
Chrome's protection is left exactly as it was. Nothing is listening until somebody asks for
DevTools, and it listens on the loopback interface only.
The whole file is that one problem. It serves nothing, knows nothing about /repl or about this
REPL, and would do the same job for any frontend a browser has to open on any CDP target.
proxyTo, not connect: it does not open a connection, it LISTENS for one. What comes back is
an address for somebody else to dial, and the socket onward to Chrome is not made until they do.
A connect() returning a port to connect to would have the direction backwards.
import { proxyTo } from './proxy.ts'; // Defined, not invoked: it binds a port and talks to a real browser. async function example() { const proxy = await proxyTo('ws://127.0.0.1:9222/devtools/page/ABC'); return proxy.address; // 'localhost:41234' — what a frontend's `ws=` should say }
Promise<Proxy>