cdp-tunnel 2.5.22 → 2.6.1
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.
|
@@ -422,51 +422,51 @@ function checkTabVisibility(tabId) {
|
|
|
422
422
|
|
|
423
423
|
var isCDPCreated = State.isCDPCreatedTab(tabId);
|
|
424
424
|
var isOwnedByClient = isCDPCreated && State.getClientIdByTabId(tabId) === clientId;
|
|
425
|
+
var otherClientOwns = isCDPCreated && !isOwnedByClient;
|
|
425
426
|
|
|
426
|
-
if (
|
|
427
|
-
Logger.info('[CDP] Skipping
|
|
427
|
+
if (otherClientOwns) {
|
|
428
|
+
Logger.info('[CDP] Skipping other-client tab:', targetId, 'tabId:', tabId);
|
|
428
429
|
State.addEmittedTarget(targetId);
|
|
429
430
|
return;
|
|
430
431
|
}
|
|
431
432
|
|
|
432
433
|
State.addEmittedTarget(targetId);
|
|
433
434
|
var targetInfo = LocalHandler.mapToTargetInfo(target);
|
|
435
|
+
var isPreExisting = !isCDPCreated;
|
|
434
436
|
|
|
435
|
-
Logger.info('[CDP] Emitting
|
|
437
|
+
Logger.info('[CDP] Emitting target:', targetId, 'tabId:', tabId, 'preExisting:', isPreExisting);
|
|
436
438
|
|
|
437
439
|
EventBuilder.send('Target.targetCreated', { targetInfo: targetInfo });
|
|
438
440
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
State.mapSession(sessionId, tabId, targetId);
|
|
441
|
+
var attachLogic = function(attached) {
|
|
442
|
+
var sessionId = CDPUtils.generateSessionId();
|
|
443
|
+
State.mapSession(sessionId, tabId, targetId);
|
|
443
444
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
445
|
+
if (isPreExisting && clientId) {
|
|
446
|
+
State.setTabIdToClientId(tabId, clientId);
|
|
447
|
+
}
|
|
448
|
+
if (isPreExisting) {
|
|
449
|
+
State.addPreExistingTab(tabId);
|
|
450
|
+
}
|
|
447
451
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
452
|
+
if (config.waitForDebuggerOnStart) {
|
|
453
|
+
State.addPendingDebuggerTab(tabId);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
EventBuilder.send('Target.attachedToTarget', {
|
|
457
|
+
sessionId: sessionId,
|
|
458
|
+
targetInfo: Object.assign({}, targetInfo, { attached: true }),
|
|
459
|
+
waitingForDebugger: config.waitForDebuggerOnStart || false
|
|
460
|
+
});
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
if (target.attached) {
|
|
464
|
+
promises.push(Promise.resolve().then(function() { attachLogic(true); }));
|
|
454
465
|
} else {
|
|
455
466
|
promises.push(
|
|
456
467
|
DebuggerManager.attach(tabId).then(function(attached) {
|
|
457
468
|
if (!attached) return;
|
|
458
|
-
|
|
459
|
-
State.mapSession(sessionId, tabId, targetId);
|
|
460
|
-
|
|
461
|
-
if (config.waitForDebuggerOnStart) {
|
|
462
|
-
State.addPendingDebuggerTab(tabId);
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
EventBuilder.send('Target.attachedToTarget', {
|
|
466
|
-
sessionId: sessionId,
|
|
467
|
-
targetInfo: Object.assign({}, targetInfo, { attached: true }),
|
|
468
|
-
waitingForDebugger: config.waitForDebuggerOnStart || false
|
|
469
|
-
});
|
|
469
|
+
attachLogic(attached);
|
|
470
470
|
})
|
|
471
471
|
);
|
|
472
472
|
}
|
|
@@ -33,25 +33,12 @@ var DebuggerManager = (function() {
|
|
|
33
33
|
if (tagName.toLowerCase() === 'iframe') {
|
|
34
34
|
var originalSetAttribute = element.setAttribute;
|
|
35
35
|
element.setAttribute = function(name, value) {
|
|
36
|
-
if (name.toLowerCase() === 'src' && isInternalUrl(value)) {
|
|
36
|
+
if (name.toLowerCase() === 'src' && isInternalUrl(String(value || ''))) {
|
|
37
37
|
console.warn('[CDP-BLOCK] Blocked iframe src:', value);
|
|
38
|
-
return;
|
|
38
|
+
return element;
|
|
39
39
|
}
|
|
40
40
|
return originalSetAttribute.call(this, name, value);
|
|
41
41
|
};
|
|
42
|
-
|
|
43
|
-
Object.defineProperty(element, 'src', {
|
|
44
|
-
set: function(value) {
|
|
45
|
-
if (isInternalUrl(value)) {
|
|
46
|
-
console.warn('[CDP-BLOCK] Blocked iframe src via property:', value);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
originalSetAttribute.call(this, 'src', value);
|
|
50
|
-
},
|
|
51
|
-
get: function() {
|
|
52
|
-
return element.getAttribute('src');
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
42
|
}
|
|
56
43
|
return element;
|
|
57
44
|
};
|
|
@@ -68,18 +55,25 @@ var DebuggerManager = (function() {
|
|
|
68
55
|
|
|
69
56
|
// 拦截 location 修改
|
|
70
57
|
var locationDescriptor = Object.getOwnPropertyDescriptor(window, 'location');
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
58
|
+
if (locationDescriptor && typeof locationDescriptor.set === 'function') {
|
|
59
|
+
try {
|
|
60
|
+
Object.defineProperty(window, 'location', {
|
|
61
|
+
set: function(value) {
|
|
62
|
+
if (isInternalUrl(String(value))) {
|
|
63
|
+
console.warn('[CDP-BLOCK] Blocked location change:', value);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
locationDescriptor.set.call(window, value);
|
|
67
|
+
},
|
|
68
|
+
get: function() {
|
|
69
|
+
return locationDescriptor.get.call(window);
|
|
70
|
+
},
|
|
71
|
+
configurable: true
|
|
72
|
+
});
|
|
73
|
+
} catch(e) {
|
|
74
|
+
// location property cannot be redefined on some contexts, skip silently
|
|
81
75
|
}
|
|
82
|
-
}
|
|
76
|
+
}
|
|
83
77
|
|
|
84
78
|
console.log('[CDP-BLOCK] Internal URL block script injected');
|
|
85
79
|
})();
|
|
@@ -222,17 +216,22 @@ var DebuggerManager = (function() {
|
|
|
222
216
|
return;
|
|
223
217
|
}
|
|
224
218
|
|
|
225
|
-
//
|
|
219
|
+
// 在新的执行上下文中也注入拦截脚本(data: URL 上下文跳过,避免干扰导航)
|
|
226
220
|
if (isDefaultContext) {
|
|
227
|
-
chrome.
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
221
|
+
chrome.tabs.get(source.tabId, function(tab) {
|
|
222
|
+
if (chrome.runtime.lastError) return;
|
|
223
|
+
var tabUrl = tab ? (tab.url || tab.pendingUrl || '') : '';
|
|
224
|
+
if (tabUrl.startsWith('data:')) return;
|
|
225
|
+
chrome.debugger.sendCommand(
|
|
226
|
+
{ tabId: source.tabId },
|
|
227
|
+
'Runtime.evaluate',
|
|
228
|
+
{
|
|
229
|
+
expression: INTERNAL_URL_BLOCK_SCRIPT,
|
|
230
|
+
contextId: context.id,
|
|
231
|
+
runImmediately: true
|
|
232
|
+
}
|
|
233
|
+
).catch(function() {});
|
|
234
|
+
});
|
|
236
235
|
}
|
|
237
236
|
}
|
|
238
237
|
|
package/package.json
CHANGED
package/server/proxy-server.js
CHANGED
|
@@ -167,6 +167,7 @@ class PluginNamespace {
|
|
|
167
167
|
this.cachedTargets = [];
|
|
168
168
|
this.lastTargetsUpdate = 0;
|
|
169
169
|
this.cachedBrowserVersion = null;
|
|
170
|
+
this.discoveringClientIds = new Map();
|
|
170
171
|
}
|
|
171
172
|
}
|
|
172
173
|
|
|
@@ -505,6 +506,7 @@ function cleanupClient(ws, id, reason) {
|
|
|
505
506
|
if (ns.clientIdToBrowserContext.has(id)) {
|
|
506
507
|
ns.clientIdToBrowserContext.delete(id);
|
|
507
508
|
}
|
|
509
|
+
ns.discoveringClientIds.delete(id);
|
|
508
510
|
}
|
|
509
511
|
for (const [gId, mapping] of globalRequestIdMap.entries()) {
|
|
510
512
|
if (mapping.clientId === id) globalRequestIdMap.delete(gId);
|
|
@@ -787,8 +789,27 @@ function handlePluginConnection(ws, clientInfo, request) {
|
|
|
787
789
|
}
|
|
788
790
|
} else if (targetId && (parsed.method === 'Target.targetCreated' || parsed.method === 'Target.attachedToTarget')) {
|
|
789
791
|
const pendingMap = parsed.method === 'Target.targetCreated' ? ns.pendingTargetCreatedEvents : ns.pendingAttachedEvents;
|
|
790
|
-
|
|
791
|
-
|
|
792
|
+
|
|
793
|
+
let routedToDiscoverer = false;
|
|
794
|
+
if (ns.discoveringClientIds.size > 0) {
|
|
795
|
+
for (const [discClientId, timestamp] of ns.discoveringClientIds) {
|
|
796
|
+
if (Date.now() - timestamp < 30000) {
|
|
797
|
+
const discWs = clientById.get(discClientId);
|
|
798
|
+
if (discWs && discWs.readyState === WebSocket.OPEN) {
|
|
799
|
+
discWs.send(cdpData);
|
|
800
|
+
console.log(`[TARGET EVENT DISCOVERED] ${parsed.method} targetId=${targetId?.substring(0,8)} -> discovering client=${discClientId}`);
|
|
801
|
+
routedToDiscoverer = true;
|
|
802
|
+
}
|
|
803
|
+
} else {
|
|
804
|
+
ns.discoveringClientIds.delete(discClientId);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
if (!routedToDiscoverer) {
|
|
810
|
+
pendingMap.set(targetId, { parsed: JSON.parse(JSON.stringify(parsed)), cdpData });
|
|
811
|
+
console.log(`[TARGET EVENT PENDING] ${parsed.method} targetId=${targetId?.substring(0,8)} (cached, waiting for createTarget response)`);
|
|
812
|
+
}
|
|
792
813
|
} else {
|
|
793
814
|
console.log(`[TARGET EVENT DROPPED] ${parsed.method} targetId=${targetId?.substring(0,8) || 'none'} (no owner, dropped for isolation)`);
|
|
794
815
|
}
|
|
@@ -905,9 +926,11 @@ function handlePluginConnection(ws, clientInfo, request) {
|
|
|
905
926
|
}
|
|
906
927
|
if (mapping.isGetTargets && parsed.result && parsed.result.targetInfos) {
|
|
907
928
|
const clientId = mapping.clientId;
|
|
929
|
+
const pluginWsForGetTargets = ws;
|
|
908
930
|
parsed.result.targetInfos = parsed.result.targetInfos.filter(t => {
|
|
909
931
|
if (t.type !== 'page') return true;
|
|
910
932
|
const ownerClient = ns.targetIdToClientId.get(t.targetId);
|
|
933
|
+
if (!ownerClient) return true;
|
|
911
934
|
return ownerClient === clientId;
|
|
912
935
|
});
|
|
913
936
|
console.log(`[GET TARGETS FILTERED] client=${clientId} returned ${parsed.result.targetInfos.filter(t => t.type === 'page').length} page targets`);
|
|
@@ -1218,6 +1241,14 @@ function handleClientConnection(ws, clientInfo, customClientId = null, targetPlu
|
|
|
1218
1241
|
}
|
|
1219
1242
|
}
|
|
1220
1243
|
|
|
1244
|
+
if (parsed && (parsed.method === 'Target.setDiscoverTargets' || parsed.method === 'Target.setAutoAttach')) {
|
|
1245
|
+
const ns = ws.pairedPlugin ? getNamespace(ws.pairedPlugin) : null;
|
|
1246
|
+
if (ns) {
|
|
1247
|
+
ns.discoveringClientIds.set(id, Date.now());
|
|
1248
|
+
console.log(`[DISCOVERING] client=${id} method=${parsed.method}`);
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1221
1252
|
if (parsed && parsed.method === 'Browser.close') {
|
|
1222
1253
|
if (shouldLog('info')) {
|
|
1223
1254
|
console.log(`\n[BROWSER CLOSE] Client ${id} requested Browser.close, forwarding to plugin`);
|