import * as plugins from './smartproxy.plugins.js'; import * as net from 'net'; let netServer: plugins.net.Server; let httpServer: plugins.http.Server; export class PortProxy { fromPort: number; toPort: number; constructor(fromPortArg: number, toPortArg: number) { this.fromPort = fromPortArg; this.toPort = toPortArg } public async start () { httpServer = plugins.http.createServer((request, response) => { const requestUrl = new URL(request.url, `http://${request.headers.host}`); const completeUrlWithoutProtocol = `${requestUrl.host}${requestUrl.pathname}${requestUrl.search}`; const redirectUrl = `https://${completeUrlWithoutProtocol}`; console.log(`Got http request for http://${completeUrlWithoutProtocol}`); console.log(`Redirecting to ${redirectUrl}`); response.writeHead(302, { Location: redirectUrl, }); response.end(); }); httpServer.listen(this.fromPort); const cleanUpSockets = (from: plugins.net.Socket, to: plugins.net.Socket) => { from.end(); to.end(); from.removeAllListeners(); to.removeAllListeners(); from.unpipe(); to.unpipe(); from.destroy(); to.destroy(); } netServer = net .createServer((from) => { const to = net.createConnection({ host: 'localhost', port: this.toPort, }); from.setTimeout(120000); from.pipe(to); to.pipe(from); from.on('error', () => { cleanUpSockets(from, to); }); to.on('error', () => { cleanUpSockets(from, to); }); from.on('close', () => { cleanUpSockets(from, to); }); to.on('close', () => { cleanUpSockets(from, to); }); from.on('timeout', () => { cleanUpSockets(from, to); }); to.on('timeout', () => { cleanUpSockets(from, to); }); from.on('end', () => { cleanUpSockets(from, to); }) to.on('end', () => { cleanUpSockets(from, to); }) }) .listen(this.fromPort); console.log(`PortProxy -> OK: Now listening on port ${this.fromPort}`); } public async stop() { const done = plugins.smartpromise.defer(); httpServer.close(() => { netServer.close(() => { done.resolve(); }); }); await done.promise; } };