@fanboynz/network-scanner 1.0.46 → 1.0.48
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/.github/workflows/npm-publish.yml +66 -19
- package/eslint.config.mjs +6 -0
- package/lib/cdp.js +302 -0
- package/nwss.js +19 -44
- package/package.json +8 -3
|
@@ -1,33 +1,80 @@
|
|
|
1
|
-
|
|
2
|
-
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
|
|
3
|
-
|
|
4
|
-
name: Node.js Package
|
|
1
|
+
name: Publish to NPM
|
|
5
2
|
|
|
6
3
|
on:
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, master ] # adjust to your default branch name
|
|
9
6
|
|
|
10
7
|
jobs:
|
|
11
|
-
|
|
8
|
+
check-version:
|
|
12
9
|
runs-on: ubuntu-latest
|
|
10
|
+
outputs:
|
|
11
|
+
version-changed: ${{ steps.check.outputs.changed }}
|
|
12
|
+
version: ${{ steps.check.outputs.version }}
|
|
13
13
|
steps:
|
|
14
14
|
- uses: actions/checkout@v4
|
|
15
|
-
- uses: actions/setup-node@v4
|
|
16
15
|
with:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
16
|
+
fetch-depth: 0 # fetch full history to compare versions
|
|
17
|
+
|
|
18
|
+
- name: Check if version changed
|
|
19
|
+
id: check
|
|
20
|
+
run: |
|
|
21
|
+
# Get current version from package.json
|
|
22
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
23
|
+
echo "Current version: $CURRENT_VERSION"
|
|
24
|
+
|
|
25
|
+
# Get previous version from the last commit
|
|
26
|
+
git checkout HEAD~1 -- package.json 2>/dev/null || echo "No previous package.json found"
|
|
27
|
+
PREVIOUS_VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "0.0.0")
|
|
28
|
+
echo "Previous version: $PREVIOUS_VERSION"
|
|
29
|
+
|
|
30
|
+
# Restore current package.json
|
|
31
|
+
git checkout HEAD -- package.json
|
|
32
|
+
|
|
33
|
+
# Check if version changed
|
|
34
|
+
if [ "$CURRENT_VERSION" != "$PREVIOUS_VERSION" ]; then
|
|
35
|
+
echo "Version changed from $PREVIOUS_VERSION to $CURRENT_VERSION"
|
|
36
|
+
echo "changed=true" >> $GITHUB_OUTPUT
|
|
37
|
+
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
|
38
|
+
else
|
|
39
|
+
echo "Version unchanged"
|
|
40
|
+
echo "changed=false" >> $GITHUB_OUTPUT
|
|
41
|
+
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
|
42
|
+
fi
|
|
20
43
|
|
|
21
|
-
publish
|
|
22
|
-
needs:
|
|
44
|
+
publish:
|
|
45
|
+
needs: check-version
|
|
46
|
+
if: needs.check-version.outputs.version-changed == 'true'
|
|
23
47
|
runs-on: ubuntu-latest
|
|
24
48
|
steps:
|
|
25
49
|
- uses: actions/checkout@v4
|
|
26
|
-
|
|
50
|
+
|
|
51
|
+
- name: Setup Node.js
|
|
52
|
+
uses: actions/setup-node@v4
|
|
27
53
|
with:
|
|
28
|
-
node-version:
|
|
29
|
-
registry-url: https://registry.npmjs.org
|
|
30
|
-
|
|
31
|
-
-
|
|
54
|
+
node-version: '18' # matches your package.json requirement
|
|
55
|
+
registry-url: 'https://registry.npmjs.org'
|
|
56
|
+
|
|
57
|
+
- name: Install dependencies
|
|
58
|
+
run: npm ci
|
|
59
|
+
|
|
60
|
+
- name: Run linting
|
|
61
|
+
run: npm run lint
|
|
62
|
+
|
|
63
|
+
- name: Verify npm authentication
|
|
64
|
+
run: npm whoami
|
|
65
|
+
env:
|
|
66
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
67
|
+
|
|
68
|
+
- name: Publish to NPM
|
|
69
|
+
run: npm publish
|
|
70
|
+
env:
|
|
71
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
72
|
+
|
|
73
|
+
- name: Create Git Tag
|
|
74
|
+
run: |
|
|
75
|
+
git config --local user.email "action@github.com"
|
|
76
|
+
git config --local user.name "GitHub Action"
|
|
77
|
+
git tag v${{ needs.check-version.outputs.version }}
|
|
78
|
+
git push origin v${{ needs.check-version.outputs.version }}
|
|
32
79
|
env:
|
|
33
|
-
|
|
80
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
package/lib/cdp.js
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
// === Chrome DevTools Protocol (CDP) Module ===
|
|
2
|
+
// Handles CDP session management and network request logging for enhanced browser monitoring
|
|
3
|
+
//
|
|
4
|
+
// INTEGRATION GUIDE FOR OTHER APPLICATIONS:
|
|
5
|
+
// This module provides a clean interface for Chrome DevTools Protocol integration with Puppeteer.
|
|
6
|
+
// It can be easily integrated into any Node.js application that uses Puppeteer for browser automation.
|
|
7
|
+
//
|
|
8
|
+
// BASIC USAGE:
|
|
9
|
+
// const { createCDPSession } = require('./lib/cdp');
|
|
10
|
+
// const cdpManager = await createCDPSession(page, url, options);
|
|
11
|
+
// // ... do your work ...
|
|
12
|
+
// await cdpManager.cleanup(); // Always cleanup when done
|
|
13
|
+
//
|
|
14
|
+
// DEPENDENCIES:
|
|
15
|
+
// - Puppeteer (any recent version)
|
|
16
|
+
// - ./colorize module (for logging) - can be replaced with console.log if needed
|
|
17
|
+
//
|
|
18
|
+
// PERFORMANCE CONSIDERATIONS:
|
|
19
|
+
// - CDP adds ~10-20% overhead to page processing
|
|
20
|
+
// - Use selectively on complex sites that need deep network visibility
|
|
21
|
+
// - Avoid on high-volume batch processing unless debugging
|
|
22
|
+
//
|
|
23
|
+
// COMPATIBILITY:
|
|
24
|
+
// - Works with Chrome/Chromium browsers
|
|
25
|
+
// - Compatible with headless and headful modes
|
|
26
|
+
// - Tested with Puppeteer 13+ but should work with older versions
|
|
27
|
+
|
|
28
|
+
const { formatLogMessage } = require('./colorize');
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Creates and manages a CDP session for network monitoring
|
|
32
|
+
*
|
|
33
|
+
* INTEGRATION EXAMPLE:
|
|
34
|
+
* const cdpManager = await createCDPSession(page, 'https://example.com', {
|
|
35
|
+
* enableCDP: true, // Global CDP flag
|
|
36
|
+
* siteSpecificCDP: true, // Site-specific CDP flag
|
|
37
|
+
* forceDebug: false // Enable debug logging
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* // Your page automation code here...
|
|
41
|
+
* await page.goto('https://example.com');
|
|
42
|
+
*
|
|
43
|
+
* // Always cleanup when done
|
|
44
|
+
* await cdpManager.cleanup();
|
|
45
|
+
*
|
|
46
|
+
* WHAT IT MONITORS:
|
|
47
|
+
* - All network requests (GET, POST, etc.)
|
|
48
|
+
* - Request initiators (script, parser, user, etc.)
|
|
49
|
+
* - Request/response timing
|
|
50
|
+
* - Failed requests and errors
|
|
51
|
+
*
|
|
52
|
+
* ERROR HANDLING:
|
|
53
|
+
* - Gracefully handles CDP connection failures
|
|
54
|
+
* - Distinguishes between critical and non-critical errors
|
|
55
|
+
* - Returns null session object if CDP setup fails
|
|
56
|
+
* - Never throws on cleanup operations
|
|
57
|
+
*
|
|
58
|
+
* @param {import('puppeteer').Page} page - The Puppeteer page instance
|
|
59
|
+
* @param {string} currentUrl - The URL being processed (used for logging context)
|
|
60
|
+
* @param {object} options - Configuration options
|
|
61
|
+
* @param {boolean} options.enableCDP - Global CDP flag (from --cdp command line)
|
|
62
|
+
* @param {boolean} options.siteSpecificCDP - Site-specific CDP flag (from config)
|
|
63
|
+
* @param {boolean} options.forceDebug - Debug logging flag
|
|
64
|
+
* @returns {Promise<object>} CDP session object with cleanup method
|
|
65
|
+
*/
|
|
66
|
+
async function createCDPSession(page, currentUrl, options = {}) {
|
|
67
|
+
const { enableCDP, siteSpecificCDP, forceDebug } = options;
|
|
68
|
+
|
|
69
|
+
// Determine if CDP logging is needed for this page
|
|
70
|
+
// You can customize this logic for your application's needs
|
|
71
|
+
const cdpLoggingNeeded = enableCDP || siteSpecificCDP === true;
|
|
72
|
+
|
|
73
|
+
if (!cdpLoggingNeeded) {
|
|
74
|
+
// Return a null session with no-op cleanup for consistent API
|
|
75
|
+
return { session: null, cleanup: async () => {} };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Log which CDP mode is being used
|
|
79
|
+
if (forceDebug) {
|
|
80
|
+
if (enableCDP) {
|
|
81
|
+
console.log(formatLogMessage('debug', `CDP logging globally enabled by --cdp, applying to page: ${currentUrl}`));
|
|
82
|
+
} else if (siteSpecificCDP === true) {
|
|
83
|
+
console.log(formatLogMessage('debug', `CDP logging enabled for page ${currentUrl} via site-specific 'cdp: true' config.`));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let cdpSession = null;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
// Create CDP session - this connects to Chrome's internal debugging interface
|
|
91
|
+
cdpSession = await page.target().createCDPSession();
|
|
92
|
+
|
|
93
|
+
// Enable network domain - required for network event monitoring
|
|
94
|
+
await cdpSession.send('Network.enable');
|
|
95
|
+
|
|
96
|
+
// Set up network request monitoring
|
|
97
|
+
// This captures ALL network requests at the browser engine level
|
|
98
|
+
cdpSession.on('Network.requestWillBeSent', (params) => {
|
|
99
|
+
const { url: requestUrl, method } = params.request;
|
|
100
|
+
const initiator = params.initiator ? params.initiator.type : 'unknown';
|
|
101
|
+
|
|
102
|
+
// Extract hostname for logging context (handles URL parsing errors gracefully)
|
|
103
|
+
let hostnameForLog = 'unknown-host';
|
|
104
|
+
try {
|
|
105
|
+
hostnameForLog = new URL(currentUrl).hostname;
|
|
106
|
+
} catch (_) {
|
|
107
|
+
// Ignore URL parsing errors for logging context
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Log the request with context - customize this for your needs
|
|
111
|
+
// Format: [cdp][hostname] METHOD url (initiator: type)
|
|
112
|
+
console.log(formatLogMessage('debug', `[cdp][${hostnameForLog}] ${method} ${requestUrl} (initiator: ${initiator})`));
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
if (forceDebug) {
|
|
116
|
+
console.log(formatLogMessage('debug', `CDP session created successfully for ${currentUrl}`));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
session: cdpSession,
|
|
121
|
+
cleanup: async () => {
|
|
122
|
+
// Safe cleanup that never throws errors
|
|
123
|
+
if (cdpSession) {
|
|
124
|
+
try {
|
|
125
|
+
await cdpSession.detach();
|
|
126
|
+
if (forceDebug) {
|
|
127
|
+
console.log(formatLogMessage('debug', `CDP session detached for ${currentUrl}`));
|
|
128
|
+
}
|
|
129
|
+
} catch (cdpCleanupErr) {
|
|
130
|
+
// Log cleanup errors but don't throw - cleanup should never fail the calling code
|
|
131
|
+
if (forceDebug) {
|
|
132
|
+
console.log(formatLogMessage('debug', `Failed to detach CDP session for ${currentUrl}: ${cdpCleanupErr.message}`));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
} catch (cdpErr) {
|
|
140
|
+
cdpSession = null; // Reset on failure
|
|
141
|
+
|
|
142
|
+
// Categorize CDP errors for proper handling
|
|
143
|
+
if (cdpErr.message.includes('Network.enable timed out') ||
|
|
144
|
+
cdpErr.message.includes('Protocol error')) {
|
|
145
|
+
// CRITICAL ERROR: Browser is broken and needs restart
|
|
146
|
+
// Re-throw these errors so calling code can handle browser restart
|
|
147
|
+
throw new Error(`Browser protocol broken: ${cdpErr.message}`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// NON-CRITICAL ERROR: CDP failed but browser is still usable
|
|
151
|
+
// Log warning but return working session object
|
|
152
|
+
console.warn(formatLogMessage('warn', `[cdp] Failed to attach CDP session for ${currentUrl}: ${cdpErr.message}`));
|
|
153
|
+
|
|
154
|
+
// Return null session with no-op cleanup for consistent API
|
|
155
|
+
return {
|
|
156
|
+
session: null,
|
|
157
|
+
cleanup: async () => {}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Validates CDP availability and configuration
|
|
164
|
+
*
|
|
165
|
+
* USAGE IN YOUR APPLICATION:
|
|
166
|
+
* const validation = validateCDPConfig(siteConfig, globalCDPFlag);
|
|
167
|
+
* if (!validation.isValid) {
|
|
168
|
+
* console.warn('CDP configuration issues detected');
|
|
169
|
+
* }
|
|
170
|
+
* validation.recommendations.forEach(rec => console.log('Recommendation:', rec));
|
|
171
|
+
*
|
|
172
|
+
* @param {object} siteConfig - Site configuration object
|
|
173
|
+
* @param {boolean} globalCDP - Global CDP flag
|
|
174
|
+
* @returns {object} Validation result with recommendations
|
|
175
|
+
*/
|
|
176
|
+
function validateCDPConfig(siteConfig, globalCDP) {
|
|
177
|
+
const warnings = [];
|
|
178
|
+
const recommendations = [];
|
|
179
|
+
|
|
180
|
+
// Check for conflicting configurations
|
|
181
|
+
if (globalCDP && siteConfig.cdp === false) {
|
|
182
|
+
warnings.push('Site-specific CDP disabled but global CDP is enabled - global setting will override');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Performance recommendations
|
|
186
|
+
if (globalCDP || siteConfig.cdp === true) {
|
|
187
|
+
recommendations.push('CDP logging enabled - this may impact performance for high-traffic sites');
|
|
188
|
+
|
|
189
|
+
if (siteConfig.timeout && siteConfig.timeout < 30000) {
|
|
190
|
+
recommendations.push('Consider increasing timeout when using CDP logging to avoid protocol timeouts');
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
isValid: true,
|
|
196
|
+
warnings,
|
|
197
|
+
recommendations
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Enhanced CDP session with additional network monitoring features
|
|
203
|
+
*
|
|
204
|
+
* ADVANCED FEATURES:
|
|
205
|
+
* - JavaScript exception monitoring
|
|
206
|
+
* - Security state change detection
|
|
207
|
+
* - Failed network request tracking
|
|
208
|
+
* - Enhanced error reporting
|
|
209
|
+
*
|
|
210
|
+
* USE CASES:
|
|
211
|
+
* - Security analysis requiring comprehensive monitoring
|
|
212
|
+
* - Debugging complex single-page applications
|
|
213
|
+
* - Performance analysis of web applications
|
|
214
|
+
* - Research requiring detailed browser insights
|
|
215
|
+
*
|
|
216
|
+
* PERFORMANCE IMPACT:
|
|
217
|
+
* - Adds additional CDP domain subscriptions
|
|
218
|
+
* - Higher memory usage due to more event listeners
|
|
219
|
+
* - Recommended only for detailed analysis scenarios
|
|
220
|
+
*
|
|
221
|
+
* @param {import('puppeteer').Page} page - The Puppeteer page instance
|
|
222
|
+
* @param {string} currentUrl - The URL being processed
|
|
223
|
+
* @param {object} options - Configuration options (same as createCDPSession)
|
|
224
|
+
* @returns {Promise<object>} Enhanced CDP session object with isEnhanced flag
|
|
225
|
+
*/
|
|
226
|
+
async function createEnhancedCDPSession(page, currentUrl, options = {}) {
|
|
227
|
+
const basicSession = await createCDPSession(page, currentUrl, options);
|
|
228
|
+
|
|
229
|
+
if (!basicSession.session) {
|
|
230
|
+
return basicSession;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const { session } = basicSession;
|
|
234
|
+
const { forceDebug } = options;
|
|
235
|
+
|
|
236
|
+
try {
|
|
237
|
+
// Enable additional CDP domains for enhanced monitoring
|
|
238
|
+
await session.send('Runtime.enable'); // For JavaScript exceptions
|
|
239
|
+
await session.send('Security.enable'); // For security state changes
|
|
240
|
+
|
|
241
|
+
// Monitor JavaScript exceptions - useful for debugging problematic sites
|
|
242
|
+
session.on('Runtime.exceptionThrown', (params) => {
|
|
243
|
+
if (forceDebug) {
|
|
244
|
+
console.log(formatLogMessage('debug', `[cdp][exception] ${params.exceptionDetails.text}`));
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// Monitor security state changes - detect mixed content, certificate issues, etc.
|
|
249
|
+
session.on('Security.securityStateChanged', (params) => {
|
|
250
|
+
if (forceDebug && params.securityState !== 'secure') {
|
|
251
|
+
console.log(formatLogMessage('debug', `[cdp][security] Security state: ${params.securityState}`));
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// Monitor failed network requests - useful for understanding site issues
|
|
256
|
+
session.on('Network.loadingFailed', (params) => {
|
|
257
|
+
if (forceDebug) {
|
|
258
|
+
console.log(formatLogMessage('debug', `[cdp][failed] ${params.errorText}: ${params.requestId}`));
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
return {
|
|
263
|
+
session,
|
|
264
|
+
cleanup: basicSession.cleanup,
|
|
265
|
+
isEnhanced: true // Flag to indicate enhanced features are active
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
} catch (enhancedErr) {
|
|
269
|
+
if (forceDebug) {
|
|
270
|
+
console.log(formatLogMessage('debug', `Enhanced CDP features failed, falling back to basic session: ${enhancedErr.message}`));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Graceful degradation: return basic session if enhanced features fail
|
|
274
|
+
// This ensures your application continues working even if advanced features break
|
|
275
|
+
return basicSession;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// EXPORT INTERFACE FOR OTHER APPLICATIONS:
|
|
280
|
+
// This module provides a clean, reusable interface for CDP integration.
|
|
281
|
+
// Simply require this module and use the exported functions.
|
|
282
|
+
//
|
|
283
|
+
// CUSTOMIZATION TIPS:
|
|
284
|
+
// 1. Replace './colorize' import with your own logging system
|
|
285
|
+
// 2. Modify the request logging format in the Network.requestWillBeSent handler
|
|
286
|
+
// 3. Add additional CDP domain subscriptions in createEnhancedCDPSession
|
|
287
|
+
// 4. Customize error categorization in the catch blocks
|
|
288
|
+
//
|
|
289
|
+
// TROUBLESHOOTING:
|
|
290
|
+
// - If you get "Protocol error" frequently, the browser may be overloaded
|
|
291
|
+
// - Timeout errors usually indicate the browser needs to be restarted
|
|
292
|
+
// - "Target closed" means the page was closed while CDP was active
|
|
293
|
+
//
|
|
294
|
+
// BROWSER COMPATIBILITY:
|
|
295
|
+
// - Chrome/Chromium 60+ (older versions may have limited CDP support)
|
|
296
|
+
// - Works in both headless and headed modes
|
|
297
|
+
// - Some features may not work in --no-sandbox mode
|
|
298
|
+
module.exports = {
|
|
299
|
+
createCDPSession,
|
|
300
|
+
validateCDPConfig,
|
|
301
|
+
createEnhancedCDPSession
|
|
302
|
+
};
|
package/nwss.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// === Network scanner script (nwss.js) v1.0.
|
|
1
|
+
// === Network scanner script (nwss.js) v1.0.48 ===
|
|
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
|
|
@@ -25,6 +25,8 @@ const { handleBrowserExit, cleanupChromeTempFiles } = require('./lib/browserexit
|
|
|
25
25
|
const { createNetToolsHandler, createEnhancedDryRunCallback, validateWhoisAvailability, validateDigAvailability } = require('./lib/nettools');
|
|
26
26
|
// File compare
|
|
27
27
|
const { loadComparisonRules, filterUniqueRules } = require('./lib/compare');
|
|
28
|
+
// CDP functionality
|
|
29
|
+
const { createCDPSession } = require('./lib/cdp');
|
|
28
30
|
// Colorize various text when used
|
|
29
31
|
const { colorize, colors, messageColors, tags, formatLogMessage } = require('./lib/colorize');
|
|
30
32
|
// Enhanced mouse interaction and page simulation
|
|
@@ -37,7 +39,7 @@ const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/r
|
|
|
37
39
|
const { monitorBrowserHealth, isBrowserHealthy } = require('./lib/browserhealth');
|
|
38
40
|
|
|
39
41
|
// --- Script Configuration & Constants ---
|
|
40
|
-
const VERSION = '1.0.
|
|
42
|
+
const VERSION = '1.0.48'; // Script version
|
|
41
43
|
|
|
42
44
|
// get startTime
|
|
43
45
|
const startTime = Date.now();
|
|
@@ -1149,6 +1151,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1149
1151
|
|
|
1150
1152
|
let page = null;
|
|
1151
1153
|
let cdpSession = null;
|
|
1154
|
+
let cdpSessionManager = null;
|
|
1152
1155
|
// Use Map to track domains and their resource types for --adblock-rules or --dry-run
|
|
1153
1156
|
const matchedDomains = (adblockRulesMode || siteConfig.adblock_rules || dryRunMode) ? new Map() : new Set();
|
|
1154
1157
|
|
|
@@ -1274,36 +1277,19 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1274
1277
|
// --- END: CSS Element Blocking Setup ---
|
|
1275
1278
|
|
|
1276
1279
|
// --- Per-Page CDP Setup ---
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
cdpSession = await page.target().createCDPSession();
|
|
1288
|
-
await cdpSession.send('Network.enable');
|
|
1289
|
-
cdpSession.on('Network.requestWillBeSent', (params) => {
|
|
1290
|
-
const { url: requestUrl, method } = params.request;
|
|
1291
|
-
const initiator = params.initiator ? params.initiator.type : 'unknown';
|
|
1292
|
-
let hostnameForLog = 'unknown-host';
|
|
1293
|
-
try {
|
|
1294
|
-
hostnameForLog = new URL(currentUrl).hostname;
|
|
1295
|
-
} catch (_) { /* ignore if currentUrl is invalid for URL parsing */ }
|
|
1296
|
-
console.log(formatLogMessage('debug', `[cdp][${hostnameForLog}] ${method} ${requestUrl} (initiator: ${initiator})`));
|
|
1297
|
-
});
|
|
1298
|
-
} catch (cdpErr) {
|
|
1299
|
-
cdpSession = null; // Reset on failure
|
|
1300
|
-
if (cdpErr.message.includes('Network.enable timed out') ||
|
|
1301
|
-
cdpErr.message.includes('Protocol error')) {
|
|
1302
|
-
// This indicates browser is completely broken
|
|
1303
|
-
throw new Error(`Browser protocol broken: ${cdpErr.message}`);
|
|
1304
|
-
}
|
|
1305
|
-
console.warn(formatLogMessage('warn', `[cdp] Failed to attach CDP session for ${currentUrl}: ${cdpErr.message}`));
|
|
1280
|
+
|
|
1281
|
+
try {
|
|
1282
|
+
cdpSessionManager = await createCDPSession(page, currentUrl, {
|
|
1283
|
+
enableCDP,
|
|
1284
|
+
siteSpecificCDP: siteConfig.cdp,
|
|
1285
|
+
forceDebug
|
|
1286
|
+
});
|
|
1287
|
+
} catch (cdpErr) {
|
|
1288
|
+
if (cdpErr.message.includes('Browser protocol broken')) {
|
|
1289
|
+
throw cdpErr; // Re-throw critical browser errors
|
|
1306
1290
|
}
|
|
1291
|
+
// Non-critical CDP errors are already handled in the module
|
|
1292
|
+
cdpSessionManager = { session: null, cleanup: async () => {} };
|
|
1307
1293
|
}
|
|
1308
1294
|
// --- End of Per-Page CDP Setup ---
|
|
1309
1295
|
|
|
@@ -2267,19 +2253,8 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2267
2253
|
} finally {
|
|
2268
2254
|
// Guaranteed resource cleanup - this runs regardless of success or failure
|
|
2269
2255
|
|
|
2270
|
-
if (
|
|
2271
|
-
|
|
2272
|
-
await cdpSession.detach();
|
|
2273
|
-
if (forceDebug) console.log(formatLogMessage('debug', `CDP session detached for ${currentUrl}`));
|
|
2274
|
-
} catch (cdpCleanupErr) {
|
|
2275
|
-
if (forceDebug) console.log(formatLogMessage('debug', `Failed to detach CDP session for ${currentUrl}: ${cdpCleanupErr.message}`));
|
|
2276
|
-
}
|
|
2277
|
-
}
|
|
2278
|
-
// Add small delay to allow cleanup to complete
|
|
2279
|
-
try {
|
|
2280
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
2281
|
-
} catch (delayErr) {
|
|
2282
|
-
// Ignore timeout errors
|
|
2256
|
+
if (cdpSessionManager) {
|
|
2257
|
+
await cdpSessionManager.cleanup();
|
|
2283
2258
|
}
|
|
2284
2259
|
|
|
2285
2260
|
if (page && !page.isClosed()) {
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fanboynz/network-scanner",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.48",
|
|
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": {
|
|
7
7
|
"start": "node nwss.js",
|
|
8
8
|
"scan": "node nwss.js",
|
|
9
9
|
"help": "node nwss.js --help",
|
|
10
|
-
"version": "node nwss.js --version"
|
|
10
|
+
"version": "node nwss.js --version",
|
|
11
|
+
"lint": "eslint *.js lib/*.js"
|
|
11
12
|
},
|
|
12
13
|
"dependencies": {
|
|
13
14
|
"p-limit": "^4.0.0",
|
|
@@ -41,5 +42,9 @@
|
|
|
41
42
|
"bugs": {
|
|
42
43
|
"url": "https://github.com/ryanbr/network-scanner/issues"
|
|
43
44
|
},
|
|
44
|
-
"homepage": "https://github.com/ryanbr/network-scanner"
|
|
45
|
+
"homepage": "https://github.com/ryanbr/network-scanner",
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"eslint": "^9.32.0",
|
|
48
|
+
"globals": "^16.3.0"
|
|
49
|
+
}
|
|
45
50
|
}
|