/** * codex F3 critical test: real Chromium navigates through the SOCKS5 bridge. * * The other bridge tests prove TCP relay works at the byte level. This test * proves the FEATURE works: a Chromium browser launched with * proxy.server = 'socks5://127.0.0.1:' actually traverses the * bridge → authenticated upstream → destination chain. Without this test, * we could ship a working transport layer and a broken integration with * Chromium and not know it. */ import { describe, test, expect, beforeAll, afterAll } from 'bun:test'; import { chromium, type Browser } from 'playwright'; import * as net from 'net'; import * as http from 'http'; import { startSocksBridge, type BridgeHandle } from '../src/socks-bridge'; interface MockUpstream { port: number; close: () => Promise; totalConnects: () => number; } /** * Minimal SOCKS5 upstream with username/password auth. Tracks how many * CONNECT requests succeeded — non-zero proves the browser's request * actually traversed the chain. */ async function startAuthUpstream(user: string, pass: string): Promise { let connects = 0; const server = net.createServer((sock) => { sock.once('data', (greeting) => { if (greeting[0] !== 0x05) { sock.destroy(); return; } const methods = greeting.subarray(2, 2 + greeting[1]); if (!methods.includes(0x02)) { sock.write(Buffer.from([0x05, 0xFF])); sock.destroy(); return; } sock.write(Buffer.from([0x05, 0x02])); sock.once('data', (auth) => { const ulen = auth[1]; const uname = auth.subarray(2, 2 + ulen).toString(); const plen = auth[2 + ulen]; const passwd = auth.subarray(3 + ulen, 3 + ulen + plen).toString(); if (uname !== user || passwd !== pass) { sock.write(Buffer.from([0x01, 0x01])); sock.destroy(); return; } sock.write(Buffer.from([0x01, 0x00])); sock.once('data', (req) => { const atyp = req[3]; let host: string; let port: number; if (atyp === 0x01) { host = `${req[4]}.${req[5]}.${req[6]}.${req[7]}`; port = req.readUInt16BE(8); } else if (atyp === 0x03) { const len = req[4]; host = req.subarray(5, 5 + len).toString(); port = req.readUInt16BE(5 + len); } else { sock.write(Buffer.from([0x05, 0x08, 0x00, 0x01, 0, 0, 0, 0, 0, 0])); sock.destroy(); return; } const dest = net.createConnection({ host, port }, () => { connects++; sock.write(Buffer.from([0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0])); sock.pipe(dest); dest.pipe(sock); sock.on('error', () => dest.destroy()); dest.on('error', () => sock.destroy()); sock.on('close', () => dest.destroy()); dest.on('close', () => sock.destroy()); }); dest.on('error', () => { try { sock.write(Buffer.from([0x05, 0x04, 0x00, 0x01, 0, 0, 0, 0, 0, 0])); } catch {} sock.destroy(); }); }); }); }); sock.on('error', () => sock.destroy()); }); await new Promise((resolve, reject) => { server.once('error', reject); server.once('listening', () => resolve()); server.listen(0, '127.0.0.1'); }); const addr = server.address(); if (!addr || typeof addr === 'string') throw new Error('mock upstream: bad address'); return { port: addr.port, totalConnects: () => connects, close: () => new Promise((r) => server.close(() => r())), }; } /** Tiny HTTP server to serve as the navigation target. */ async function startHttpFixture(body: string): Promise<{ port: number; close: () => Promise; hits: () => number }> { let hits = 0; const server = http.createServer((_req, res) => { hits++; res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(body); }); await new Promise((resolve, reject) => { server.once('error', reject); server.listen(0, '127.0.0.1', () => resolve()); }); const addr = server.address(); if (!addr || typeof addr === 'string') throw new Error('http fixture: bad address'); return { port: addr.port, hits: () => hits, close: () => new Promise((r) => server.close(() => r())), }; } describe('bridge-chromium-e2e (codex F3)', () => { let upstream: MockUpstream; let bridge: BridgeHandle; let httpFixture: { port: number; close: () => Promise; hits: () => number }; let browser: Browser; beforeAll(async () => { upstream = await startAuthUpstream('alice', 'wonderland'); bridge = await startSocksBridge({ upstream: { host: '127.0.0.1', port: upstream.port, userId: 'alice', password: 'wonderland' }, }); httpFixture = await startHttpFixture('

via-bridge

'); browser = await chromium.launch({ headless: true, proxy: { server: `socks5://127.0.0.1:${bridge.port}` }, }); }); afterAll(async () => { await browser.close(); await httpFixture.close(); await bridge.close(); await upstream.close(); }); test('Chromium navigates through bridge → auth upstream → HTTP fixture', async () => { const page = await browser.newPage(); try { const before = upstream.totalConnects(); const fixtureHitsBefore = httpFixture.hits(); // Use 127.0.0.1 explicitly so we hit our local HTTP server (not via DNS). const target = `http://127.0.0.1:${httpFixture.port}/`; const response = await page.goto(target); expect(response?.ok()).toBe(true); const text = await page.locator('#ok').textContent(); expect(text).toBe('via-bridge'); // Proof of traversal: the upstream's connect counter incremented AND // the HTTP fixture got a hit. expect(upstream.totalConnects()).toBeGreaterThan(before); expect(httpFixture.hits()).toBeGreaterThan(fixtureHitsBefore); } finally { await page.close(); } }); test('subsequent navigation also traverses the bridge', async () => { const page = await browser.newPage(); try { const before = upstream.totalConnects(); const target = `http://127.0.0.1:${httpFixture.port}/page2`; await page.goto(target); expect(upstream.totalConnects()).toBeGreaterThan(before); } finally { await page.close(); } }); }); describe('bridge-port-restart (codex F1, reframed)', () => { test('two sequential bridge instances pick different ephemeral ports', async () => { // codex F1: the original bridge-port-isolation test assumed two browse // daemons coexist, which contradicts our single-daemon refuse-on-mismatch // model (D2). The valid restart test is: spin up bridge A, close it, // spin up bridge B, assert B picks a fresh ephemeral port (and that a // hardcoded port like 1090 never appears in either). const upstream = await startAuthUpstream('u', 'p'); try { const a = await startSocksBridge({ upstream: { host: '127.0.0.1', port: upstream.port, userId: 'u', password: 'p' }, }); expect(a.port).not.toBe(1090); const portA = a.port; await a.close(); const b = await startSocksBridge({ upstream: { host: '127.0.0.1', port: upstream.port, userId: 'u', password: 'p' }, }); expect(b.port).not.toBe(1090); // The same port can be reused safely because the listener is closed. // But more importantly, both ports are valid ephemeral ports and the // bridge chose them via listen(0), not a hardcoded constant. expect(b.port).toBeGreaterThan(0); expect(typeof portA).toBe('number'); await b.close(); } finally { await upstream.close(); } }); });