-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathworker.js
More file actions
67 lines (52 loc) · 2.57 KB
/
worker.js
File metadata and controls
67 lines (52 loc) · 2.57 KB
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
// REQUIRED: When configuring this worker script, in the UI, go to the "resource" tab, create a
// new WebAssembly module resource, name it "RESIZER_WASM", and upload resizer.wasm.
// OR, upload via the API (see `upload` in Makefile).
// Instantiate the WebAssembly module with 32MB of memory.
const wasmMemory = new WebAssembly.Memory({initial: 512});
const wasmInstance = new WebAssembly.Instance(
// RESIZER_WASM is a global variable created through the Resource Bindings UI (or API).
RESIZER_WASM,
// This second parameter is the imports object. Our module imports its memory object (so that
// we can allocate it ourselves), but doesn't require any other imports.
{env: {memory: wasmMemory}})
// Define some shortcuts.
const resizer = wasmInstance.exports
const memoryBytes = new Uint8Array(wasmMemory.buffer)
// Now we can write our worker script.
addEventListener("fetch", event => {
event.respondWith(handle(event.request))
});
async function handle(request) {
// Forward the request to our origin.
let response = await fetch(request)
// Check if the response is an image. If not, we'll just return it.
let type = response.headers.get("Content-Type") || ""
if (!type.startsWith("image/")) return response
// Check if the `width` query parameter was specified in the URL. If not,
// don't resize -- just return the response directly.
let width = new URL(request.url).searchParams.get("width")
if (!width) return response
// OK, we're going to resize. First, read the image data into memory.
let bytes = new Uint8Array(await response.arrayBuffer())
// Call our WebAssembly module's init() function to allocate space for
// the image.
let ptr = resizer.init(bytes.length)
// Copy the image into WebAssembly memory.
memoryBytes.set(bytes, ptr)
// Call our WebAssembly module's resize() function to perform the resize.
let newSize = resizer.resize(bytes.length, parseInt(width))
if (newSize == 0) {
// Resizer didn't want to process this image, so just return it. Since
// we already read the response body, we need to reconstruct the
// response here from the bytes we read.
return new Response(bytes, response);
}
// Extract the result bytes from WebAssembly memory.
let resultBytes = memoryBytes.slice(ptr, ptr + newSize)
// Create a new response with the image bytes. Our resizer module always
// outputs JPEG regardless of input type, so change the header.
let newResponse = new Response(resultBytes, response)
newResponse.headers.set("Content-Type", "image/jpeg")
// Return the response.
return newResponse
}