[feat]: expose `headers` param on `localBrowser.connect()`
why
port the Python support from #3260 to TypeScript so callers can authenticate against CDP gateways without putting credentials in the URL
what
const browser = await localBrowser.connect({
cdpUrl: "https://gateway/.../cdp",
headers: { "X-Api-Key": "..." },
});
Headers are sent with HTTP discovery and the client’s CDP WebSocket handshake. They only reach endpoints on the same host and effective port, without downgrading TLS, and are never passed to the extension. Unsafe HTTP redirects are rejected; Node’s WebSocket transport already rejects redirects.
Header validation rejects unsafe names, non-ASCII values, and leading or trailing whitespace without exposing credentials in errors. Discovery fails immediately on HTTP 401/403, and optional debug logging explains when headers are withheld. Includes a minor changeset.
test plan
- Network tests cover HTTP discovery and WebSocket header forwarding, allowed HTTP redirects, blocked redirects, and connections with omitted or empty headers.
- Regression tests cover header validation and error redaction, host/port/TLS boundaries, safe diagnostics, immediate 401/403 failures, and retries for transient failures.
- Browser factory tests verify headers stay out of extension initialization metadata.
- All 159 targeted tests, TypeScript type checking, and lint checks pass.
Summary by cubic
Adds a headers option to TypeScript localBrowser.connect(), porting the existing Python support so CDP gateways can be authenticated without putting credentials in the URL.
New Features
- Headers are sent with HTTP discovery and the CDP WebSocket handshake; they only reach endpoints on the same host and effective port, without downgrading transport security.
- Unsafe HTTP and WebSocket redirects are rejected, and gateway responses with HTTP 401/403 fail fast with instructions to check credentials.
- Header validation rejects invalid names, non-ASCII values, and leading/trailing whitespace. The map is snapshotted once before parsing, so throwing getters and proxy traps never leak header content into validation errors.
- Headers are never passed to the extension initialization metadata.