@vladmandic/piproxy
Version:
Reverse HTTP/HTTPS/HTTP2 Proxy in NodeJS with SSL Certificate Management, Compression, Security Enforcement and Rate Limiting
59 lines (53 loc) • 2.44 kB
text/typescript
import * as net from 'net';
import * as log from '@vladmandic/pilogger';
import * as config from './config';
const timeout = 250;
type SocketStatus = {
lookup: boolean,
connect: boolean,
error: string,
ready: boolean,
data: boolean,
}
async function checkSocket(server): Promise<{ timestamp: Date, server: string, url: SocketStatus, target: SocketStatus }> {
return new Promise((resolve) => {
const srcStatus: SocketStatus = { lookup: false, connect: false, error: '', ready: false, data: false };
const src = net.connect(config.get().http2.port, server.url);
src.on('lookup', () => { srcStatus.lookup = true; });
src.on('connect', () => { srcStatus.connect = true; });
src.on('error', (error) => { srcStatus.error = error.message || JSON.stringify(error, null, 2); });
src.on('ready', () => { srcStatus.ready = true; });
const tgtStatus: SocketStatus = { lookup: false, connect: false, error: '', ready: false, data: false };
const tgt = net.connect(server.port, server.target);
tgt.on('lookup', () => { tgtStatus.lookup = true; });
tgt.on('connect', () => { tgtStatus.connect = true; });
tgt.on('data', (data) => { tgtStatus.data = data.toString().startsWith('HTTP'); });
tgt.on('error', (error) => { tgtStatus.error = error.message || JSON.stringify(error, null, 2); });
tgt.on('ready', () => {
tgtStatus.ready = true;
// const head = `HEAD /favicon.ico HTTP/1.1\r\nHost: ${server.target}\r\nUser-Agent: proxy\r\nAccept: */*\r\nConnection: close\r\n\r\n`;
// tgt.write(head);
tgt.end();
});
setTimeout(() => {
tgt.destroy();
src.destroy();
resolve({ timestamp: new Date(), server, url: srcStatus, target: tgtStatus });
}, timeout);
});
}
export async function check() {
const out: Array<{ timestamp: Date, server: string, url: SocketStatus, target: SocketStatus }> = [];
if (!config.get().redirects || (config.get().redirects.length <= 0)) log.warn('monitor', { targets: 0 });
for (const server of config.get().redirects) {
const res = await checkSocket(server);
out.push(res);
if (!res.url.error && !res.target.error) log.state('monitor', { server, url: res.url, target: res.target });
else log.warn('monitor', { server, url: res.url, target: res.target });
}
return out;
}
export async function start() {
check();
if (config.get().monitor) setInterval(check, 5 * 60 * 60 * 1000);
}