-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathr2-image.js
More file actions
74 lines (66 loc) · 2.62 KB
/
Copy pathr2-image.js
File metadata and controls
74 lines (66 loc) · 2.62 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
68
69
70
71
72
73
74
/**
* Cloudflare Service Integration
* Transform Images in R2 with Workers
*/
export default {
async fetch(request, env) {
const { origin, pathname, searchParams } = new URL(request.url);
if (pathname === "/") {
return new Response("(c) 2024 Object Storage Service based on Cloudflare R2");
}
// Get bucket
const { bucketName, objectKey } = this.parse(pathname);
const bucket = env[bucketName];
if (!bucket) {
return new Response("Bucket Not Found", { status: 404 });
}
// Get object
const object = await bucket.get(objectKey);
if (!object) {
return new Response("Object Not Found", { status: 404 });
}
// If not image or has no querystring, return the raw content
const { contentType } = object.httpMetadata;
if (!contentType.startsWith("image/") || !searchParams.toString()) {
// HTTP caching
const etag = this.extractEtag(request);
if (etag == object.httpEtag) {
return new Response(null, { status: 304 });
}
// Raw content
const headers = new Headers();
object.writeHttpMetadata(headers);
headers.set("Access-Control-Allow-Origin", "*");
headers.set("Access-Control-Allow-Headers", "*");
headers.set("Access-Control-Allow-Methods", "GET, OPTIONS");
headers.set("etag", object.httpEtag);
return new Response(object.body, { headers });
}
// If image, transform with query parameters
const image = { fit: "scale-down" };
if (searchParams.has("size")) {
image.width = image.height = searchParams.get("size");
}
if (searchParams.has("width")) image.width = searchParams.get("width");
if (searchParams.has("height")) image.height = searchParams.get("height");
if (searchParams.has("quality")) image.quality = searchParams.get("quality");
if (searchParams.has("fit")) image.fit = searchParams.get("fit");
return fetch(new Request(origin + pathname,
{ headers: request.headers }), { cf: { image } });
},
parse(pathname) {
const parts = pathname.slice(1).split("/");
return {
bucketName: parts.shift(),
objectKey: decodeURI(parts.join("/"))
};
},
extractEtag(request) {
const etag = request.headers.get("If-None-Match");
if (etag) {
const matched = etag.match(/W\/("\w+")/);
return matched ? matched[1] : etag;
}
return null;
}
}