File size: 1,479 Bytes
bee6636
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
addEventListener(
	"message",
	({

		data: {

			sab,

			args: [method, url, _, username, password],

			body,

			headers,

		},

	}) => {
		const view = new DataView(sab);
		const u8view = new Uint8Array(sab);

		const xhr = new XMLHttpRequest();
		xhr.responseType = "arraybuffer";

		// force async since we need it to resolve to the sw
		xhr.open(method, url, true, username, password);

		if (headers)
			for (const [k, v] of Object.entries(headers)) {
				xhr.setRequestHeader(k, v as string);
			}

		xhr.send(body);

		xhr.onload = () => {
			let cursor = 1; // first byte is the lock

			view.setUint16(cursor, xhr.status);
			cursor += 2;

			// next write the header string
			const headers = xhr.getAllResponseHeaders();
			view.setUint32(cursor, headers.length);
			cursor += 4;

			if (sab.byteLength < cursor + headers.length)
				sab.grow(cursor + headers.length);
			u8view.set(new TextEncoder().encode(headers), cursor);
			cursor += headers.length;

			view.setUint32(cursor, xhr.response.byteLength);
			cursor += 4;

			if (sab.byteLength < cursor + xhr.response.byteLength)
				sab.grow(cursor + xhr.response.byteLength);
			u8view.set(new Uint8Array(xhr.response), cursor);

			// release the lock, main thread will stop spinning now
			view.setUint8(0, 1);
		};
		xhr.ontimeout =
			xhr.onerror =
			xhr.onabort =
				() => {
					console.error("xhr failed");
					view.setUint8(0, 1);
				};
	}
);