106 lines
3.7 KiB
TypeScript
106 lines
3.7 KiB
TypeScript
let requestMaps = {};
|
|
const potentialActiveTabs: Array<string | number> = [];
|
|
|
|
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}, ${tabId}`);
|
|
if (!requestMaps[tabId]) requestMaps[tabId] = {};
|
|
potentialActiveTabs.push(tabId);
|
|
chrome.debugger.sendCommand({ tabId }, "Network.enable", {}, resolve);
|
|
});
|
|
chrome.debugger.onEvent.addListener(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.toLowerCase()) {
|
|
case "fetch":
|
|
case "xhr":
|
|
case "xmlhttprequest":
|
|
return 'xmlhttprequest'
|
|
default:
|
|
return requestType
|
|
}
|
|
}
|
|
|
|
function handleRequestIntercept(source, method, params) {
|
|
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":
|
|
requestMaps[tabId][reqId] = {
|
|
encodedBodySize: 0,
|
|
responseBodySize: 0,
|
|
duration: 0,
|
|
method: params.request.method,
|
|
type: params.type ? getType(params.type) : "resource",
|
|
statusCode: 0,
|
|
url: params.request.url,
|
|
body: params.request.postData || "",
|
|
responseBody: "",
|
|
fromCache: false,
|
|
requestHeaders: params.request.headers || {},
|
|
responseHeaders: {},
|
|
timestamp: Date.now(),
|
|
time: Date.now(),
|
|
};
|
|
break;
|
|
case "Network.responseReceived":
|
|
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 (!requestMaps[tabId][reqId]) return;
|
|
requestMaps[tabId][reqId].encodedBodySize += params.dataLength;
|
|
break;
|
|
case "Network.loadingFinished":
|
|
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 (!requestMaps[tabId][reqId]) return;
|
|
requestMaps[tabId][reqId].error = params.errorText || "Unknown";
|
|
break;
|
|
}
|
|
}
|
|
|
|
export function getRequests(tabId?: string) {
|
|
if (tabId) {
|
|
return Object.values(requestMaps[tabId] || {});
|
|
}
|
|
return Object.values(requestMaps).reduce((acc, curr) => acc.concat(Object.values(curr)), []);
|
|
}
|