2022-01-29 20:01:45 +00:00
|
|
|
import { Platform } from "./platform";
|
|
|
|
|
|
|
|
const obj = execution_mode == "chrome_api" ? chrome : browser;
|
|
|
|
type Methods<T> = {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
|
|
[k in Exclude<keyof T, 'prototype'>]: T[k] extends Function ? T[k] : never;
|
|
|
|
};
|
|
|
|
|
2022-05-02 19:07:24 +00:00
|
|
|
const types = [
|
|
|
|
"csp_report",
|
|
|
|
"font",
|
|
|
|
"image",
|
|
|
|
"main_frame",
|
|
|
|
"media",
|
|
|
|
"object",
|
|
|
|
"other",
|
|
|
|
"ping",
|
|
|
|
"script",
|
|
|
|
"stylesheet",
|
|
|
|
"sub_frame",
|
|
|
|
"websocket",
|
|
|
|
"xmlhttprequest"
|
|
|
|
] as browser.webRequest.ResourceType[];
|
2022-05-04 03:21:53 +00:00
|
|
|
|
2022-05-02 19:07:24 +00:00
|
|
|
const filts = {
|
|
|
|
urls: ["https://boards.4channel.org/*",
|
|
|
|
"https://boards.4chan.org/*",
|
|
|
|
"https://desuarchive.org/*",
|
|
|
|
"https://archived.moe/*",
|
|
|
|
"https://archive.nyafuu.org/*",
|
|
|
|
"https://arch.b4k.co/*",
|
|
|
|
"https://archive.wakarimasen.moe/*",
|
|
|
|
"https://fireden.net/*",
|
|
|
|
"https://thebarchive.com/*",
|
|
|
|
"https://files.catbox.moe/*",
|
|
|
|
"https://de.catbox.moe/*",
|
|
|
|
"https://based.coom.tech/*",
|
|
|
|
"https://archiveofsins.com/*"],
|
2022-05-04 03:21:53 +00:00
|
|
|
types: ["main_frame", "sub_frame", "csp_report", "object", "other", "ping"] as browser.webRequest.ResourceType[]
|
2022-05-02 19:07:24 +00:00
|
|
|
};
|
2022-05-04 03:21:53 +00:00
|
|
|
|
|
|
|
if (manifest == 2)
|
|
|
|
obj.webRequest.onHeadersReceived.addListener(details => {
|
|
|
|
if (details.url.startsWith('https://arch.b4k.co/') && details.type == "main_frame") {
|
|
|
|
const e = details.responseHeaders!.findIndex(e => e.name.toLowerCase() == "content-security-policy");
|
|
|
|
if (e >= 0)
|
|
|
|
details.responseHeaders![e].value = "";
|
|
|
|
return {
|
|
|
|
responseHeaders: [
|
|
|
|
...details.responseHeaders!,
|
|
|
|
{ name: 'access-control-allow-origin', value: '*' }
|
|
|
|
]
|
|
|
|
} as browser.webRequest.BlockingResponse;
|
|
|
|
}
|
|
|
|
}, filts, ['blocking', 'responseHeaders', ...(execution_mode == "chrome_api" ? ['extraHeaders' as 'blocking'] : [])]);
|
2022-05-02 19:07:24 +00:00
|
|
|
|
2022-07-18 18:57:26 +00:00
|
|
|
async function bravedeserialize(src: any): Promise<any> {
|
|
|
|
if (typeof src != "object")
|
|
|
|
return src;
|
|
|
|
switch (src.cls) {
|
|
|
|
case 'FormData': {
|
|
|
|
const ret = new FormData();
|
|
|
|
for (const [key, items] of src.value) {
|
|
|
|
for (const item of items) {
|
|
|
|
ret.append(key, await bravedeserialize(item));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
case 'File': {
|
|
|
|
return new File([src.value], src.name, {
|
|
|
|
lastModified: src.lastModified,
|
|
|
|
type: src.type
|
|
|
|
});
|
|
|
|
}
|
|
|
|
case 'Blob': {
|
|
|
|
return new Blob([src.value], {
|
|
|
|
type: src.type
|
|
|
|
});
|
|
|
|
}
|
|
|
|
case 'Object': {
|
|
|
|
const ret = {} as any;
|
|
|
|
for (const prop in src.value) {
|
|
|
|
ret[prop] = await bravedeserialize(src.value[prop]);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-04 03:21:53 +00:00
|
|
|
const pendingFetches = new Map<MessagePort, { [id in number]: { fetchFully: boolean } }>();
|
2022-05-02 19:07:24 +00:00
|
|
|
|
2022-05-04 03:21:53 +00:00
|
|
|
const bgCorsFetch = async (c: MessagePort, id: number, input: string, init?: RequestInit) => {
|
|
|
|
if (input.startsWith('//')) // firefox??
|
2022-05-02 19:07:24 +00:00
|
|
|
input = 'https:' + input;
|
2022-07-18 18:57:26 +00:00
|
|
|
if (init?.body && execution_mode == "chrome_api") {
|
|
|
|
init.body = await bravedeserialize(init.body);
|
|
|
|
}
|
2022-06-26 19:03:31 +00:00
|
|
|
try {
|
|
|
|
const k = await fetch(input, init);
|
2022-05-02 19:07:24 +00:00
|
|
|
|
2022-06-26 19:03:31 +00:00
|
|
|
let headersStr = '';
|
|
|
|
const headerObj = {} as any;
|
|
|
|
k.headers.forEach((v, k) => {
|
|
|
|
headerObj[k] = v;
|
|
|
|
headersStr += `${k}: ${v}\n`;
|
|
|
|
});
|
|
|
|
c.postMessage({
|
|
|
|
id, setRes: true,
|
|
|
|
ok: k.ok,
|
|
|
|
headers: headerObj,
|
|
|
|
responseHeaders: headersStr,
|
|
|
|
redirected: k.redirected,
|
|
|
|
type: k.type,
|
|
|
|
url: k.url,
|
|
|
|
status: k.status,
|
|
|
|
bodyUsed: k.bodyUsed,
|
|
|
|
statusText: k.statusText,
|
|
|
|
});
|
2022-05-02 19:07:24 +00:00
|
|
|
|
2022-06-26 19:03:31 +00:00
|
|
|
pendingFetches.set(c, {
|
|
|
|
[id]: {
|
|
|
|
fetchFully: false
|
|
|
|
},
|
|
|
|
...(pendingFetches.get(c) || {})
|
|
|
|
});
|
|
|
|
|
|
|
|
let buff: Buffer[] = [];
|
|
|
|
|
|
|
|
const ctotal = +headerObj['content-length'] || 0; // content total
|
|
|
|
let ltotal = 0; // loaded total
|
|
|
|
|
|
|
|
// sequence number, required to reorder messages client-side
|
|
|
|
// if they get processed out of order
|
|
|
|
let s = 0;
|
|
|
|
const e = {
|
|
|
|
write(chunk: Uint8Array) {
|
|
|
|
ltotal += chunk.byteLength;
|
|
|
|
c.postMessage({ id, progress: [ltotal, ctotal] });
|
|
|
|
if (!pendingFetches.get(c)![id].fetchFully) {
|
|
|
|
//const url = new Blob([chunk]);
|
|
|
|
c.postMessage({ id, s: s++, pushData: { data: chunk } }, [chunk.buffer]);
|
|
|
|
} else {
|
|
|
|
buff.push(Buffer.from(chunk));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
close() {
|
|
|
|
if (buff.length > 0) {
|
|
|
|
const chunk = Buffer.concat(buff);
|
|
|
|
c.postMessage({ id, s: s++, pushData: { data: chunk } }, [chunk.buffer]);
|
|
|
|
buff = [];
|
|
|
|
}
|
|
|
|
const obj = pendingFetches.get(c)!;
|
|
|
|
delete obj[id];
|
|
|
|
if (Object.keys(obj).length == 0)
|
|
|
|
pendingFetches.delete(c);
|
|
|
|
c.postMessage({ id, s: s++, pushData: {} });
|
2022-05-02 19:07:24 +00:00
|
|
|
}
|
2022-06-26 19:03:31 +00:00
|
|
|
};
|
|
|
|
const reader = k.body?.getReader();
|
|
|
|
let res: ReadableStreamDefaultReadResult<Uint8Array>;
|
|
|
|
for (; ;) {
|
|
|
|
res = await reader!.read();
|
|
|
|
if (res.done) break;
|
|
|
|
e.write(res.value);
|
2022-05-02 19:07:24 +00:00
|
|
|
}
|
2022-06-26 19:03:31 +00:00
|
|
|
e.close();
|
|
|
|
reader?.releaseLock();
|
2022-07-18 18:57:26 +00:00
|
|
|
} catch (e) {
|
2022-06-26 19:03:31 +00:00
|
|
|
const err = e as Error;
|
|
|
|
c.postMessage({
|
|
|
|
id,
|
|
|
|
setRes: true,
|
|
|
|
ok: false,
|
|
|
|
url: input,
|
|
|
|
status: err.message
|
|
|
|
});
|
2022-05-02 19:07:24 +00:00
|
|
|
}
|
|
|
|
};
|
2022-01-29 20:01:45 +00:00
|
|
|
|
2022-05-04 03:21:53 +00:00
|
|
|
const meself = new URL(obj.runtime.getURL('')).origin;
|
|
|
|
|
|
|
|
const waitConnect = (cb: any) => {
|
|
|
|
window.addEventListener("message", (msg) => {
|
|
|
|
//if (msg.origin === meself) {
|
2022-06-26 19:03:31 +00:00
|
|
|
cb(msg.ports[0]);
|
2022-05-04 03:21:53 +00:00
|
|
|
//}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const onMessage = (c: MessagePort, cb: any) =>
|
|
|
|
c.onmessage = (e) => {
|
|
|
|
cb(e.data);
|
|
|
|
};
|
|
|
|
|
|
|
|
waitConnect((c: any) => {
|
|
|
|
onMessage(c, async (obj: any) => {
|
2022-05-02 19:07:24 +00:00
|
|
|
const { id, name, args, sid, fid, url } = obj as { url?: string, fid?: number, sid?: number, id: number, name: string, args: Parameters<typeof Platform[keyof Methods<typeof Platform>]> };
|
2022-05-04 03:21:53 +00:00
|
|
|
if (name == "keepAlive") {
|
|
|
|
console.log('im alive, tho?');
|
|
|
|
return;
|
|
|
|
}
|
2022-05-02 19:07:24 +00:00
|
|
|
if (name == "abortCorsFetch") {
|
|
|
|
//chrome.runtime.sendMessage({ name, sid });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (name == "corsFetch") {
|
|
|
|
// this handles the reply
|
|
|
|
(bgCorsFetch as any)(c, id, ...args);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (name == "revoke") {
|
|
|
|
URL.revokeObjectURL(url!);
|
|
|
|
c.postMessage({
|
|
|
|
id, ok: 1
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (name == "fullyRead") {
|
|
|
|
const obj = pendingFetches.get(c)!;
|
|
|
|
if (obj && fid! in obj)
|
|
|
|
obj[fid!].fetchFully = true;
|
|
|
|
c.postMessage({
|
|
|
|
id, ok: 1
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const res = await (Platform as any)[name](...args);
|
2022-01-29 20:01:45 +00:00
|
|
|
c.postMessage({
|
|
|
|
id, res
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|