68 lines
1.6 KiB
JavaScript
68 lines
1.6 KiB
JavaScript
'use strict';
|
|
|
|
const http = require('http');
|
|
const { settings, validate } = require('./src/settings');
|
|
const {
|
|
probeCycle,
|
|
startProbing,
|
|
stopProbing,
|
|
} = require('./src/upstream-pool');
|
|
const { handleProxy } = require('./src/proxy');
|
|
const { healthPayload } = require('./src/health');
|
|
const { sendText, sendJson } = require('./src/http-utils');
|
|
|
|
const HEALTH_PATHS = new Set(['/health', '/healthz']);
|
|
|
|
const server = http.createServer((req, res) => {
|
|
let reqUrl;
|
|
try {
|
|
const rawUrl = req.url.replace(/^\/+/, '/');
|
|
reqUrl = new URL(rawUrl, 'http://proxy.invalid');
|
|
} catch {
|
|
sendText(res, 400, 'Bad request');
|
|
return;
|
|
}
|
|
|
|
if (req.method === 'GET' && HEALTH_PATHS.has(reqUrl.pathname)) {
|
|
sendJson(res, 200, healthPayload());
|
|
return;
|
|
}
|
|
|
|
handleProxy(req, res, reqUrl);
|
|
});
|
|
|
|
function shutdown(signal) {
|
|
console.log(`Received ${signal}, shutting down`);
|
|
stopProbing();
|
|
server.close(() => process.exit(0));
|
|
setTimeout(() => process.exit(0), 5000).unref();
|
|
}
|
|
|
|
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
|
|
async function main() {
|
|
try {
|
|
validate();
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
process.exit(1);
|
|
}
|
|
|
|
await probeCycle();
|
|
|
|
server.listen(settings.listenPort, () => {
|
|
console.log(`Xtream proxy listening on :${settings.listenPort}`);
|
|
console.log(`Config file: ${settings.configFile}`);
|
|
console.log(
|
|
`Probe interval: ${settings.probeIntervalSec}s, probe timeout: ${settings.probeTimeoutMs}ms`
|
|
);
|
|
startProbing();
|
|
});
|
|
}
|
|
|
|
main().catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
});
|