@fanboynz/network-scanner 2.0.16 → 2.0.18
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/lib/browserhealth.js +27 -4
- package/lib/fingerprint.js +12 -0
- package/lib/nettools.js +15 -6
- package/lib/redirect.js +24 -1
- package/nwss.js +4 -4
- package/package.json +1 -1
package/lib/browserhealth.js
CHANGED
|
@@ -9,9 +9,9 @@ const { formatLogMessage, messageColors } = require('./colorize');
|
|
|
9
9
|
// Window cleanup delay constant
|
|
10
10
|
const WINDOW_CLEANUP_DELAY_MS = 15000;
|
|
11
11
|
// window_clean REALTIME
|
|
12
|
-
const REALTIME_CLEANUP_BUFFER_MS =
|
|
13
|
-
const REALTIME_CLEANUP_THRESHOLD =
|
|
14
|
-
const REALTIME_CLEANUP_MIN_PAGES =
|
|
12
|
+
const REALTIME_CLEANUP_BUFFER_MS = 25000; // Additional buffer time after site delay (increased for Cloudflare)
|
|
13
|
+
const REALTIME_CLEANUP_THRESHOLD = 12; // Default number of pages to keep
|
|
14
|
+
const REALTIME_CLEANUP_MIN_PAGES = 6; // Minimum pages before cleanup kicks in
|
|
15
15
|
|
|
16
16
|
// Track page creation order for realtime cleanup
|
|
17
17
|
const pageCreationTracker = new Map(); // Maps page -> creation timestamp
|
|
@@ -19,7 +19,7 @@ let pageCreationCounter = 0;
|
|
|
19
19
|
|
|
20
20
|
// Track page usage for realtime cleanup safety
|
|
21
21
|
const pageUsageTracker = new Map(); // Maps page -> { lastActivity: timestamp, isProcessing: boolean }
|
|
22
|
-
const PAGE_IDLE_THRESHOLD =
|
|
22
|
+
const PAGE_IDLE_THRESHOLD = 25000; // 25 seconds of inactivity before considering page safe to clean
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Performs group-level window cleanup after all URLs in a site group complete
|
|
@@ -299,6 +299,29 @@ async function performRealtimeWindowCleanup(browserInstance, threshold = REALTIM
|
|
|
299
299
|
|
|
300
300
|
const allPagesAfterDelay = await browserInstance.pages();
|
|
301
301
|
|
|
302
|
+
// Also check for and close any popup contexts
|
|
303
|
+
try {
|
|
304
|
+
const contexts = await browserInstance.browserContexts();
|
|
305
|
+
for (const context of contexts) {
|
|
306
|
+
if (context.isIncognito && context !== browserInstance.defaultBrowserContext()) {
|
|
307
|
+
const contextPages = await context.pages();
|
|
308
|
+
if (forceDebug) {
|
|
309
|
+
console.log(formatLogMessage('debug', `[realtime_cleanup] Found ${contextPages.length} pages in popup context`));
|
|
310
|
+
}
|
|
311
|
+
// Close popup context pages
|
|
312
|
+
for (const page of contextPages) {
|
|
313
|
+
if (!page.isClosed()) {
|
|
314
|
+
await page.close();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
} catch (contextErr) {
|
|
320
|
+
if (forceDebug) {
|
|
321
|
+
console.log(formatLogMessage('debug', `[realtime_cleanup] Context cleanup error: ${contextErr.message}`));
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
302
325
|
// Find main Puppeteer page (usually about:blank)
|
|
303
326
|
let mainPage = allPagesAfterDelay.find(page => {
|
|
304
327
|
const url = page.url();
|
package/lib/fingerprint.js
CHANGED
|
@@ -1333,6 +1333,18 @@ async function applyFingerprintProtection(page, siteConfig, forceDebug, currentU
|
|
|
1333
1333
|
*/
|
|
1334
1334
|
async function simulateHumanBehavior(page, forceDebug) {
|
|
1335
1335
|
try {
|
|
1336
|
+
// Validate page state before injection
|
|
1337
|
+
if (!page || page.isClosed()) {
|
|
1338
|
+
if (forceDebug) console.log(`[debug] Human behavior simulation skipped - page closed`);
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
// Check if browser is still connected
|
|
1343
|
+
if (!page.browser().isConnected()) {
|
|
1344
|
+
if (forceDebug) console.log(`[debug] Human behavior simulation skipped - browser disconnected`);
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1336
1348
|
await page.evaluateOnNewDocument((debugEnabled) => {
|
|
1337
1349
|
|
|
1338
1350
|
try {
|
package/lib/nettools.js
CHANGED
|
@@ -418,15 +418,17 @@ async function whoisLookupWithRetry(domain, timeout = 10000, whoisServer = null,
|
|
|
418
418
|
|
|
419
419
|
// Add delay between retry attempts to prevent rate limiting
|
|
420
420
|
if (attemptCount > 1) {
|
|
421
|
-
if (
|
|
422
|
-
if (
|
|
423
|
-
logFunc
|
|
424
|
-
|
|
425
|
-
|
|
421
|
+
if (whoisDelay > 0) {
|
|
422
|
+
if (debugMode) {
|
|
423
|
+
if (logFunc) {
|
|
424
|
+
logFunc(`${messageColors.highlight('[whois-retry]')} Adding ${whoisDelay}ms delay before retry attempt...`);
|
|
425
|
+
} else {
|
|
426
|
+
console.log(formatLogMessage('debug', `${messageColors.highlight('[whois-retry]')} Adding ${whoisDelay}ms delay before retry attempt...`));
|
|
427
|
+
}
|
|
426
428
|
}
|
|
429
|
+
await new Promise(resolve => setTimeout(resolve, whoisDelay));
|
|
427
430
|
}
|
|
428
431
|
|
|
429
|
-
await new Promise(resolve => setTimeout(resolve, whoisDelay));
|
|
430
432
|
} else if (whoisDelay > 0) {
|
|
431
433
|
// Add initial delay on first attempt if configured
|
|
432
434
|
if (debugMode) {
|
|
@@ -437,6 +439,13 @@ async function whoisLookupWithRetry(domain, timeout = 10000, whoisServer = null,
|
|
|
437
439
|
}
|
|
438
440
|
}
|
|
439
441
|
await new Promise(resolve => setTimeout(resolve, whoisDelay));
|
|
442
|
+
} else if (debugMode) {
|
|
443
|
+
// Log when delay is skipped due to whoisDelay being 0
|
|
444
|
+
if (logFunc) {
|
|
445
|
+
logFunc(`${messageColors.highlight('[whois-retry]')} Skipping delay (whoisDelay: ${whoisDelay}ms)`);
|
|
446
|
+
} else {
|
|
447
|
+
console.log(formatLogMessage('debug', `${messageColors.highlight('[whois-retry]')} Skipping delay (whoisDelay: ${whoisDelay}ms)`));
|
|
448
|
+
}
|
|
440
449
|
}
|
|
441
450
|
|
|
442
451
|
try {
|
package/lib/redirect.js
CHANGED
|
@@ -45,6 +45,22 @@ async function navigateWithRedirectHandling(page, currentUrl, siteConfig, gotoOp
|
|
|
45
45
|
// Monitor JavaScript redirects by intercepting location changes
|
|
46
46
|
const jsRedirectDetector = async () => {
|
|
47
47
|
try {
|
|
48
|
+
// Validate page state before injection
|
|
49
|
+
if (!page || page.isClosed()) {
|
|
50
|
+
if (forceDebug) {
|
|
51
|
+
console.log(formatLogMessage('debug', 'JS redirect detector skipped - page closed'));
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Check if browser is still connected
|
|
57
|
+
if (!page.browser().isConnected()) {
|
|
58
|
+
if (forceDebug) {
|
|
59
|
+
console.log(formatLogMessage('debug', 'JS redirect detector skipped - browser disconnected'));
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
48
64
|
await page.evaluateOnNewDocument(() => {
|
|
49
65
|
// Store original location methods
|
|
50
66
|
const originalReplace = window.location.replace;
|
|
@@ -121,7 +137,14 @@ async function navigateWithRedirectHandling(page, currentUrl, siteConfig, gotoOp
|
|
|
121
137
|
}
|
|
122
138
|
});
|
|
123
139
|
} catch (jsErr) {
|
|
124
|
-
if (
|
|
140
|
+
if (jsErr.message.includes('Session closed') ||
|
|
141
|
+
jsErr.message.includes('Target closed') ||
|
|
142
|
+
jsErr.message.includes('Protocol error')) {
|
|
143
|
+
if (forceDebug) {
|
|
144
|
+
console.log(formatLogMessage('debug', 'JS redirect detector skipped - session ended'));
|
|
145
|
+
}
|
|
146
|
+
return;
|
|
147
|
+
} else if (forceDebug) {
|
|
125
148
|
console.log(formatLogMessage('debug', `Failed to inject JS redirect detector: ${jsErr.message}`));
|
|
126
149
|
}
|
|
127
150
|
}
|
package/nwss.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// === Network scanner script (nwss.js) v2.0.
|
|
1
|
+
// === Network scanner script (nwss.js) v2.0.18 ===
|
|
2
2
|
|
|
3
3
|
// puppeteer for browser automation, fs for file system operations, psl for domain parsing.
|
|
4
4
|
// const pLimit = require('p-limit'); // Will be dynamically imported
|
|
@@ -130,7 +130,7 @@ const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/r
|
|
|
130
130
|
const { monitorBrowserHealth, isBrowserHealthy, isQuicklyResponsive, performGroupWindowCleanup, performRealtimeWindowCleanup, trackPageForRealtime, updatePageUsage, cleanupPageBeforeReload } = require('./lib/browserhealth');
|
|
131
131
|
|
|
132
132
|
// --- Script Configuration & Constants ---
|
|
133
|
-
const VERSION = '2.0.
|
|
133
|
+
const VERSION = '2.0.18'; // Script version
|
|
134
134
|
|
|
135
135
|
// get startTime
|
|
136
136
|
const startTime = Date.now();
|
|
@@ -2555,7 +2555,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2555
2555
|
const netToolsHandler = createNetToolsHandler({
|
|
2556
2556
|
whoisTerms,
|
|
2557
2557
|
whoisOrTerms,
|
|
2558
|
-
whoisDelay: siteConfig.whois_delay
|
|
2558
|
+
whoisDelay: siteConfig.whois_delay !== undefined ? siteConfig.whois_delay : whois_delay,
|
|
2559
2559
|
whoisServer,
|
|
2560
2560
|
whoisServerMode: siteConfig.whois_server_mode || whois_server_mode,
|
|
2561
2561
|
debugLogFile,
|
|
@@ -2662,7 +2662,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2662
2662
|
const netToolsHandler = createNetToolsHandler({
|
|
2663
2663
|
whoisTerms,
|
|
2664
2664
|
whoisOrTerms,
|
|
2665
|
-
whoisDelay: siteConfig.whois_delay
|
|
2665
|
+
whoisDelay: siteConfig.whois_delay !== undefined ? siteConfig.whois_delay : whois_delay, // Site-specific or global fallback
|
|
2666
2666
|
whoisServer, // Pass whois server configuration
|
|
2667
2667
|
whoisServerMode: siteConfig.whois_server_mode || whois_server_mode,
|
|
2668
2668
|
debugLogFile, // Pass debug log file for whois error logging
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fanboynz/network-scanner",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.18",
|
|
4
4
|
"description": "A Puppeteer-based network scanner for analyzing web traffic, generating adblock filter rules, and identifying third-party requests. Features include fingerprint spoofing, Cloudflare bypass, content analysis with curl/grep, and multiple output formats.",
|
|
5
5
|
"main": "nwss.js",
|
|
6
6
|
"scripts": {
|