|
|
@@ -25,126 +25,75 @@
|
|
|
|
|
|
this.singlefile.extension.lib.fetch.content.resources = this.singlefile.extension.lib.fetch.content.resources || (() => {
|
|
|
|
|
|
- const MAX_CONTENT_SIZE = 8 * (1024 * 1024);
|
|
|
const FETCH_REQUEST_EVENT = "single-file-request-fetch";
|
|
|
const FETCH_RESPONSE_EVENT = "single-file-response-fetch";
|
|
|
|
|
|
- const pendingRequests = [];
|
|
|
-
|
|
|
browser.runtime.onMessage.addListener(message => {
|
|
|
- if ((message.method == "singlefile.fetchFrameRequest" && window.frameId && window.frameId == message.frameId)
|
|
|
- || message.method == "singlefile.fetchResponse"
|
|
|
- || message.method == "singlefile.fetchFrameResponse") {
|
|
|
+ if (message.method == "singlefile.fetchFrame" && window.frameId && window.frameId == message.frameId) {
|
|
|
return onMessage(message);
|
|
|
}
|
|
|
});
|
|
|
- return {
|
|
|
- fetch: async url => {
|
|
|
- try {
|
|
|
- let response = await fetch(url, { cache: "force-cache" });
|
|
|
- if (response.status == 403 || response.status == 404) {
|
|
|
- response = hostFetch(url);
|
|
|
- }
|
|
|
- return response;
|
|
|
- }
|
|
|
- catch (error) {
|
|
|
- return sendRequest("singlefile.fetchRequest", url);
|
|
|
- }
|
|
|
- },
|
|
|
- frameFetch: (url, frameId) => sendRequest("singlefile.fetchFrameRequest", url, frameId)
|
|
|
- };
|
|
|
|
|
|
async function onMessage(message) {
|
|
|
- if (message.method == "singlefile.fetchFrameRequest") {
|
|
|
- sendFetchFrameResponse(message);
|
|
|
- return {};
|
|
|
- } else if (message.method == "singlefile.fetchResponse" || message.method == "singlefile.fetchFrameResponse") {
|
|
|
- resolveRequest(message);
|
|
|
- return {};
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- async function sendFetchFrameResponse(message) {
|
|
|
- const { id, tabId } = message;
|
|
|
try {
|
|
|
let response = await fetch(message.url, { cache: "force-cache" });
|
|
|
- if (response.status == 403 || response.status == 404) {
|
|
|
+ if (response.status == 403) {
|
|
|
response = hostFetch(message.url);
|
|
|
}
|
|
|
- const array = new Uint8Array(await response.arrayBuffer());
|
|
|
- for (let blockIndex = 0; blockIndex * MAX_CONTENT_SIZE < array.length; blockIndex++) {
|
|
|
- const message = {
|
|
|
- method: "singlefile.bgFetchFrameResponse",
|
|
|
- id,
|
|
|
- tabId
|
|
|
- };
|
|
|
- message.truncated = array.length > MAX_CONTENT_SIZE;
|
|
|
- if (message.truncated) {
|
|
|
- message.finished = (blockIndex + 1) * MAX_CONTENT_SIZE > array.length;
|
|
|
- message.array = array.slice(blockIndex * MAX_CONTENT_SIZE, (blockIndex + 1) * MAX_CONTENT_SIZE);
|
|
|
- } else {
|
|
|
- message.array = array;
|
|
|
- }
|
|
|
- message.array = Array.from(message.array);
|
|
|
- const headers = {};
|
|
|
- response.headers.forEach((value, key) => headers[key] = value);
|
|
|
- if (!message.truncated || message.finished) {
|
|
|
- message.headers = headers;
|
|
|
- message.status = response.status;
|
|
|
- }
|
|
|
- browser.runtime.sendMessage(message);
|
|
|
- }
|
|
|
+ return {
|
|
|
+ status: response.status,
|
|
|
+ headers: [...response.headers],
|
|
|
+ array: Array.from(new Uint8Array(await response.arrayBuffer()))
|
|
|
+ };
|
|
|
} catch (error) {
|
|
|
- await browser.runtime.sendMessage({
|
|
|
- method: "singlefile.bgFetchFrameResponse",
|
|
|
- id: message.id,
|
|
|
- tabId,
|
|
|
+ return {
|
|
|
error: error.toString()
|
|
|
- });
|
|
|
+ };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- function resolveRequest(message) {
|
|
|
- const pendingRequest = pendingRequests[message.id];
|
|
|
- if (pendingRequest) {
|
|
|
- if (message.error) {
|
|
|
- pendingRequest.reject(new Error(message.error.toString()));
|
|
|
- pendingRequests[message.id] = null;
|
|
|
- } else {
|
|
|
- if (message.truncated) {
|
|
|
- if (!pendingRequest.responseArray) {
|
|
|
- pendingRequest.responseArray = [];
|
|
|
- }
|
|
|
- pendingRequest.responseArray = pendingRequest.responseArray.concat(message.array);
|
|
|
- } else {
|
|
|
- pendingRequest.responseArray = message.array;
|
|
|
- }
|
|
|
- if (!message.truncated || message.finished) {
|
|
|
- pendingRequest.resolve({
|
|
|
- status: message.status,
|
|
|
- headers: {
|
|
|
- get: headerName => message.headers[headerName]
|
|
|
- },
|
|
|
- arrayBuffer: async () => new Uint8Array(pendingRequest.responseArray).buffer
|
|
|
- });
|
|
|
- pendingRequests[message.id] = null;
|
|
|
+ return {
|
|
|
+ fetch: async url => {
|
|
|
+ try {
|
|
|
+ let response = await fetch(url, { cache: "force-cache" });
|
|
|
+ if (response.status == 403 || response.status == 404) {
|
|
|
+ response = hostFetch(url);
|
|
|
}
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+ catch (error) {
|
|
|
+ const response = await sendMessage({ method: "singlefile.fetch", url });
|
|
|
+ return {
|
|
|
+ status: response.status,
|
|
|
+ headers: { get: headerName => response.headers[headerName] },
|
|
|
+ arrayBuffer: async () => new Uint8Array(response.array).buffer
|
|
|
+ };
|
|
|
}
|
|
|
+ },
|
|
|
+ frameFetch: async (url, frameId) => {
|
|
|
+ const response = await sendMessage({ method: "singlefile.fetchFrame", url, frameId });
|
|
|
+ return {
|
|
|
+ status: response.status,
|
|
|
+ headers: {
|
|
|
+ get: headerName => {
|
|
|
+ const headerArray = response.headers.find(headerArray => headerArray[0] == headerName);
|
|
|
+ if (headerArray) {
|
|
|
+ return headerArray[1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ arrayBuffer: async () => new Uint8Array(response.array).buffer
|
|
|
+ };
|
|
|
}
|
|
|
- }
|
|
|
+ };
|
|
|
|
|
|
- function sendRequest(method, url, frameId) {
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- const responsePromise = browser.runtime.sendMessage({ method, url, frameId, id: pendingRequests.length });
|
|
|
- responsePromise
|
|
|
- .then(response => {
|
|
|
- if (!response) {
|
|
|
- reject();
|
|
|
- }
|
|
|
- })
|
|
|
- .catch(reject);
|
|
|
- pendingRequests.push({ resolve, reject });
|
|
|
- });
|
|
|
+ async function sendMessage(message) {
|
|
|
+ const response = await browser.runtime.sendMessage(message);
|
|
|
+ if (!response || response.error) {
|
|
|
+ throw new Error(response && response.error.toString());
|
|
|
+ } else {
|
|
|
+ return response;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
function hostFetch(url) {
|