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