-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.mjs
153 lines (130 loc) · 3.93 KB
/
index.mjs
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import querystring from "querystring"; // Don't install.
import AWS from "aws-sdk";
import Sharp from "sharp";
const S3 = new AWS.S3({
region: "ap-northeast-2",
});
const BUCKET = "your-bucket-name"; // Input your bucket
// Image types that can be handled by Sharp
const supportImageTypes = ["auto", "jpg", "jpeg", "webp", "avif", "png"];
function initFormat(draftFormat, acceptHeader) {
switch (draftFormat) {
case "auto":
if (acceptHeader) {
if (acceptHeader.value.includes("avif")) {
return "avif";
} else if (acceptHeader.value.includes("webp")) {
return "webp";
}
} else {
return "jpeg";
}
break;
case "jpg":
return "jpeg";
default:
return draftFormat;
}
}
export const handler = async (event, context, callback) => {
let s3Object;
let resizedImage;
const { request, response } = event.Records[0].cf;
const { uri } = request;
const params = querystring.parse(request.querystring);
const ObjectKey = decodeURIComponent(uri).substring(1);
// If there is no width or height, return the original image.
if (!(params.width || params.height)) {
return callback(null, response);
}
const width = parseInt(params.width, 10) || null;
const height = parseInt(params.height, 10) || null;
// Sharp has different default values for quality depending on the image format.
// https://sharp.pixelplumbing.com/api-output#toformat
const quality = parseInt(params.quality, 10) || 100;
const extension = uri.match(/\/?(.*)\.(.*)/)[2].toLowerCase();
console.log("extension : ", extension);
// Return the original if there is no format conversion for GIF format requests.
if (extension === "gif" && !params.f) {
return callback(null, response);
}
const lowerCaseFormat = (params.format || extension).toLowerCase();
const acceptHeader = request.headers["accept"];
const finalFormat = initFormat(lowerCaseFormat, acceptHeader);
if (!supportImageTypes.some((type) => type === extension)) {
responseHandler(403, "Forbidden", "Unsupported image type", [
{
key: "Content-Type",
value: "text/plain",
},
]);
return callback(null, response);
}
// Verify For AWS CloudWatch.
console.log(`params: ${JSON.stringify(params)}`); // Cannot convert object to primitive value.\
console.log("S3 Object key:", ObjectKey);
console.log("Bucket name : ", BUCKET);
try {
s3Object = await S3.getObject({
Bucket: BUCKET,
Key: ObjectKey,
}).promise();
console.log("S3 Object:", s3Object);
} catch (error) {
console.log("S3.getObject error : ", error);
responseHandler(404, "Not Found", "OMG... The image does not exist.", [
{ key: "Content-Type", value: "text/plain" },
]);
return callback(null, response);
}
try {
/**
* @reference http://sharp.pixelplumbing.com/en/stable/api-resize/
*/
resizedImage = await Sharp(s3Object.Body)
.rotate()
.resize(width, height, { fit: "contain" })
.toFormat(finalFormat, {
quality,
})
.toBuffer();
} catch (error) {
console.log("Sharp error : ", error);
responseHandler(500, "Internal Server Error", "Fail to resize image.", [
{
key: "Content-Type",
value: "text/plain",
},
]);
return callback(null, response);
}
responseHandler(
200,
"OK",
resizedImage.toString("base64"),
[
{
key: "Content-Type",
value: `image/${finalFormat}`,
},
],
"base64"
);
function responseHandler(
status,
statusDescription,
body,
contentHeader,
bodyEncoding
) {
response.status = status;
response.statusDescription = statusDescription;
response.body = body;
response.headers["content-type"] = contentHeader;
if (bodyEncoding) {
response.bodyEncoding = bodyEncoding;
}
}
console.log("Success resizing image");
return callback(null, response);
};