From f89cba4a2494a755499d234fff73e78583399250 Mon Sep 17 00:00:00 2001 From: Dmitriy Petrov Date: Fri, 8 May 2026 21:02:31 +0300 Subject: [PATCH] =?UTF-8?q?style:=20=D0=BE=D1=82=D1=84=D0=BE=D1=80=D0=BC?= =?UTF-8?q?=D0=B0=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=B4=20=D0=B4=D0=BB=D1=8F=20=D1=83=D0=BB=D1=83=D1=87=D1=88?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=87=D0=B8=D1=82=D0=B0=D0=B5=D0=BC?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/index.js | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/server/index.js b/src/server/index.js index 5690839..d1a83b7 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -35,10 +35,13 @@ const trafficSubscribers = new Set(); // outbound/direct[tag]: dial tcp connection to host:port from ip:port // [router] matched rule #0 [rule-name], outbound: vpn, domain: example.com // [TCP] DIRECT host:port --> direct -const TRAFFIC_OUTBOUND_RE = /outbound[/\\]([a-z0-9_\-]+)|\boutbound:\s*([a-z0-9_\-]+)/i; -const TRAFFIC_DEST_RE = /(?:to|dial|connection to|DIRECT|REJECT)\s+(?:tcp\s+|udp\s+)?(?:[^\s]*\s+to\s+)?([a-zA-Z0-9._\-]+|\d{1,3}(?:\.\d{1,3}){3}):(\d{1,5})/i; +const TRAFFIC_OUTBOUND_RE = + /outbound[/\\]([a-z0-9_\-]+)|\boutbound:\s*([a-z0-9_\-]+)/i; +const TRAFFIC_DEST_RE = + /(?:to|dial|connection to|DIRECT|REJECT)\s+(?:tcp\s+|udp\s+)?(?:[^\s]*\s+to\s+)?([a-zA-Z0-9._\-]+|\d{1,3}(?:\.\d{1,3}){3}):(\d{1,5})/i; const TRAFFIC_DOMAIN_RE = /\bdomain:\s*([a-zA-Z0-9._\-]+)/i; -const TRAFFIC_RULE_RE = /matched\s+rule\s+#\d+\s*\[([^\]]+)\]|matched\s+\[([^\]]+)\]/i; +const TRAFFIC_RULE_RE = + /matched\s+rule\s+#\d+\s*\[([^\]]+)\]|matched\s+\[([^\]]+)\]/i; function parseTrafficLine(line) { const clean = line.replace(/\x1b\[\d+m/g, "").trim(); @@ -49,8 +52,10 @@ function parseTrafficLine(line) { if (!outboundRaw) return null; let category = "other"; - if (outboundRaw === "direct" || outboundRaw.startsWith("direct")) category = "direct"; - else if (outboundRaw === "block" || outboundRaw === "reject") category = "block"; + if (outboundRaw === "direct" || outboundRaw.startsWith("direct")) + category = "direct"; + else if (outboundRaw === "block" || outboundRaw === "reject") + category = "block"; else if (outboundRaw !== "dns-out" && outboundRaw !== "dns") category = "vpn"; else return null; // пропускаем DNS-аутбаунды @@ -78,7 +83,9 @@ function pushTrafficEntry(entry) { trafficBuffer.push(entry); if (trafficBuffer.length > TRAFFIC_BUFFER_SIZE) trafficBuffer.shift(); for (const sub of trafficSubscribers) { - try { sub(entry); } catch {} + try { + sub(entry); + } catch {} } } @@ -474,8 +481,15 @@ async function handleApi(req, res) { } const sub = (entry) => res.write(`data: ${JSON.stringify(entry)}\n\n`); trafficSubscribers.add(sub); - const keepalive = setInterval(() => { try { res.write(": ping\n\n"); } catch {} }, 15000); - req.on("close", () => { clearInterval(keepalive); trafficSubscribers.delete(sub); }); + const keepalive = setInterval(() => { + try { + res.write(": ping\n\n"); + } catch {} + }, 15000); + req.on("close", () => { + clearInterval(keepalive); + trafficSubscribers.delete(sub); + }); return; }