Revision 13a707c6
Added by koszko over 1 year ago
| background/CORS_bypass_server.js | ||
|---|---|---|
| 2 | 2 |
* This file is part of Haketilo. |
| 3 | 3 |
* |
| 4 | 4 |
* Function: Allow other parts of the extension to bypass CORS by routing their |
| 5 |
* request through this background script using one-off messages. |
|
| 5 |
* requests through this background script using one-off messages.
|
|
| 6 | 6 |
* |
| 7 | 7 |
* Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> |
| 8 | 8 |
* |
| ... | ... | |
| 43 | 43 |
*/ |
| 44 | 44 |
|
| 45 | 45 |
#FROM common/browser.js IMPORT browser |
| 46 |
#FROM common/misc.js IMPORT uint8_to_hex, error_data_jsonifiable |
|
| 46 | 47 |
|
| 47 |
async function get_prop(object, prop, result_object, call_prop=false) {
|
|
| 48 |
try {
|
|
| 49 |
result_object[prop] = call_prop ? (await object[prop]()) : object[prop]; |
|
| 50 |
} catch(e) {
|
|
| 51 |
result_object[`error_${prop}`] = "" + e;
|
|
| 52 |
} |
|
| 48 |
/* |
|
| 49 |
* In this file we implement a fetch()-from-background-script service. Code in |
|
| 50 |
* other parts of the extension shall call sendMessage() with arguments to |
|
| 51 |
* fetch() and code here will call fetch() with those arguments and send back |
|
| 52 |
* the response. |
|
| 53 |
* |
|
| 54 |
* We have to convert the Response from fetch() into a JSON-ifiable value and |
|
| 55 |
* then convert it back (using Response() constructor) due (among others) the |
|
| 56 |
* limitations of Chromium's messaging API: |
|
| 57 |
* https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities#data_cloning_algorithm |
|
| 58 |
* |
|
| 59 |
* We also catch possible errors from fetch() (e.g. in case of an invalid URL) |
|
| 60 |
* and send their data in JSON-ifiable form so that the error object can be |
|
| 61 |
* later re-created. |
|
| 62 |
*/ |
|
| 63 |
|
|
| 64 |
/* Make it possible to serialize Response object. */ |
|
| 65 |
async function response_data_jsonifiable(response) {
|
|
| 66 |
return {
|
|
| 67 |
status: response.status, |
|
| 68 |
statusText: response.statusText, |
|
| 69 |
headers: [...response.headers.entries()], |
|
| 70 |
body: uint8_to_hex(new Uint8Array(await response.arrayBuffer())) |
|
| 71 |
}; |
|
| 53 | 72 |
} |
| 54 | 73 |
|
| 55 |
async function perform_download(fetch_data, respond_cb) {
|
|
| 74 |
async function perform_download(fetch_data) {
|
|
| 56 | 75 |
try {
|
| 57 |
const response = await fetch(fetch_data.url); |
|
| 58 |
const result = {};
|
|
| 59 |
|
|
| 60 |
for (const prop of (fetch_data.to_get || [])) |
|
| 61 |
get_prop(response, prop, result); |
|
| 62 |
|
|
| 63 |
const to_call = (fetch_data.to_call || []); |
|
| 64 |
const promises = []; |
|
| 65 |
for (let i = 0; i < to_call.length; i++) {
|
|
| 66 |
const response_to_use = i === to_call.length - 1 ? |
|
| 67 |
response : response.clone(); |
|
| 68 |
promises.push(get_prop(response_to_use, to_call[i], result, true)); |
|
| 69 |
} |
|
| 70 |
|
|
| 71 |
await Promise.all(promises); |
|
| 72 |
return result; |
|
| 76 |
const response = await fetch(fetch_data.url, fetch_data.init); |
|
| 77 |
return response_data_jsonifiable(response); |
|
| 73 | 78 |
} catch(e) {
|
| 74 |
return {error: "" + e};
|
|
| 79 |
return {error: error_data_jsonifiable(e)};
|
|
| 75 | 80 |
} |
| 76 | 81 |
} |
| 77 | 82 |
|
Also available in: Unified diff
serialize and deserialize entire Response object when relaying fetch() calls to other contexts using sendMessage