add ws support to proxy

This commit is contained in:
Simon Knott 2024-11-26 15:39:09 +01:00
parent 109d1b6874
commit 1d12889ac1
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
2 changed files with 45 additions and 0 deletions

View file

@ -32,6 +32,7 @@ export class TestProxy {
connectHosts: string[] = []; connectHosts: string[] = [];
requestUrls: string[] = []; requestUrls: string[] = [];
wsUrls: string[] = [];
private readonly _server: ProxyServer; private readonly _server: ProxyServer;
private readonly _sockets = new Set<net.Socket>(); private readonly _sockets = new Set<net.Socket>();
@ -75,6 +76,14 @@ export class TestProxy {
this.connectHosts.push(req.url); this.connectHosts.push(req.url);
req.url = `127.0.0.1:${port}`; 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) { setAuthHandler(handler: (req: IncomingMessage) => boolean) {

View file

@ -33,6 +33,7 @@ export function createProxy(server?: http.Server): ProxyServer {
if (!server) server = http.createServer(); if (!server) server = http.createServer();
server.on('request', onrequest); server.on('request', onrequest);
server.on('connect', onconnect); server.on('connect', onconnect);
server.on('upgrade', onupgrade);
return server; return server;
} }
@ -465,4 +466,39 @@ function requestAuthorization(
}; };
res.writeHead(407, headers); res.writeHead(407, headers);
res.end('Proxy authorization required'); 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);
} }