@fanboynz/network-scanner 2.0.34 → 2.0.36
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/browserexit.js +15 -20
- package/nwss.js +105 -64
- package/package.json +1 -1
package/lib/browserexit.js
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
* Provides graceful and forced browser closure functionality with comprehensive temp file cleanup
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const { execSync } = require('child_process');
|
|
9
|
+
|
|
6
10
|
// Constants for temp file cleanup
|
|
7
11
|
const CHROME_TEMP_PATHS = [
|
|
8
12
|
'/tmp',
|
|
@@ -13,8 +17,7 @@ const CHROME_TEMP_PATHS = [
|
|
|
13
17
|
const CHROME_TEMP_PATTERNS = [
|
|
14
18
|
'.com.google.Chrome.*', // Google Chrome temp files
|
|
15
19
|
'.org.chromium.Chromium.*',
|
|
16
|
-
'puppeteer-*'
|
|
17
|
-
'.com.google.Chrome.*' // Ensure Google Chrome pattern is included
|
|
20
|
+
'puppeteer-*'
|
|
18
21
|
];
|
|
19
22
|
|
|
20
23
|
/**
|
|
@@ -33,7 +36,6 @@ async function cleanupChromeTempFiles(options = {}) {
|
|
|
33
36
|
} = options;
|
|
34
37
|
|
|
35
38
|
try {
|
|
36
|
-
const { execSync } = require('child_process');
|
|
37
39
|
|
|
38
40
|
// Base cleanup commands for standard temp directories
|
|
39
41
|
const cleanupCommands = [
|
|
@@ -56,17 +58,17 @@ async function cleanupChromeTempFiles(options = {}) {
|
|
|
56
58
|
|
|
57
59
|
for (const command of cleanupCommands) {
|
|
58
60
|
try {
|
|
59
|
-
//
|
|
60
|
-
const
|
|
61
|
-
|
|
61
|
+
// Extract glob pattern and count matches before deletion
|
|
62
|
+
const globPattern = command.match(/rm -rf ([^ ]+)/)?.[1];
|
|
63
|
+
if (!globPattern) continue;
|
|
64
|
+
const fileCount = parseInt(execSync(`ls -1d ${globPattern} 2>/dev/null | wc -l || echo 0`, { stdio: 'pipe' }).toString().trim()) || 0;
|
|
62
65
|
|
|
63
66
|
if (fileCount > 0) {
|
|
64
67
|
execSync(command, { stdio: 'ignore' });
|
|
65
68
|
totalCleaned += fileCount;
|
|
66
69
|
|
|
67
70
|
if (forceDebug) {
|
|
68
|
-
|
|
69
|
-
console.log(`[debug] [temp-cleanup] Cleaned ${fileCount} items from ${pathPattern}`);
|
|
71
|
+
console.log(`[debug] [temp-cleanup] Cleaned ${fileCount} items from ${globPattern}`);
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
74
|
} catch (cmdErr) {
|
|
@@ -102,7 +104,6 @@ async function comprehensiveChromeTempCleanup(options = {}) {
|
|
|
102
104
|
const { forceDebug = false, verbose = false } = options;
|
|
103
105
|
|
|
104
106
|
try {
|
|
105
|
-
const { execSync } = require('child_process');
|
|
106
107
|
let totalCleaned = 0;
|
|
107
108
|
|
|
108
109
|
if (verbose && !forceDebug) {
|
|
@@ -112,8 +113,7 @@ async function comprehensiveChromeTempCleanup(options = {}) {
|
|
|
112
113
|
for (const basePath of CHROME_TEMP_PATHS) {
|
|
113
114
|
// Check if the base path exists before trying to clean it
|
|
114
115
|
try {
|
|
115
|
-
const pathExists =
|
|
116
|
-
.toString().trim() === 'exists';
|
|
116
|
+
const pathExists = fs.existsSync(basePath);
|
|
117
117
|
|
|
118
118
|
if (!pathExists) {
|
|
119
119
|
if (forceDebug) {
|
|
@@ -149,7 +149,7 @@ async function comprehensiveChromeTempCleanup(options = {}) {
|
|
|
149
149
|
if (verbose && totalCleaned > 0) {
|
|
150
150
|
console.log(`[temp-cleanup] ? Removed ${totalCleaned} temporary file(s)/folder(s)`);
|
|
151
151
|
} else if (verbose && totalCleaned === 0) {
|
|
152
|
-
console.log(`[temp-cleanup]
|
|
152
|
+
console.log(`[temp-cleanup] ? Clean - no remaining temporary files`);
|
|
153
153
|
} else if (forceDebug) {
|
|
154
154
|
console.log(`[debug] [temp-cleanup] Comprehensive cleanup completed (${totalCleaned} items)`);
|
|
155
155
|
}
|
|
@@ -179,7 +179,6 @@ async function cleanupUserDataDir(userDataDir, forceDebug = false) {
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
try {
|
|
182
|
-
const fs = require('fs');
|
|
183
182
|
|
|
184
183
|
if (!fs.existsSync(userDataDir)) {
|
|
185
184
|
if (forceDebug) {
|
|
@@ -281,9 +280,7 @@ async function forceBrowserKill(browser, forceDebug = false) {
|
|
|
281
280
|
const mainPid = browserProcess.pid;
|
|
282
281
|
if (forceDebug) console.log(`[debug] [browser] Main Chrome PID: ${mainPid}`);
|
|
283
282
|
|
|
284
|
-
// Find and kill ALL related Chrome processes
|
|
285
|
-
const { execSync } = require('child_process');
|
|
286
|
-
|
|
283
|
+
// Find and kill ALL related Chrome processes
|
|
287
284
|
|
|
288
285
|
try {
|
|
289
286
|
// Find all Chrome processes with puppeteer in command line
|
|
@@ -390,9 +387,7 @@ async function forceBrowserKill(browser, forceDebug = false) {
|
|
|
390
387
|
* @returns {Promise<void>}
|
|
391
388
|
*/
|
|
392
389
|
async function killAllPuppeteerChrome(forceDebug = false) {
|
|
393
|
-
try {
|
|
394
|
-
const { execSync } = require('child_process');
|
|
395
|
-
|
|
390
|
+
try {
|
|
396
391
|
if (forceDebug) console.log(`[debug] [browser] Nuclear option: killing all puppeteer Chrome processes...`);
|
|
397
392
|
|
|
398
393
|
try {
|
|
@@ -439,7 +434,7 @@ async function handleBrowserExit(browser, options = {}) {
|
|
|
439
434
|
|
|
440
435
|
const results = {
|
|
441
436
|
browserClosed: false,
|
|
442
|
-
|
|
437
|
+
tempFilesCleanedCount: 0,
|
|
443
438
|
userDataCleaned: false,
|
|
444
439
|
success: false,
|
|
445
440
|
errors: []
|
package/nwss.js
CHANGED
|
@@ -694,6 +694,11 @@ const {
|
|
|
694
694
|
...otherGlobalConfig
|
|
695
695
|
} = config;
|
|
696
696
|
|
|
697
|
+
// Pre-compile global blocked regexes ONCE (used in every processUrl call)
|
|
698
|
+
const globalBlockedRegexes = Array.isArray(globalBlocked)
|
|
699
|
+
? globalBlocked.map(pattern => new RegExp(pattern))
|
|
700
|
+
: [];
|
|
701
|
+
|
|
697
702
|
// Apply global configuration overrides with validation
|
|
698
703
|
// Priority: Command line args > config.json > defaults
|
|
699
704
|
const MAX_CONCURRENT_SITES = (() => {
|
|
@@ -943,6 +948,39 @@ if (dumpUrls) {
|
|
|
943
948
|
}
|
|
944
949
|
}
|
|
945
950
|
|
|
951
|
+
// --- Buffered Log Writer ---
|
|
952
|
+
// Avoids blocking I/O on every intercepted request in debug/dumpurls mode
|
|
953
|
+
const _logBuffers = new Map(); // filePath -> string[]
|
|
954
|
+
const LOG_FLUSH_INTERVAL = 2000; // Flush every 2 seconds
|
|
955
|
+
let _logFlushTimer = null;
|
|
956
|
+
|
|
957
|
+
function bufferedLogWrite(filePath, entry) {
|
|
958
|
+
if (!filePath) return;
|
|
959
|
+
if (!_logBuffers.has(filePath)) {
|
|
960
|
+
_logBuffers.set(filePath, []);
|
|
961
|
+
}
|
|
962
|
+
_logBuffers.get(filePath).push(entry);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
function flushLogBuffers() {
|
|
966
|
+
for (const [filePath, entries] of _logBuffers) {
|
|
967
|
+
if (entries.length > 0) {
|
|
968
|
+
try {
|
|
969
|
+
fs.appendFileSync(filePath, entries.join(''));
|
|
970
|
+
} catch (err) {
|
|
971
|
+
console.warn(formatLogMessage('warn', `Failed to flush log buffer to ${filePath}: ${err.message}`));
|
|
972
|
+
}
|
|
973
|
+
entries.length = 0; // Clear buffer
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
// Start periodic flush if any logging is enabled
|
|
979
|
+
if (forceDebug || dumpUrls) {
|
|
980
|
+
_logFlushTimer = setInterval(flushLogBuffers, LOG_FLUSH_INTERVAL);
|
|
981
|
+
_logFlushTimer.unref(); // Don't keep process alive just for flushing
|
|
982
|
+
}
|
|
983
|
+
|
|
946
984
|
// Log comments if debug mode is enabled and comments exist
|
|
947
985
|
if (forceDebug && globalComments) {
|
|
948
986
|
const commentList = Array.isArray(globalComments) ? globalComments : [globalComments];
|
|
@@ -1047,15 +1085,21 @@ function shouldBypassCacheForUrl(url, siteConfig) {
|
|
|
1047
1085
|
return siteConfig.bypass_cache === true;
|
|
1048
1086
|
}
|
|
1049
1087
|
|
|
1050
|
-
// ability to use
|
|
1088
|
+
// ability to use wildcards in ignoreDomains
|
|
1089
|
+
// Cache compiled wildcard regexes to avoid recompilation on every request
|
|
1090
|
+
const _wildcardRegexCache = new Map();
|
|
1051
1091
|
function matchesIgnoreDomain(domain, ignorePatterns) {
|
|
1052
1092
|
return ignorePatterns.some(pattern => {
|
|
1053
1093
|
if (pattern.includes('*')) {
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1094
|
+
let compiled = _wildcardRegexCache.get(pattern);
|
|
1095
|
+
if (!compiled) {
|
|
1096
|
+
const regexPattern = pattern
|
|
1097
|
+
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // Escape all regex specials including *
|
|
1098
|
+
.replace(/\\\*/g, '.*'); // Convert escaped \* back to .*
|
|
1099
|
+
compiled = new RegExp(`^${regexPattern}$`);
|
|
1100
|
+
_wildcardRegexCache.set(pattern, compiled);
|
|
1101
|
+
}
|
|
1102
|
+
return compiled.test(domain);
|
|
1059
1103
|
}
|
|
1060
1104
|
return domain.endsWith(pattern);
|
|
1061
1105
|
});
|
|
@@ -1065,14 +1109,6 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1065
1109
|
// Track active frames and clear on navigation to prevent detached frame access
|
|
1066
1110
|
let activeFrames = new Set(); // Use Set to track frame references
|
|
1067
1111
|
|
|
1068
|
-
// Clear frame tracking on navigation to prevent stale references
|
|
1069
|
-
page.on('framenavigated', (frame) => {
|
|
1070
|
-
if (frame === page.mainFrame()) {
|
|
1071
|
-
// Main frame navigated - clear all tracked frames
|
|
1072
|
-
activeFrames.clear();
|
|
1073
|
-
}
|
|
1074
|
-
});
|
|
1075
|
-
|
|
1076
1112
|
// Handle frame creation with error suppression
|
|
1077
1113
|
page.on('frameattached', async (frame) => {
|
|
1078
1114
|
// Enhanced frame handling with detached frame protection
|
|
@@ -1182,10 +1218,16 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1182
1218
|
}
|
|
1183
1219
|
}
|
|
1184
1220
|
});
|
|
1185
|
-
// Handle frame navigations
|
|
1221
|
+
// Handle frame navigations - clear stale tracking and monitor activity
|
|
1186
1222
|
page.on('framenavigated', (frame) => {
|
|
1187
1223
|
|
|
1188
|
-
//
|
|
1224
|
+
// Main frame navigated - clear all tracked frames to prevent stale references
|
|
1225
|
+
if (frame === page.mainFrame()) {
|
|
1226
|
+
activeFrames.clear();
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
// Skip child frames not in our active set
|
|
1189
1231
|
if (!activeFrames.has(frame)) return;
|
|
1190
1232
|
|
|
1191
1233
|
let frameUrl;
|
|
@@ -1399,12 +1441,16 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1399
1441
|
// Set up cleanup on process termination
|
|
1400
1442
|
process.on('SIGINT', async () => {
|
|
1401
1443
|
if (forceDebug) console.log(formatLogMessage('debug', 'SIGINT received, performing cleanup...'));
|
|
1444
|
+
flushLogBuffers();
|
|
1445
|
+
if (_logFlushTimer) clearInterval(_logFlushTimer);
|
|
1402
1446
|
await performEmergencyCleanup();
|
|
1403
1447
|
process.exit(0);
|
|
1404
1448
|
});
|
|
1405
1449
|
|
|
1406
1450
|
process.on('SIGTERM', async () => {
|
|
1407
1451
|
if (forceDebug) console.log(formatLogMessage('debug', 'SIGTERM received, performing cleanup...'));
|
|
1452
|
+
flushLogBuffers();
|
|
1453
|
+
if (_logFlushTimer) clearInterval(_logFlushTimer);
|
|
1408
1454
|
await performEmergencyCleanup();
|
|
1409
1455
|
process.exit(0);
|
|
1410
1456
|
});
|
|
@@ -2195,11 +2241,10 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2195
2241
|
? siteConfig.blocked.map(pattern => new RegExp(pattern))
|
|
2196
2242
|
: [];
|
|
2197
2243
|
|
|
2198
|
-
//
|
|
2199
|
-
const
|
|
2200
|
-
?
|
|
2201
|
-
:
|
|
2202
|
-
const allBlockedRegexes = [...blockedRegexes, ...globalBlockedRegexes];
|
|
2244
|
+
// Combine site-specific with pre-compiled global blocked patterns
|
|
2245
|
+
const allBlockedRegexes = blockedRegexes.length > 0
|
|
2246
|
+
? [...blockedRegexes, ...globalBlockedRegexes]
|
|
2247
|
+
: globalBlockedRegexes; // Avoid spread when no site-specific patterns
|
|
2203
2248
|
|
|
2204
2249
|
/**
|
|
2205
2250
|
* Helper function to add domain to matched collection
|
|
@@ -2329,12 +2374,14 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2329
2374
|
// - URL matching against blocklists (`blockedRegexes`).
|
|
2330
2375
|
// - URL matching against filter patterns (`regexes`) for domain extraction.
|
|
2331
2376
|
// - Global `ignoreDomains` list.
|
|
2377
|
+
// Pre-compute values that are constant for this URL
|
|
2378
|
+
const simplifiedCurrentUrl = getRootDomain(currentUrl);
|
|
2379
|
+
|
|
2332
2380
|
page.on('request', request => {
|
|
2333
2381
|
const checkedUrl = request.url();
|
|
2334
|
-
const
|
|
2335
|
-
const checkedRootDomain = safeGetDomain(checkedUrl, false);
|
|
2382
|
+
const fullSubdomain = safeGetDomain(checkedUrl, true); // Full hostname for cache
|
|
2383
|
+
const checkedRootDomain = safeGetDomain(checkedUrl, false);
|
|
2336
2384
|
// Check against ALL first-party domains (original + all redirects)
|
|
2337
|
-
// This prevents redirect destinations from being marked as third-party
|
|
2338
2385
|
const isFirstParty = checkedRootDomain && firstPartyDomains.has(checkedRootDomain);
|
|
2339
2386
|
|
|
2340
2387
|
// Block infinite iframe loops - safely access frame URL
|
|
@@ -2347,9 +2394,9 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2347
2394
|
}
|
|
2348
2395
|
})();
|
|
2349
2396
|
if (frameUrl && frameUrl.includes('creative.dmzjmp.com') &&
|
|
2350
|
-
|
|
2397
|
+
checkedUrl.includes('go.dmzjmp.com/api/models')) {
|
|
2351
2398
|
if (forceDebug) {
|
|
2352
|
-
console.log(formatLogMessage('debug', `Blocking potential infinite iframe loop: ${
|
|
2399
|
+
console.log(formatLogMessage('debug', `Blocking potential infinite iframe loop: ${checkedUrl}`));
|
|
2353
2400
|
}
|
|
2354
2401
|
request.abort();
|
|
2355
2402
|
return;
|
|
@@ -2357,19 +2404,19 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2357
2404
|
|
|
2358
2405
|
// Enhanced debug logging to show which frame the request came from
|
|
2359
2406
|
if (forceDebug) {
|
|
2360
|
-
let
|
|
2407
|
+
let debugFrameUrl = 'unknown-frame';
|
|
2361
2408
|
let isMainFrame = false;
|
|
2362
2409
|
|
|
2363
2410
|
try {
|
|
2364
2411
|
const frame = request.frame();
|
|
2365
2412
|
if (frame) {
|
|
2366
|
-
|
|
2413
|
+
debugFrameUrl = frame.url();
|
|
2367
2414
|
isMainFrame = frame === page.mainFrame();
|
|
2368
2415
|
}
|
|
2369
2416
|
} catch (frameErr) {
|
|
2370
|
-
|
|
2417
|
+
debugFrameUrl = 'detached-frame';
|
|
2371
2418
|
}
|
|
2372
|
-
console.log(formatLogMessage('debug', `${messageColors.highlight('[req]')}[frame: ${isMainFrame ? 'main' : 'iframe'}] ${
|
|
2419
|
+
console.log(formatLogMessage('debug', `${messageColors.highlight('[req]')}[frame: ${isMainFrame ? 'main' : 'iframe'}] ${debugFrameUrl} → ${checkedUrl}`));
|
|
2373
2420
|
}
|
|
2374
2421
|
|
|
2375
2422
|
// Apply adblock rules BEFORE expensive regex checks for better performance
|
|
@@ -2395,46 +2442,36 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2395
2442
|
|
|
2396
2443
|
// Show --debug output and the url while its scanning
|
|
2397
2444
|
if (forceDebug) {
|
|
2398
|
-
const simplifiedUrl = getRootDomain(currentUrl);
|
|
2399
2445
|
const timestamp = new Date().toISOString();
|
|
2400
|
-
const logEntry = `${timestamp} [debug req][${
|
|
2446
|
+
const logEntry = `${timestamp} [debug req][${simplifiedCurrentUrl}] ${checkedUrl}\n`;
|
|
2401
2447
|
|
|
2402
2448
|
// Output to console
|
|
2403
|
-
console.log(formatLogMessage('debug', `${messageColors.highlight('[req]')}[${
|
|
2449
|
+
console.log(formatLogMessage('debug', `${messageColors.highlight('[req]')}[${simplifiedCurrentUrl}] ${checkedUrl}`));
|
|
2404
2450
|
|
|
2405
|
-
// Output to file
|
|
2406
|
-
|
|
2407
|
-
try {
|
|
2408
|
-
fs.appendFileSync(debugLogFile, logEntry + '\n');
|
|
2409
|
-
} catch (logErr) {
|
|
2410
|
-
console.warn(formatLogMessage('warn', `Failed to write to debug log file: ${logErr.message}`));
|
|
2411
|
-
}
|
|
2412
|
-
}
|
|
2451
|
+
// Output to file (buffered)
|
|
2452
|
+
bufferedLogWrite(debugLogFile, logEntry);
|
|
2413
2453
|
}
|
|
2414
|
-
const reqUrl =
|
|
2454
|
+
const reqUrl = checkedUrl;
|
|
2415
2455
|
|
|
2416
|
-
// ALWAYS extract the FULL subdomain for cache checking to preserve unique subdomains
|
|
2417
|
-
const fullSubdomain = safeGetDomain(reqUrl, true); // Always get full subdomain for cache
|
|
2418
2456
|
const reqDomain = safeGetDomain(reqUrl, perSiteSubDomains); // Output domain based on config
|
|
2419
2457
|
|
|
2420
2458
|
if (allBlockedRegexes.some(re => re.test(reqUrl))) {
|
|
2421
2459
|
if (forceDebug) {
|
|
2422
|
-
// Find which specific pattern matched
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
if (debugLogFile) {
|
|
2431
|
-
try {
|
|
2432
|
-
const timestamp = new Date().toISOString();
|
|
2433
|
-
fs.appendFileSync(debugLogFile, `${timestamp} [blocked][${simplifiedUrl}] ${reqUrl} (${patternSource} pattern: ${matchedPattern})\n`);
|
|
2434
|
-
} catch (logErr) {
|
|
2435
|
-
console.warn(formatLogMessage('warn', `Failed to write blocked domain to debug log: ${logErr.message}`));
|
|
2460
|
+
// Find which specific pattern matched using already-compiled regexes
|
|
2461
|
+
let matchedPattern = '(unknown)';
|
|
2462
|
+
let patternSource = 'global';
|
|
2463
|
+
for (let i = 0; i < allBlockedRegexes.length; i++) {
|
|
2464
|
+
if (allBlockedRegexes[i].test(reqUrl)) {
|
|
2465
|
+
matchedPattern = allBlockedRegexes[i].source;
|
|
2466
|
+
patternSource = i < blockedRegexes.length ? 'site' : 'global';
|
|
2467
|
+
break;
|
|
2436
2468
|
}
|
|
2437
2469
|
}
|
|
2470
|
+
console.log(formatLogMessage('debug', `${messageColors.blocked('[blocked]')}[${simplifiedCurrentUrl}] ${reqUrl} blocked by ${patternSource} pattern: ${matchedPattern}`));
|
|
2471
|
+
|
|
2472
|
+
// Also log to file (buffered)
|
|
2473
|
+
const timestamp = new Date().toISOString();
|
|
2474
|
+
bufferedLogWrite(debugLogFile, `${timestamp} [blocked][${simplifiedCurrentUrl}] ${reqUrl} (${patternSource} pattern: ${matchedPattern})\n`);
|
|
2438
2475
|
}
|
|
2439
2476
|
|
|
2440
2477
|
// NEW: Check if even_blocked is enabled and this URL matches filter regex
|
|
@@ -2461,15 +2498,14 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2461
2498
|
addMatchedDomain(reqDomain, resourceType, fullSubdomain);
|
|
2462
2499
|
}
|
|
2463
2500
|
|
|
2464
|
-
const simplifiedUrl = getRootDomain(currentUrl);
|
|
2465
2501
|
if (siteConfig.verbose === 1) {
|
|
2466
2502
|
const resourceInfo = (adblockRulesMode || siteConfig.adblock_rules) ? ` (${resourceType})` : '';
|
|
2467
|
-
console.log(formatLogMessage('match', `[${
|
|
2503
|
+
console.log(formatLogMessage('match', `[${simplifiedCurrentUrl}] ${reqUrl} matched regex: ${matchedRegexPattern} and resourceType: ${resourceType}${resourceInfo}`));
|
|
2468
2504
|
}
|
|
2469
2505
|
if (dumpUrls) {
|
|
2470
2506
|
const timestamp = new Date().toISOString();
|
|
2471
2507
|
const resourceInfo = (adblockRulesMode || siteConfig.adblock_rules) ? ` (${resourceType})` : '';
|
|
2472
|
-
|
|
2508
|
+
bufferedLogWrite(matchedUrlsLogFile, `${timestamp} [match][${simplifiedCurrentUrl}] ${reqUrl} (resourceType: ${resourceType})${resourceInfo} [BLOCKED BUT ADDED]\n`);
|
|
2473
2509
|
}
|
|
2474
2510
|
break; // Only match once per URL
|
|
2475
2511
|
}
|
|
@@ -2625,15 +2661,14 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2625
2661
|
} else {
|
|
2626
2662
|
addMatchedDomain(reqDomain, resourceType);
|
|
2627
2663
|
}
|
|
2628
|
-
const simplifiedUrl = getRootDomain(currentUrl);
|
|
2629
2664
|
if (siteConfig.verbose === 1) {
|
|
2630
2665
|
const resourceInfo = (adblockRulesMode || siteConfig.adblock_rules) ? ` (${resourceType})` : '';
|
|
2631
|
-
console.log(formatLogMessage('match', `[${
|
|
2666
|
+
console.log(formatLogMessage('match', `[${simplifiedCurrentUrl}] ${reqUrl} matched regex: ${matchedRegexPattern} and resourceType: ${resourceType}${resourceInfo}`));
|
|
2632
2667
|
}
|
|
2633
2668
|
if (dumpUrls) {
|
|
2634
2669
|
const timestamp = new Date().toISOString();
|
|
2635
2670
|
const resourceInfo = (adblockRulesMode || siteConfig.adblock_rules) ? ` (${resourceType})` : '';
|
|
2636
|
-
|
|
2671
|
+
bufferedLogWrite(matchedUrlsLogFile, `${timestamp} [match][${simplifiedCurrentUrl}] ${reqUrl} (resourceType: ${resourceType})${resourceInfo}\n`);
|
|
2637
2672
|
}
|
|
2638
2673
|
} else if (hasNetTools && !hasSearchString && !hasSearchStringAnd) {
|
|
2639
2674
|
// If nettools are configured (whois/dig), perform checks on the domain
|
|
@@ -4117,6 +4152,12 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
4117
4152
|
}
|
|
4118
4153
|
}
|
|
4119
4154
|
|
|
4155
|
+
// Flush any remaining buffered log entries before compression/exit
|
|
4156
|
+
flushLogBuffers();
|
|
4157
|
+
if (_logFlushTimer) {
|
|
4158
|
+
clearInterval(_logFlushTimer);
|
|
4159
|
+
}
|
|
4160
|
+
|
|
4120
4161
|
// Compress log files if --compress-logs is enabled
|
|
4121
4162
|
if (compressLogs && dumpUrls && !dryRunMode) {
|
|
4122
4163
|
// Collect all existing log files for compression
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fanboynz/network-scanner",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.36",
|
|
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": {
|