|
|
@@ -18,11 +18,11 @@
|
|
|
* along with SingleFile. If not, see <http://www.gnu.org/licenses/>.
|
|
|
*/
|
|
|
|
|
|
-/* global browser, fetch */
|
|
|
+/* global browser, XMLHttpRequest */
|
|
|
|
|
|
(() => {
|
|
|
|
|
|
- const fetchResponses = new Map();
|
|
|
+ const responses = new Map();
|
|
|
|
|
|
let requestId = 1;
|
|
|
|
|
|
@@ -40,29 +40,47 @@
|
|
|
if (request.method == "fetch") {
|
|
|
const responseId = requestId;
|
|
|
requestId = requestId + 1;
|
|
|
- const response = await fetch(request.url, request.options);
|
|
|
- if (response.status >= 400) {
|
|
|
- throw new Error(response.statusText || response.status);
|
|
|
- } else {
|
|
|
- fetchResponses.set(responseId, response);
|
|
|
- const headers = {};
|
|
|
- for (let headerName of response.headers.keys()) {
|
|
|
- headers[headerName] = response.headers.get(headerName);
|
|
|
+ const response = await superFetch(request.url);
|
|
|
+ responses.set(responseId, response);
|
|
|
+ response.responseId = responseId;
|
|
|
+ return { responseId, headers: response.headers };
|
|
|
+ } else if (request.method == "fetch.array") {
|
|
|
+ const response = responses.get(request.requestId);
|
|
|
+ responses.delete(response.requestId);
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ response.xhrRequest.onerror = event => reject(new Error(event.details));
|
|
|
+ if (response.xhrRequest.readyState == XMLHttpRequest.DONE) {
|
|
|
+ resolve(getResponse(response.xhrRequest));
|
|
|
+ } else {
|
|
|
+ response.xhrRequest.onload = () => resolve(getResponse(response.xhrRequest));
|
|
|
}
|
|
|
- return { responseId, headers };
|
|
|
- }
|
|
|
- } else {
|
|
|
- const content = fetchResponses.get(request.requestId);
|
|
|
- fetchResponses.delete(request.requestId);
|
|
|
- if (request.method == "fetch.array") {
|
|
|
- const buffer = await content.arrayBuffer();
|
|
|
- return { array: Array.from(new Uint8Array(buffer)) };
|
|
|
- }
|
|
|
- if (request.method == "fetch.text") {
|
|
|
- const text = await content.text();
|
|
|
- return { text };
|
|
|
- }
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ function getResponse(xhrRequest) {
|
|
|
+ return { array: Array.from(new Uint8Array(xhrRequest.response)) };
|
|
|
+ }
|
|
|
+
|
|
|
+ async function superFetch(url) {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ const xhrRequest = new XMLHttpRequest();
|
|
|
+ xhrRequest.responseType = "arraybuffer";
|
|
|
+ xhrRequest.onerror = event => reject(new Error(event.details));
|
|
|
+ xhrRequest.onreadystatechange = () => {
|
|
|
+ if (xhrRequest.readyState == XMLHttpRequest.HEADERS_RECEIVED) {
|
|
|
+ if (xhrRequest.status >= 400) {
|
|
|
+ reject(new Error(xhrRequest.statusText || xhrRequest.status));
|
|
|
+ } else {
|
|
|
+ const headers = {};
|
|
|
+ headers["content-type"] = xhrRequest.getResponseHeader("Content-Type");
|
|
|
+ resolve({ xhrRequest, headers });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ xhrRequest.open("GET", url, true);
|
|
|
+ xhrRequest.send();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
})();
|