UNPKG

hfs

Version:
94 lines (93 loc) 4.05 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_1 = __importDefault(require("lodash")); const consoleLog_1 = require("./consoleLog"); const cross_1 = require("./cross"); const misc_1 = require("./misc"); const events_1 = __importDefault(require("./events")); const log_1 = require("./log"); const promises_1 = require("fs/promises"); const SendList_1 = require("./SendList"); const serveFile_1 = require("./serveFile"); const ips_1 = require("./ips"); const connections_1 = require("./connections"); exports.default = { async get_log_info() { const current = Object.fromEntries(await Promise.all(log_1.loggers.map(async (x) => [x.name, await (0, promises_1.stat)(x.path).then(s => s.size, () => 0)]))); return { current, rotated: await (0, log_1.getRotatedFiles)() }; }, async get_log_file({ file = 'log', range = '' }, ctx) { const log = lodash_1.default.find(log_1.loggers, { name: file }); if (!log) throw cross_1.HTTP_NOT_FOUND; if (!log.path) throw cross_1.HTTP_NOT_ACCEPTABLE; (0, serveFile_1.forceDownload)(ctx, log.path); if (range) ctx.request.header.range = `bytes=${range}`; if (ctx.method === 'POST') // this would cause method_not_allowed ctx.method = 'GET'; await (0, serveFile_1.serveFile)(ctx, log.path); return null; }, get_log({ file = 'log' }, ctx) { const files = file.split('|'); // potentially more then one return new SendList_1.SendListReadable({ bufferTime: 10, async doAtStart(list) { if (file === 'disconnections') { for (const x of connections_1.disconnectionsLog) list.add(x); ctx.res.once('close', events_1.default.on('disconnection', x => list.add(x))); return list.ready(); } if (file === 'ips') { for await (const [k, v] of ips_1.ips.iterator()) list.add({ ip: k, ...v }); return list.ready(); } if (file === 'console') { for (const chunk of lodash_1.default.chunk(consoleLog_1.consoleLog, 1000)) { // avoid occupying the thread too long for (const x of chunk) list.add(x); await (0, cross_1.wait)(0); } ctx.res.once('close', events_1.default.on('console', x => list.add(x))); return list.ready(); } // for other logs we only provide updates. Use get_log_file to download past content if (lodash_1.default.some(files, x => !lodash_1.default.find(log_1.loggers, { name: x }))) return list.error(cross_1.HTTP_NOT_FOUND, true); list.ready(); // unsubscribe when connection is interrupted ctx.res.once('close', events_1.default.on(files, x => list.add(Object.assign(lodash_1.default.pick(x.ctx, ['ip', 'method', 'status']), x, { ctx: undefined })))); } }); }, async delete_ips({ ip, ts }) { (0, misc_1.apiAssertTypes)({ string_undefined: { ip, ts } }); if (ip) { if (!ips_1.ips.has(ip)) throw cross_1.HTTP_NOT_FOUND; ips_1.ips.del(ip); return {}; } if (ts) { ts = new Date(ts); let n = 0; for await (const [k, rec] of ips_1.ips.iterator()) if (rec.ts <= ts) { ips_1.ips.del(k); ++n; } return { n }; } throw cross_1.HTTP_BAD_REQUEST; }, reset_ips() { return ips_1.ips.clear(); }, };