@fanboynz/network-scanner 1.0.41 → 1.0.42

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.
Files changed (3) hide show
  1. package/lib/nettools.js +151 -19
  2. package/nwss.js +2 -2
  3. package/package.json +1 -1
package/lib/nettools.js CHANGED
@@ -728,7 +728,20 @@ function createNetToolsHandler(config) {
728
728
  // Add separate deduplication caches for different lookup types
729
729
  const processedWhoisDomains = new Set();
730
730
  const processedDigDomains = new Set();
731
-
731
+ // Add whois resolution caching to avoid redundant whois lookups
732
+ const whoisResultCache = new Map();
733
+ const WHOIS_CACHE_TTL = 900000; // 15 minutes cache TTL (whois data changes less frequently)
734
+ const MAX_CACHE_SIZE = 400; // Larger cache for whois due to longer TTL
735
+ // Size Memory
736
+ // 100 ~900KB
737
+ // 200 1.8MB
738
+ // 300 2.6MB
739
+ // 400 3.4MB
740
+ // 500 4.2MB
741
+ // Add DNS resolution caching to avoid redundant dig lookups
742
+ const digResultCache = new Map();
743
+ const DIG_CACHE_TTL = 300000; // 5 minutes cache TTL
744
+ const DIG_MAX_CACHE_SIZE = 400; // Smaller cache for dig due to shorter TTL
732
745
 
733
746
  return async function handleNetToolsCheck(domain, originalDomain) {
734
747
  // Helper function to log to BOTH console and debug file
@@ -869,14 +882,43 @@ function createNetToolsHandler(config) {
869
882
  // Mark whois domain as being processed
870
883
  processedWhoisDomains.add(domain);
871
884
 
885
+ // Check whois cache first - cache key includes server for accuracy
872
886
  const selectedServer = selectWhoisServer(whoisServer, whoisServerMode);
887
+ const whoisCacheKey = `${domain}-${selectedServer || 'default'}`;
888
+ const now = Date.now();
889
+ let whoisResult = null;
873
890
 
874
- if (forceDebug) {
875
- const serverInfo = selectedServer ? ` using server ${selectedServer}` : ' using default server';
876
- logToConsoleAndFile(`${messageColors.highlight('[whois]')} Performing whois lookup for ${domain}${serverInfo}`);
891
+ if (whoisResultCache.has(whoisCacheKey)) {
892
+ const cachedEntry = whoisResultCache.get(whoisCacheKey);
893
+ if (now - cachedEntry.timestamp < WHOIS_CACHE_TTL) {
894
+ if (forceDebug) {
895
+ const age = Math.round((now - cachedEntry.timestamp) / 1000);
896
+ const serverInfo = selectedServer ? ` (server: ${selectedServer})` : ' (default server)';
897
+ logToConsoleAndFile(`${messageColors.highlight('[whois-cache]')} Using cached result for ${domain}${serverInfo} [age: ${age}s]`);
898
+ }
899
+ whoisResult = {
900
+ ...cachedEntry.result,
901
+ // Add cache metadata
902
+ fromCache: true,
903
+ cacheAge: now - cachedEntry.timestamp,
904
+ originalTimestamp: cachedEntry.timestamp
905
+ };
906
+ } else {
907
+ // Cache expired, remove it
908
+ whoisResultCache.delete(whoisCacheKey);
909
+ if (forceDebug) {
910
+ logToConsoleAndFile(`${messageColors.highlight('[whois-cache]')} Cache expired for ${domain}, performing fresh lookup`);
911
+ }
912
+ }
877
913
  }
878
-
879
- try {
914
+
915
+ // Perform fresh lookup if not cached
916
+ if (!whoisResult) {
917
+ if (forceDebug) {
918
+ const serverInfo = selectedServer ? ` using server ${selectedServer}` : ' using default server';
919
+ logToConsoleAndFile(`${messageColors.highlight('[whois]')} Performing fresh whois lookup for ${domain}${serverInfo}`);
920
+ }
921
+
880
922
  // Configure retry options based on site config or use defaults
881
923
  const retryOptions = {
882
924
  maxRetries: siteConfig.whois_max_retries || 2,
@@ -886,7 +928,47 @@ function createNetToolsHandler(config) {
886
928
  retryOnError: siteConfig.whois_retry_on_error === true // Default false
887
929
  };
888
930
 
889
- const whoisResult = await whoisLookupWithRetry(domain, 8000, whoisServer, forceDebug, retryOptions, whoisDelay, logToConsoleAndFile);
931
+ try {
932
+ whoisResult = await whoisLookupWithRetry(domain, 8000, whoisServer, forceDebug, retryOptions, whoisDelay, logToConsoleAndFile);
933
+
934
+ // Cache successful results (and certain types of failures)
935
+ if (whoisResult.success ||
936
+ (whoisResult.error && !whoisResult.isTimeout &&
937
+ !whoisResult.error.toLowerCase().includes('connection') &&
938
+ !whoisResult.error.toLowerCase().includes('network'))) {
939
+
940
+ whoisResultCache.set(whoisCacheKey, {
941
+ result: whoisResult,
942
+ timestamp: now
943
+ });
944
+
945
+ if (forceDebug) {
946
+ const cacheType = whoisResult.success ? 'successful' : 'failed';
947
+ const serverInfo = selectedServer ? ` (server: ${selectedServer})` : ' (default server)';
948
+ logToConsoleAndFile(`${messageColors.highlight('[whois-cache]')} Cached ${cacheType} result for ${domain}${serverInfo}`);
949
+ }
950
+ }
951
+ } catch (whoisError) {
952
+ // Handle exceptions from whois lookup
953
+ if (forceDebug) {
954
+ logToConsoleAndFile(`${messageColors.highlight('[whois]')} Exception during lookup for ${domain}: ${whoisError.message}`);
955
+ logToConsoleAndFile(`${messageColors.highlight('[whois]')} Exception type: ${whoisError.constructor.name}`);
956
+ if (whoisError.stack) {
957
+ logToConsoleAndFile(`${messageColors.highlight('[whois]')} Stack trace: ${whoisError.stack.split('\n').slice(0, 3).join(' -> ')}`);
958
+ }
959
+ }
960
+
961
+ // Log whois exceptions in dry run mode
962
+ if (dryRunCallback && forceDebug) {
963
+ logToConsoleAndFile(`${messageColors.highlight('[whois-dryrun]')} Exception: ${whoisError.message}`);
964
+ }
965
+ // Continue with dig if configured
966
+ whoisResult = null; // Ensure we don't process a null result
967
+ }
968
+ }
969
+
970
+ // Process whois result (whether from cache or fresh lookup)
971
+ if (whoisResult) {
890
972
 
891
973
  if (whoisResult.success) {
892
974
  // Check AND terms if configured
@@ -896,6 +978,7 @@ function createNetToolsHandler(config) {
896
978
  dryRunCallback(domain, 'whois', 'AND logic', whoisTerms.join(', '), 'All terms found in whois data', {
897
979
  server: whoisResult.whoisServer || 'default',
898
980
  duration: whoisResult.duration,
981
+ fromCache: whoisResult.fromCache || false,
899
982
  retryAttempts: whoisResult.retryInfo?.totalAttempts || 1
900
983
  });
901
984
  }
@@ -913,6 +996,7 @@ function createNetToolsHandler(config) {
913
996
  dryRunCallback(domain, 'whois', 'OR logic', matchedTerm, 'Term found in whois data', {
914
997
  server: whoisResult.whoisServer || 'default',
915
998
  duration: whoisResult.duration,
999
+ fromCache: whoisResult.fromCache || false,
916
1000
  retryAttempts: whoisResult.retryInfo?.totalAttempts || 1
917
1001
  });
918
1002
  }
@@ -925,7 +1009,9 @@ function createNetToolsHandler(config) {
925
1009
  if (forceDebug) {
926
1010
  const serverUsed = whoisResult.whoisServer ? ` (server: ${whoisResult.whoisServer})` : ' (default server)';
927
1011
  const retryInfo = whoisResult.retryInfo ? ` [${whoisResult.retryInfo.totalAttempts}/${whoisResult.retryInfo.maxAttempts} attempts]` : '';
928
- logToConsoleAndFile(`${messageColors.highlight('[whois]')} Lookup completed for ${domain}${serverUsed} in ${whoisResult.duration}ms${retryInfo}`);
1012
+ const cacheInfo = whoisResult.fromCache ? ` [CACHED - ${Math.round(whoisResult.cacheAge / 1000)}s old]` : '';
1013
+ const duration = whoisResult.fromCache ? `cached in 0ms` : `in ${whoisResult.duration}ms`;
1014
+ logToConsoleAndFile(`${messageColors.highlight('[whois]')} Lookup completed for ${domain}${serverUsed} ${duration}${retryInfo}${cacheInfo}`);
929
1015
 
930
1016
  if (whoisResult.retryInfo && whoisResult.retryInfo.retriedAfterFailure) {
931
1017
  logToConsoleAndFile(`${messageColors.highlight('[whois]')} Success after retry - servers attempted: [${whoisResult.retryInfo.serversAttempted.map(s => s || 'default').join(', ')}]`);
@@ -1001,20 +1087,21 @@ function createNetToolsHandler(config) {
1001
1087
  }
1002
1088
  // Don't return early - continue with dig if configured
1003
1089
  }
1004
- } catch (whoisError) {
1005
- if (forceDebug) {
1006
- logToConsoleAndFile(`${messageColors.highlight('[whois]')} Exception during lookup for ${domain}: ${whoisError.message}`);
1007
- logToConsoleAndFile(`${messageColors.highlight('[whois]')} Exception type: ${whoisError.constructor.name}`);
1008
- if (whoisError.stack) {
1009
- logToConsoleAndFile(`${messageColors.highlight('[whois]')} Stack trace: ${whoisError.stack.split('\n').slice(0, 3).join(' -> ')}`);
1090
+ }
1091
+
1092
+ // Periodic whois cache cleanup to prevent memory leaks
1093
+ if (whoisResultCache.size > MAX_CACHE_SIZE) {
1094
+ const now = Date.now();
1095
+ let cleanedCount = 0;
1096
+ for (const [key, entry] of whoisResultCache.entries()) {
1097
+ if (now - entry.timestamp > WHOIS_CACHE_TTL) {
1098
+ whoisResultCache.delete(key);
1099
+ cleanedCount++;
1010
1100
  }
1011
1101
  }
1012
-
1013
- // Log whois exceptions in dry run mode
1014
- if (dryRunCallback && forceDebug) {
1015
- logToConsoleAndFile(`${messageColors.highlight('[whois-dryrun]')} Exception: ${whoisError.message}`);
1102
+ if (forceDebug && cleanedCount > 0) {
1103
+ logToConsoleAndFile(`${messageColors.highlight('[whois-cache]')} Cleaned ${cleanedCount} expired entries, cache size: ${whoisResultCache.size}`);
1016
1104
  }
1017
- // Continue with dig if configured
1018
1105
  }
1019
1106
  }
1020
1107
 
@@ -1031,7 +1118,37 @@ function createNetToolsHandler(config) {
1031
1118
  }
1032
1119
 
1033
1120
  try {
1121
+ // Check dig cache first to avoid redundant dig operations
1122
+ const digCacheKey = `${digDomain}-${digRecordType}`;
1123
+ const now = Date.now();
1124
+ let digResult = null;
1125
+
1126
+ if (digResultCache.has(digCacheKey)) {
1127
+ const cachedEntry = digResultCache.get(digCacheKey);
1128
+ if (now - cachedEntry.timestamp < DIG_CACHE_TTL) {
1129
+ if (forceDebug) {
1130
+ logToConsoleAndFile(`${messageColors.highlight('[dig-cache]')} Using cached result for ${digDomain} (${digRecordType}) [age: ${Math.round((now - cachedEntry.timestamp) / 1000)}s]`);
1131
+ }
1132
+ digResult = cachedEntry.result;
1133
+ } else {
1134
+ // Cache expired, remove it
1135
+ digResultCache.delete(digCacheKey);
1136
+ }
1137
+ }
1138
+
1139
+ if (!digResult) {
1034
1140
  const digResult = await digLookup(digDomain, digRecordType, 5000); // 5 second timeout for dig
1141
+
1142
+ // Cache the result for future use
1143
+ digResultCache.set(digCacheKey, {
1144
+ result: digResult,
1145
+ timestamp: now
1146
+ });
1147
+
1148
+ if (forceDebug && digResult.success) {
1149
+ logToConsoleAndFile(`${messageColors.highlight('[dig-cache]')} Cached new result for ${digDomain} (${digRecordType})`);
1150
+ }
1151
+ }
1035
1152
 
1036
1153
  if (digResult.success) {
1037
1154
  // Check AND terms if configured
@@ -1091,6 +1208,21 @@ function createNetToolsHandler(config) {
1091
1208
  logToConsoleAndFile(`${messageColors.highlight('[dig-dryrun]')} Exception: ${digError.message}`);
1092
1209
  }
1093
1210
  }
1211
+
1212
+ // Periodic dig cache cleanup to prevent memory leaks
1213
+ if (digResultCache.size > DIG_MAX_CACHE_SIZE) {
1214
+ const now = Date.now();
1215
+ let cleanedCount = 0;
1216
+ for (const [key, entry] of digResultCache.entries()) {
1217
+ if (now - entry.timestamp > DIG_CACHE_TTL) {
1218
+ digResultCache.delete(key);
1219
+ cleanedCount++;
1220
+ }
1221
+ }
1222
+ if (forceDebug && cleanedCount > 0) {
1223
+ logToConsoleAndFile(`${messageColors.highlight('[dig-cache]')} Cleaned ${cleanedCount} expired entries, cache size: ${digResultCache.size}`);
1224
+ }
1225
+ }
1094
1226
  }
1095
1227
 
1096
1228
  // Domain matches if any of these conditions are true:
package/nwss.js CHANGED
@@ -1,4 +1,4 @@
1
- // === Network scanner script (nwss.js) v1.0.41 ===
1
+ // === Network scanner script (nwss.js) v1.0.42 ===
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
@@ -33,7 +33,7 @@ const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/r
33
33
  const { monitorBrowserHealth, isBrowserHealthy } = require('./lib/browserhealth');
34
34
 
35
35
  // --- Script Configuration & Constants ---
36
- const VERSION = '1.0.41'; // Script version
36
+ const VERSION = '1.0.42'; // Script version
37
37
 
38
38
  // get startTime
39
39
  const startTime = Date.now();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fanboynz/network-scanner",
3
- "version": "1.0.41",
3
+ "version": "1.0.42",
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": {