From 1d12889ac19fe2444739a937114d16933f8d3edd Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Tue, 26 Nov 2024 15:39:09 +0100 Subject: [PATCH] add ws support to proxy --- tests/config/proxy.ts | 9 ++++++++ tests/third_party/proxy/index.ts | 36 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/tests/config/proxy.ts b/tests/config/proxy.ts index 79d6390cfb..b8cc73e567 100644 --- a/tests/config/proxy.ts +++ b/tests/config/proxy.ts @@ -32,6 +32,7 @@ export class TestProxy { connectHosts: string[] = []; requestUrls: string[] = []; + wsUrls: string[] = []; private readonly _server: ProxyServer; private readonly _sockets = new Set(); @@ -75,6 +76,14 @@ export class TestProxy { this.connectHosts.push(req.url); req.url = `127.0.0.1:${port}`; }); + this._prependHandler('upgrade', (req: IncomingMessage) => { + this.wsUrls.push(req.url); + const url = new URL(req.url, `http://${req.headers.host}`); + url.port = '' + port; + if (options.prefix) + url.pathname = url.pathname.replace(options.prefix, ''); + req.url = url.toString(); + }); } setAuthHandler(handler: (req: IncomingMessage) => boolean) { diff --git a/tests/third_party/proxy/index.ts b/tests/third_party/proxy/index.ts index 32f3d73437..f7841da8a6 100644 --- a/tests/third_party/proxy/index.ts +++ b/tests/third_party/proxy/index.ts @@ -33,6 +33,7 @@ export function createProxy(server?: http.Server): ProxyServer { if (!server) server = http.createServer(); server.on('request', onrequest); server.on('connect', onconnect); + server.on('upgrade', onupgrade); return server; } @@ -465,4 +466,39 @@ function requestAuthorization( }; res.writeHead(407, headers); res.end('Proxy authorization required'); +} + +function createHttpHeader(line: string, headers: http.IncomingHttpHeaders) { + return Object.keys(headers).reduce(function (head, key) { + var value = headers[key]; + + if (!Array.isArray(value)) { + head.push(key + ': ' + value); + return head; + } + + for (var i = 0; i < value.length; i++) { + head.push(key + ': ' + value[i]); + } + return head; + }, [line]) + .join('\r\n') + '\r\n\r\n'; +} + +function onupgrade(req: http.IncomingMessage, socket: net.Socket, head: Buffer) { + const parsed = url.parse(req.url || '/'); + const proxyReq = http.request({ + ...parsed, + method: req.method, + headers: req.headers, + localAddress: this.localAddress, + }); + + proxyReq.on('upgrade', function (proxyRes, proxySocket, proxyHead) { + socket.write(createHttpHeader('HTTP/1.1 101 Switching Protocols', proxyRes.headers)); + if (proxyHead && proxyHead.length) proxySocket.unshift(proxyHead); + proxySocket.pipe(socket).pipe(proxySocket); + }); + + proxyReq.end(head); } \ No newline at end of file