spot: more fixes for debugger approach, check settings before enabling network

This commit is contained in:
nick-delirium 2025-01-15 11:20:18 +01:00 committed by Delirium
parent f59a8c24f4
commit a371c79151
3 changed files with 95 additions and 93 deletions

View file

@ -8,9 +8,9 @@ import { mergeRequests, SpotNetworkRequest } from "~/utils/networkTrackingUtils"
import { safeApiUrl } from '~/utils/smallUtils'
import {
attachDebuggerToTab,
detachDebuggerFromTab,
stopDebugger,
getRequests as getDebuggerRequests,
resetMap
resetMap,
} from "~/utils/networkDebuggerTracking";
import { messages } from '~/utils/messages'
@ -299,12 +299,6 @@ export default defineBackground(() => {
if (active) {
recordingState.activeTabId = active.id;
}
if (settings.useDebugger) {
resetMap();
void attachDebuggerToTab(active.id);
} else {
startTrackingNetwork();
}
void sendToActiveTab({
type: "content:mount",
area: request.area,
@ -323,13 +317,6 @@ export default defineBackground(() => {
mic: request.mic,
audioId: request.selectedAudioDevice,
audioPerm: request.permissions ? (request.mic ? 2 : 1) : 0,
}, (tabId) => {
if (settings.useDebugger) {
resetMap();
void attachDebuggerToTab(tabId);
} else {
startTrackingNetwork();
}
});
}
}
@ -349,6 +336,24 @@ export default defineBackground(() => {
finalVideoBase64 = "";
const recArea = request.area;
finalSpotObj.startTs = Date.now();
if (settings.networkLogs) {
if (settings.useDebugger) {
resetMap();
browser.tabs.query({
active: true,
currentWindow: true,
}).then((tabs) => {
if (tabs.length === 0) {
return console.error("No active tab found");
}
recordingState.activeTabId = tabs[0].id;
void attachDebuggerToTab(recordingState.activeTabId)
})
} else {
console.log(settings.useDebugger, 'tab', recordingState.activeTabId)
startTrackingNetwork();
}
}
if (recArea === "tab") {
function signalTabRecording() {
recordingState = {
@ -632,20 +637,22 @@ export default defineBackground(() => {
if (recordingState.recording === REC_STATE.stopped) {
return console.error("Calling stopped recording?");
}
let networkRequests;
let mappedNetwork;
if (settings.useDebugger && recordingState.area === "tab") {
void detachDebuggerFromTab(recordingState.activeTabId);
mappedNetwork = getDebuggerRequests();
} else {
networkRequests = getFinalRequests(
recordingState.activeTabId ?? false,
);
stopTrackingNetwork();
mappedNetwork = mergeRequests(
networkRequests,
injectNetworkRequests,
);
let networkRequests: any = [];
let mappedNetwork: any = [];
if (settings.networkLogs) {
if (settings.useDebugger) {
stopDebugger();
mappedNetwork = getDebuggerRequests();
} else {
networkRequests = getFinalRequests(
recordingState.area === 'tab' ? recordingState.activeTabId! : undefined,
);
stopTrackingNetwork();
mappedNetwork = mergeRequests(
networkRequests,
injectNetworkRequests,
);
}
}
injectNetworkRequests = [];
finalSpotObj.network = mappedNetwork;
@ -1099,7 +1106,6 @@ export default defineBackground(() => {
stopTabActivationListening();
}
if (tabId !== previousTab) {
detachDebuggerFromTab(previousTab)
browser.runtime
.sendMessage({
type: messages.offscreen.to.checkRecStatus,

View file

@ -11,6 +11,7 @@
"lib": ["es2022", "DOM"],
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "solid-js"
}
"jsxImportSource": "solid-js",
"noImplicitAny": false,
},
}

View file

@ -1,54 +1,63 @@
let requestMap = {}
let requestMaps = {};
const potentialActiveTabs: Array<string | number> = [];
export function resetMap() {
requestMap = {}
export function resetMap(tabId?: string) {
if (tabId) delete requestMaps[tabId];
else requestMaps = {};
}
export async function attachDebuggerToTab(tabId: string | number) {
if (requestMaps[tabId] && potentialActiveTabs.includes(tabId)) return;
await new Promise((resolve, reject) => {
chrome.debugger.attach({ tabId }, "1.3", () => {
if (chrome.runtime.lastError)
return reject(chrome.runtime.lastError.message);
if (chrome.runtime.lastError) return reject(chrome.runtime.lastError.message);
if (!requestMaps[tabId]) requestMaps[tabId] = {};
potentialActiveTabs.push(tabId);
chrome.debugger.sendCommand({ tabId }, "Network.enable", {}, resolve);
});
chrome.debugger.onEvent.addListener(handleRequestIntercept);
});
}
export async function detachDebuggerFromTab(tabId: string) {
return new Promise((resolve, reject) => {
chrome.debugger.detach({ tabId }, resolve);
chrome.debugger.onEvent.removeListener(handleRequestIntercept);
});
export function stopDebugger(tabId?: string | number) {
if (tabId) {
chrome.debugger.detach({ tabId });
const index = potentialActiveTabs.indexOf(tabId);
if (index > -1) potentialActiveTabs.splice(index, 1);
} else {
potentialActiveTabs.forEach((tabId) => {
chrome.debugger.detach({ tabId });
});
potentialActiveTabs.length = 0;
}
}
const getType = (requestType: string) => {
switch (requestType) {
case "Fetch":
case "XHR":
switch (requestType.toLowerCase()) {
case "fetch":
case "xhr":
case "xmlhttprequest":
return 'xmlhttprequest'
default:
return requestType
}
}
function handleRequestIntercept(source, method, params) {
if (!source.tabId) return; // Not our target tab
if (!params.request) return; // No request object
if (params.request.method === "OPTIONS") return; // Ignore preflight requests
if (!source.tabId) return;
const tabId = source.tabId;
if (!requestMaps[tabId]) return;
if (params.request && params.request.method === "OPTIONS") return;
const reqId = `${tabId}_${params.requestId}`;
switch (method) {
case "Network.requestWillBeSent":
const reqType = params.type ? getType(params.type) : "resource";
if (reqType !== "xmlhttprequest") {
console.log(params);
}
requestMap[params.requestId] = {
requestMaps[tabId][reqId] = {
encodedBodySize: 0,
responseBodySize: 0,
duration: 0,
method: params.request.method,
type: reqType,
type: params.type ? getType(params.type) : "resource",
statusCode: 0,
url: params.request.url,
body: params.request.postData || "",
@ -57,54 +66,40 @@ function handleRequestIntercept(source, method, params) {
requestHeaders: params.request.headers || {},
responseHeaders: {},
timestamp: Date.now(),
time: Date.now(),
};
break;
case "Network.responseReceived":
if (!requestMap[params.requestId]) return;
requestMap[params.requestId].statusCode = params.response.status;
requestMap[params.requestId].responseHeaders =
params.response.headers || {};
// fromDiskCache or fromServiceWorker if available
if (params.response.fromDiskCache)
requestMap[params.requestId].fromCache = true;
if (!requestMaps[tabId][reqId]) return;
requestMaps[tabId][reqId].statusCode = params.response.status;
requestMaps[tabId][reqId].responseHeaders = params.response.headers || {};
if (params.response.fromDiskCache) requestMaps[tabId][reqId].fromCache = true;
break;
case "Network.dataReceived":
if (!requestMap[params.requestId]) return;
requestMap[params.requestId].encodedBodySize += params.dataLength;
// There's no direct content-encoding size from debugger
if (!requestMaps[tabId][reqId]) return;
requestMaps[tabId][reqId].encodedBodySize += params.dataLength;
break;
case "Network.loadingFinished":
if (!requestMap[params.requestId]) return;
requestMap[params.requestId].duration =
Date.now() - requestMap[params.requestId].time;
requestMap[params.requestId].responseBodySize =
requestMap[params.requestId].encodedBodySize;
chrome.debugger.sendCommand(
{ tabId: source.tabId },
"Network.getResponseBody",
{ requestId: params.requestId },
(res) => {
if (!res || res.error) {
requestMap[params.requestId].error = res?.error || "Unknown";
} else {
requestMap[params.requestId].responseBody = res.base64Encoded
? atob(res.body)
: res.body;
}
},
);
if (!requestMaps[tabId][reqId]) return;
requestMaps[tabId][reqId].duration = Date.now() - requestMaps[tabId][reqId].timestamp;
requestMaps[tabId][reqId].responseBodySize = requestMaps[tabId][reqId].encodedBodySize;
chrome.debugger.sendCommand({ tabId }, "Network.getResponseBody", { requestId: params.requestId }, (res) => {
if (!res || res.error) {
requestMaps[tabId][reqId].error = res?.error || "Unknown";
} else {
requestMaps[tabId][reqId].responseBody = res.base64Encoded ? 'base64 payload' : res.body;
}
});
break;
case "Network.loadingFailed":
if (!requestMap[params.requestId]) return;
requestMap[params.requestId].error = params.errorText || "Unknown";
if (!requestMaps[tabId][reqId]) return;
requestMaps[tabId][reqId].error = params.errorText || "Unknown";
break;
}
}
export const getRequests = () => {
return Object.values(requestMap);
};
export function getRequests(tabId?: string) {
if (tabId) {
return Object.values(requestMaps[tabId] || {});
}
}