arn-browser 0.1.22 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -30,10 +30,14 @@ export interface GeoDetails {
|
|
|
30
30
|
export interface TrafficStats {
|
|
31
31
|
/** Number of requests handled */
|
|
32
32
|
req: number;
|
|
33
|
-
/** Data sent to client (
|
|
34
|
-
|
|
35
|
-
/** Data received from client (
|
|
36
|
-
|
|
33
|
+
/** Data sent to client (source Tx, formatted string) */
|
|
34
|
+
sTx: string;
|
|
35
|
+
/** Data received from client (source Rx, formatted string) */
|
|
36
|
+
sRx: string;
|
|
37
|
+
/** Data sent to upstream proxy (target Tx, formatted string). Only present when showTg is true. */
|
|
38
|
+
tTx?: string;
|
|
39
|
+
/** Data received from upstream proxy (target Rx, formatted string). Only present when showTg is true. */
|
|
40
|
+
tRx?: string;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
/**
|
|
@@ -69,6 +73,8 @@ export interface ProxyServerOptions {
|
|
|
69
73
|
proxy_stats?: boolean;
|
|
70
74
|
/** Track hostname usage statistics (default: true) */
|
|
71
75
|
host_stats?: boolean;
|
|
76
|
+
/** Show target bytes (tTx/tRx) in stats output (default: false) */
|
|
77
|
+
tg_stats?: boolean;
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
/**
|
|
@@ -10,8 +10,8 @@ import { SocksProxyAgent } from "socks-proxy-agent";
|
|
|
10
10
|
// SECTION 1: NETWORK HELPERS
|
|
11
11
|
// ==========================================
|
|
12
12
|
|
|
13
|
-
function nativeGet(url, agent = null, timeout = 5000) {
|
|
14
|
-
|
|
13
|
+
async function nativeGet(url, agent = null, timeout = 5000, retries = 5) {
|
|
14
|
+
const attempt = () => new Promise((resolve, reject) => {
|
|
15
15
|
const urlObj = new URL(url);
|
|
16
16
|
const requestModule = urlObj.protocol === "https:" ? https : http;
|
|
17
17
|
|
|
@@ -40,6 +40,15 @@ function nativeGet(url, agent = null, timeout = 5000) {
|
|
|
40
40
|
reject(new Error("Request Timed Out"));
|
|
41
41
|
});
|
|
42
42
|
});
|
|
43
|
+
|
|
44
|
+
for (let i = 1; i <= retries; i++) {
|
|
45
|
+
try {
|
|
46
|
+
return await attempt();
|
|
47
|
+
} catch (err) {
|
|
48
|
+
if (i === retries) throw err;
|
|
49
|
+
await sleep(1000);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
const isPortAvailable = (port) => {
|
|
@@ -190,6 +199,7 @@ export async function startProxyServer({
|
|
|
190
199
|
debug = false,
|
|
191
200
|
proxy_stats = true,
|
|
192
201
|
host_stats = true,
|
|
202
|
+
tg_stats = false,
|
|
193
203
|
}) {
|
|
194
204
|
// 1. Matchers
|
|
195
205
|
const matchers = {
|
|
@@ -360,16 +370,21 @@ export async function startProxyServer({
|
|
|
360
370
|
return (bytes / (1024 * 1024)).toFixed(3) + " MB";
|
|
361
371
|
};
|
|
362
372
|
|
|
373
|
+
|
|
374
|
+
|
|
363
375
|
const getProxyStatsFormatted = () => {
|
|
364
376
|
const formatted = {};
|
|
365
377
|
for (const [key, val] of Object.entries(stats)) {
|
|
366
|
-
|
|
378
|
+
const entry = {
|
|
367
379
|
req: val.request,
|
|
368
380
|
sTx: formatBytes(val.srcTx),
|
|
369
381
|
sRx: formatBytes(val.srcRx),
|
|
370
|
-
tTx: formatBytes(val.trgTx),
|
|
371
|
-
tRx: formatBytes(val.trgRx),
|
|
372
382
|
};
|
|
383
|
+
if (tg_stats) {
|
|
384
|
+
entry.tTx = formatBytes(val.trgTx);
|
|
385
|
+
entry.tRx = formatBytes(val.trgRx);
|
|
386
|
+
}
|
|
387
|
+
formatted[key] = entry;
|
|
373
388
|
}
|
|
374
389
|
return formatted;
|
|
375
390
|
};
|
|
@@ -380,13 +395,16 @@ export async function startProxyServer({
|
|
|
380
395
|
const sortedHosts = Object.entries(hosts)
|
|
381
396
|
.sort((a, b) => b[1].req - a[1].req)
|
|
382
397
|
.reduce((acc, [host, hostData]) => {
|
|
383
|
-
|
|
398
|
+
const entry = {
|
|
384
399
|
req: hostData.req,
|
|
385
400
|
sTx: formatBytes(hostData.srcTx),
|
|
386
401
|
sRx: formatBytes(hostData.srcRx),
|
|
387
|
-
tTx: formatBytes(hostData.trgTx),
|
|
388
|
-
tRx: formatBytes(hostData.trgRx),
|
|
389
402
|
};
|
|
403
|
+
if (tg_stats) {
|
|
404
|
+
entry.tTx = formatBytes(hostData.trgTx);
|
|
405
|
+
entry.tRx = formatBytes(hostData.trgRx);
|
|
406
|
+
}
|
|
407
|
+
acc[host] = entry;
|
|
390
408
|
return acc;
|
|
391
409
|
}, {});
|
|
392
410
|
|
|
@@ -425,11 +443,11 @@ export async function startProxyServer({
|
|
|
425
443
|
await server.close(true);
|
|
426
444
|
serverRunning = false;
|
|
427
445
|
|
|
428
|
-
// Wait up to
|
|
446
|
+
// Wait up to 5000ms (5 seconds) for all async 'connectionClosed' events to fire
|
|
429
447
|
// When sockets are destroyed, their 'close' events happen asynchronously
|
|
430
|
-
let maxWait =
|
|
448
|
+
let maxWait = 250; // 250 * 20ms = 5000ms
|
|
431
449
|
while (Object.keys(connectionMap).length > 0 && maxWait > 0) {
|
|
432
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
450
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
433
451
|
maxWait--;
|
|
434
452
|
}
|
|
435
453
|
|