Add possibility to generate a trimmed HAR file
This commit is contained in:
parent
399b5eca9d
commit
a859d0239f
|
@ -1,25 +1,42 @@
|
|||
import { StolenDataEntry } from "./stolen-data-entry";
|
||||
import { getshorthost, parseCookie, Request } from "./util";
|
||||
|
||||
type NameValue = { name: string; value: string };
|
||||
|
||||
export type HAREntry = {
|
||||
pageref: string;
|
||||
startedDateTime: string;
|
||||
request: {
|
||||
bodySize: number;
|
||||
cookies: {}[];
|
||||
headers: {}[];
|
||||
cookies: NameValue[];
|
||||
headers: NameValue[];
|
||||
headersSize: number;
|
||||
httpVersion: string;
|
||||
method: string;
|
||||
postData: {
|
||||
postData?: {
|
||||
mimeType: string;
|
||||
params: { name: string; value: string }[];
|
||||
params: NameValue[];
|
||||
text: string;
|
||||
};
|
||||
queryString: { name: string; value: string }[];
|
||||
queryString: NameValue[];
|
||||
url: string;
|
||||
};
|
||||
response: {}; // not relevant
|
||||
response: {
|
||||
status: number;
|
||||
statusText: string;
|
||||
httpVersion: string;
|
||||
headers: NameValue[];
|
||||
cookies: NameValue[];
|
||||
content: {
|
||||
mimeType: string;
|
||||
size: number;
|
||||
encoding: "base64";
|
||||
text: string;
|
||||
};
|
||||
redirectURL: "";
|
||||
headersSize: number;
|
||||
bodySize: number;
|
||||
}; // not relevant
|
||||
cache: {};
|
||||
timings: {};
|
||||
time: number;
|
||||
|
@ -48,6 +65,13 @@ export default class ExtendedRequest {
|
|||
public initialized = false;
|
||||
public stolenData: StolenDataEntry[];
|
||||
|
||||
constructor(public data: Request) {
|
||||
this.tabId = data.tabId;
|
||||
this.url = data.url;
|
||||
this.requestHeaders = data.requestHeaders;
|
||||
this.shorthost = getshorthost(data.url);
|
||||
}
|
||||
|
||||
async init() {
|
||||
await this.cacheOrigin();
|
||||
this.initialized = true;
|
||||
|
@ -67,6 +91,8 @@ export default class ExtendedRequest {
|
|||
);
|
||||
if (headers.Referer) {
|
||||
url = headers.Referer;
|
||||
} else {
|
||||
url = this.data.url;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,8 +116,10 @@ export default class ExtendedRequest {
|
|||
}
|
||||
|
||||
getReferer() {
|
||||
return this.data.requestHeaders.filter((h) => h.name === "Referer")[0]
|
||||
.value;
|
||||
return (
|
||||
this.data.requestHeaders.filter((h) => h.name === "Referer")?.[0].value ||
|
||||
"missing-referrer"
|
||||
);
|
||||
}
|
||||
|
||||
exposesOrigin() {
|
||||
|
@ -180,13 +208,6 @@ export default class ExtendedRequest {
|
|||
);
|
||||
}
|
||||
|
||||
constructor(public data: Request) {
|
||||
this.tabId = data.tabId;
|
||||
this.url = data.url;
|
||||
this.requestHeaders = data.requestHeaders;
|
||||
this.shorthost = getshorthost(data.url);
|
||||
}
|
||||
|
||||
hasMark() {
|
||||
return this.stolenData.some((data) => data.hasMark());
|
||||
}
|
||||
|
@ -204,4 +225,57 @@ export default class ExtendedRequest {
|
|||
const hrq = har.request;
|
||||
return rq.url == hrq.url;
|
||||
}
|
||||
|
||||
toHAR(): HAREntry {
|
||||
return {
|
||||
pageref: "page_1",
|
||||
startedDateTime: `${new Date().toJSON().replace("Z", "+01:00")}`,
|
||||
request: {
|
||||
bodySize: 0,
|
||||
method: this.data.method,
|
||||
url: this.data.url,
|
||||
headersSize: 100,
|
||||
httpVersion: "HTTP/2",
|
||||
headers: this.data.requestHeaders as NameValue[],
|
||||
cookies: this.getCookieData().map((cookie) => ({
|
||||
name: cookie.name,
|
||||
value: cookie.value,
|
||||
})),
|
||||
queryString: this.getQueryParams().map((param) => ({
|
||||
name: param.name,
|
||||
value: param.value,
|
||||
})),
|
||||
},
|
||||
response: {
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
httpVersion: "HTTP/2",
|
||||
headers: [],
|
||||
cookies: [],
|
||||
content: {
|
||||
mimeType: "text/plain",
|
||||
size: 15,
|
||||
encoding: "base64",
|
||||
text: "ZG9lc24ndCBtYXR0ZXIK",
|
||||
},
|
||||
redirectURL: "",
|
||||
headersSize: 15,
|
||||
bodySize: 15,
|
||||
},
|
||||
cache: {},
|
||||
timings: {
|
||||
blocked: -1,
|
||||
dns: 0,
|
||||
connect: 0,
|
||||
ssl: 0,
|
||||
send: 0,
|
||||
wait: 79,
|
||||
receive: 0,
|
||||
},
|
||||
time: 79,
|
||||
_securityState: "secure",
|
||||
serverIPAddress: "31.13.92.36",
|
||||
connection: "443",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ export default function DomainSummary({
|
|||
<li>
|
||||
Właściciel domeny <strong>{cluster.id}</strong> otrzymał:{" "}
|
||||
<ul>
|
||||
<li>Mój adres IP</li>
|
||||
{cluster
|
||||
.getMarkedEntries()
|
||||
.sort((entryA, entryB) => (entryA.value > entryB.value ? -1 : 1))
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import React, { useState } from "react";
|
||||
import { HAREntry } from "../extended-request";
|
||||
import { StolenDataEntry } from "../stolen-data-entry";
|
||||
import { getshorthost, unique } from "../util";
|
||||
|
||||
function handleNewFile(
|
||||
element: HTMLInputElement,
|
||||
marked_entries: StolenDataEntry[],
|
||||
setFiltered: (Blob) => void
|
||||
) {
|
||||
): void {
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener("load", () => {
|
||||
const content = JSON.parse(reader.result as string);
|
||||
|
@ -22,6 +23,35 @@ function handleNewFile(
|
|||
reader.readAsText(element.files[0]);
|
||||
}
|
||||
|
||||
function generateFakeHAR(marked_entries: StolenDataEntry[]) {
|
||||
const requests = marked_entries.map((entry) => entry.request);
|
||||
return {
|
||||
log: {
|
||||
version: "1.2",
|
||||
creator: {
|
||||
name: "Firefox",
|
||||
version: "94.0",
|
||||
},
|
||||
browser: {
|
||||
name: "Firefox",
|
||||
version: "94.0",
|
||||
},
|
||||
pages: [
|
||||
{
|
||||
startedDateTime: "2021-11-08T20:27:23.195+01:00",
|
||||
id: "page_1",
|
||||
title: "HAR DUmp",
|
||||
pageTimings: {
|
||||
onContentLoad: 467,
|
||||
onLoad: 4226,
|
||||
},
|
||||
},
|
||||
],
|
||||
entries: unique(requests).map((r) => r.toHAR()),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default function HARConverter({
|
||||
marked_entries,
|
||||
}: {
|
||||
|
@ -29,6 +59,7 @@ export default function HARConverter({
|
|||
}) {
|
||||
const [filtered, setFiltered] = useState<Blob | null>(null);
|
||||
const [filename, setFilename] = useState("");
|
||||
const fakeHAR = generateFakeHAR(marked_entries);
|
||||
return (
|
||||
<div>
|
||||
<input
|
||||
|
@ -48,6 +79,16 @@ export default function HARConverter({
|
|||
</a>
|
||||
)) ||
|
||||
null}
|
||||
<a
|
||||
href={URL.createObjectURL(
|
||||
new Blob([JSON.stringify(fakeHAR)], { type: "application/json" })
|
||||
)}
|
||||
download={`${getshorthost(
|
||||
marked_entries[0].request.originalURL
|
||||
)}-${new Date().toJSON()}-faked.har`}
|
||||
>
|
||||
Pobierz "zfałszowany" HAR
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
32
util.ts
32
util.ts
|
@ -6,9 +6,31 @@ export type Unpromisify<T> = T extends Promise<infer R> ? R : T;
|
|||
export type Unarray<T> = T extends Array<infer R> ? R : T;
|
||||
|
||||
export type Tab = Unarray<Unpromisify<ReturnType<typeof browser.tabs.query>>>;
|
||||
export type Request = Parameters<
|
||||
Parameters<typeof browser.webRequest.onBeforeSendHeaders.addListener>[0]
|
||||
>[0];
|
||||
export type Request = {
|
||||
cookieStoreId?: string;
|
||||
documentUrl?: string; // RL of the document in which the resource will be loaded. For example, if the web page at "https://example.com" contains an image or an iframe, then the documentUrl for the image or iframe will be "https://example.com". For a top-level document, documentUrl is undefined.
|
||||
frameId: number;
|
||||
incognito?: boolean;
|
||||
method: string;
|
||||
originUrl: string;
|
||||
parentFrameId: number;
|
||||
proxyInfo?: {
|
||||
host: string;
|
||||
port: number;
|
||||
type: string;
|
||||
username: string;
|
||||
proxyDNS: boolean;
|
||||
failoverTimeout: number;
|
||||
};
|
||||
requestHeaders?: { name: string; value?: string; binaryValue?: number[] }[];
|
||||
requestId: string;
|
||||
tabId: number;
|
||||
thirdParty?: boolean;
|
||||
timeStamp: number;
|
||||
type: string;
|
||||
url: string; // the target of the request;
|
||||
urlClassification?: { firstParty: string[]; thirdParty: string[] };
|
||||
};
|
||||
|
||||
export function getshorthost(host: string) {
|
||||
return host
|
||||
|
@ -83,8 +105,8 @@ export function hyphenate(str: string): string {
|
|||
return str.replace(/[_\[A-Z]/g, `${String.fromCharCode(173)}$&`);
|
||||
}
|
||||
|
||||
export function unique(array: string[]) {
|
||||
return Array.from(new Set(array));
|
||||
export function unique<T>(array: T[]): Array<T> {
|
||||
return Array.from(new Set<T>(array));
|
||||
}
|
||||
|
||||
export function allSubhosts(host: string) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user