/
browserfetch.js
75 lines (68 loc) · 2.36 KB
/
browserfetch.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// ==UserScript==
// @name browserfetch
// @namespace https://github.com/5j9/browserfetch
// @match https://example.com/
// @grant GM_registerMenuCommand
// ==/UserScript==
(() => {
function connect() {
var ws = new WebSocket("ws://127.0.0.1:9404/ws");
ws.binaryType = "arraybuffer";
ws.onopen = () => {
ws.send(location.host);
}
ws.onclose = function () {
console.error('browserfetch: WebSocket was closed; will retry in 5 seconds');
setTimeout(connect, 5000);
};
ws.onmessage = async (evt) => {
var returnData, responseBlob, body, jArray;
var requestArray = new Uint8Array(evt.data);
var nullIndex = requestArray.indexOf(0);
if (nullIndex === -1) {
body = null;
jArray = requestArray;
} else {
body = requestArray.slice(nullIndex + 1);
jArray = requestArray.slice(0, nullIndex)
}
var j = JSON.parse(new TextDecoder().decode(jArray));
var options = j['options'] || {};
if (j['timeout']) {
options.signal = AbortSignal.timeout(j['timeout'] * 1000);
}
if (body !== null) {
options.body = body;
}
try {
var r = await fetch(j['url'], options);
returnData = {
'event_id': j['event_id'],
'headers': Object.fromEntries([...r.headers]),
'ok': r.ok,
'redirected': r.redirected,
'status': r.status,
'status_text': r.statusText,
'type': r.type,
'url': r.url
};
responseBlob = await r.blob();
} catch (err) {
returnData = {
'event_id': j['event_id'],
'error': err.toString()
};
responseBlob = "";
};
ws.send(new Blob([new TextEncoder().encode(JSON.stringify(returnData)), "\0", responseBlob]));
}
};
if (window.GM_registerMenuCommand) {
GM_registerMenuCommand(
'connect to browserfetch',
connect
);
} else {
connect();
}
})();