UNPKG

hfs

Version:
116 lines (115 loc) 5.11 kB
"use strict"; // This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt 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 connections_1 = require("./connections"); const misc_1 = require("./misc"); const throttler_1 = require("./throttler"); const auth_1 = require("./auth"); const SendList_1 = require("./SendList"); const persistence_1 = require("./persistence"); exports.default = { async disconnect({ ip, port, allButLocalhost }) { const match = allButLocalhost ? ((x) => !(0, misc_1.isLocalHost)(x.ip)) : lodash_1.default.matches({ ip, port }); const found = (0, connections_1.getConnections)().filter(c => match(getConnAddress(c))); for (const c of found) (0, connections_1.disconnect)(c.socket, "manual disconnection"); return { result: found.length }; }, get_connections({}, ctx) { const list = new SendList_1.SendListReadable({ diff: true, addAtStart: (0, connections_1.getConnections)().map(c => !ignore(c) && serializeConnection(c)).filter(Boolean), }); list.props({ you: ctx.ip }); return list.events(ctx, { connection(conn) { if (ignore(conn)) return; list.add(serializeConnection(conn)); }, connectionClosed(conn) { if (ignore(conn)) return; list.remove(getConnAddress(conn)); }, connectionUpdated(conn, change) { if (conn.socket.closed || ignore(conn) || ignore(change) || lodash_1.default.isEmpty(change)) return; if (change.ctx) { Object.assign(change, fromCtx(change.ctx)); change.ctx = undefined; } list.update(getConnAddress(conn), change); }, }); function serializeConnection(conn) { var _a; const { socket, started, secure } = conn; return { ...getConnAddress(conn), v: (((_a = socket.remoteFamily) === null || _a === void 0 ? void 0 : _a.endsWith('6')) ? 6 : 4), got: socket.bytesRead, sent: socket.bytesWritten, country: conn.country, started, secure: (secure || undefined), // undefined will save some space once json-ed ...fromCtx(conn.ctx), }; } function fromCtx(ctx) { if (!ctx) return; const s = ctx.state; // short alias return { user: (0, auth_1.getCurrentUsername)(ctx), agent: (0, misc_1.shortenAgent)(ctx.get('user-agent')), archive: s.archive, ...s.browsing ? { op: 'browsing', path: decodeURIComponent(s.browsing) } : s.uploadPath ? { op: 'upload', path: decodeURIComponent(s.uploadPath) } : { op: !s.considerAsGui && (ctx.state.archive || ctx.state.vfsNode) ? 'download' : undefined, path: (0, misc_1.try_)(() => decodeURIComponent(ctx.originalUrl), () => ctx.originalUrl), }, opProgress: lodash_1.default.isNumber(s.opProgress) ? lodash_1.default.round(s.opProgress, 3) : undefined, opTotal: s.opTotal, opOffset: s.opOffset, }; } }, async *get_connection_stats() { while (1) { const filtered = (0, connections_1.getConnections)().filter(x => !ignore(x)); yield { outSpeed: throttler_1.totalOutSpeed, inSpeed: throttler_1.totalInSpeed, sent_got: [throttler_1.totalSent.get(), throttler_1.totalGot.get(), totalGotSentResetTime.get()], connections: filtered.length, ips: lodash_1.default.uniqBy(filtered, x => x.ip).length, }; await (0, misc_1.wait)(1000); } }, async clear_persistent({ k }) { (0, misc_1.apiAssertTypes)({ string_array: { k } }); totalGotSentResetTime.set(new Date); for (const x of (0, misc_1.wantArray)(k)) void persistence_1.storedMap.del(x); }, }; function ignore(conn) { return false; //conn.socket && isLocalHost(conn) } function getConnAddress(conn) { return { ip: conn.ip, port: conn.socket.remotePort, }; } const totalGotSentResetTime = persistence_1.storedMap.singleSync('totalGotSentResetTime', new Date(0)); totalGotSentResetTime.ready().then(() => // because default value is not stored, and we need to init this value totalGotSentResetTime.set(was => was.getTime() ? was : new Date));