Skip to content

Commit e38850f

Browse files
committed
Update s3-resizer 4.0
Technically, the interface is still compatible with version 3.x (`100x100_max/my-image.jpg` - the path is still the same), but this update brings major changes including using new import/export syntax, so the decision was to jump to a new version. Here is what's new: - Update the Sharp library: [v0.23.3](https://www.npmjs.com/package/sharp/v/0.23.3) => [v0.32.0](https://www.npmjs.com/package/sharp/v/0.32.0) - Update AWS SDK: [aws-sdk v2.36.0](https://www.npmjs.com/package/aws-sdk/v/2.36.0) => [@aws-sdk/client-s3 v3.304.0](https://www.npmjs.com/package/@aws-sdk/client-s3/v/3.304.0). The former api contained the whole sdk with 99% unused code whereas the new one contains functions specific to S3. - Buffers were replaced by streams. So now it's almost impossible to go out-of-memory if an image is too large (though it is still highly recommended to keep memory big +512mb, you can do that in Configuration->Edit) - CommonJS => ES Module. And hence `require/exports` => `import/export`. They promise to be faster as well. - Reduce zip size containing compiled node_modules: 30mb => 10mb. - If `?path=` is not set, return explaining message and `statusCode: 400`. Previously it was `Internal Server Error` with `statusCode: 500`. 🎉 Compiled and tested for NodeJS 18.x 🎉 ```bash npm i --arch=x64 --platform=linux npm i --arch=x64 --platform=linux --only=prod ``` Use the latter only if you know what you are doing! It does not contain awk libraries in node_modules, so the latest version of the sdk will be used. You can configure auto update of built-in sdk in lambda _Runtime settings -> Edit runtime management configuration -> Update runtime version_.
1 parent 1015d1b commit e38850f

File tree

2 files changed

+52
-40
lines changed

2 files changed

+52
-40
lines changed

index.js

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
'use strict'
1+
import {S3Client, GetObjectCommand} from "@aws-sdk/client-s3";
2+
import {Upload} from '@aws-sdk/lib-storage';
3+
import Sharp from 'sharp';
24

3-
4-
const AWS = require('aws-sdk');
5-
const S3 = new AWS.S3({signatureVersion: 'v4'});
6-
const Sharp = require('sharp');
75
const PathPattern = /(.*\/)?(.*)\/(.*)/;
86

97
// parameters
@@ -12,10 +10,18 @@ const WHITELIST = process.env.WHITELIST
1210
? Object.freeze(process.env.WHITELIST.split(' '))
1311
: null;
1412

13+
const s3Client = new S3Client();
14+
15+
export const handler = async (event) => {
16+
const path = event.queryStringParameters?.path;
17+
if (!path) {
18+
return errorResponse('Parameter "?path=" is empty or missing');
19+
}
1520

16-
exports.handler = async (event) => {
17-
const path = event.queryStringParameters.path;
1821
const parts = PathPattern.exec(path);
22+
if (!parts || !parts[2] || !parts[3]) {
23+
return errorResponse('Parameter "?path=" should look like: path/150x150_max/image.jpg');
24+
}
1925
const dir = parts[1] || '';
2026
const resizeOption = parts[2]; // e.g. "150x150_max"
2127
const sizeAndAction = resizeOption.split('_');
@@ -26,27 +32,22 @@ exports.handler = async (event) => {
2632

2733
// Whitelist validation.
2834
if (WHITELIST && !WHITELIST.includes(resizeOption)) {
29-
return {
30-
statusCode: 400,
31-
body: `WHITELIST is set but does not contain the size parameter "${resizeOption}"`,
32-
headers: {"Content-Type": "text/plain"}
33-
};
35+
return errorResponse(`WHITELIST is set but does not contain the size parameter "${resizeOption}"`, 403);
3436
}
3537

3638
// Action validation.
3739
if (action && action !== 'max' && action !== 'min') {
38-
return {
39-
statusCode: 400,
40-
body: `Unknown func parameter "${action}"\n` +
41-
'For query ".../150x150_func", "_func" must be either empty, "_min" or "_max"',
42-
headers: {"Content-Type": "text/plain"}
43-
};
40+
return errorResponse(
41+
`Unknown func parameter "${action}"\n` +
42+
'For query ".../150x150_func", "_func" must be either empty, "_min" or "_max"'
43+
);
4444
}
4545

4646
try {
47-
const data = await S3
48-
.getObject({Bucket: BUCKET, Key: dir + filename})
49-
.promise();
47+
const originImage = await s3Client.send(new GetObjectCommand({
48+
Bucket: BUCKET,
49+
Key: dir + filename,
50+
}));
5051

5152
const width = sizes[0] === 'AUTO' ? null : parseInt(sizes[0]);
5253
const height = sizes[1] === 'AUTO' ? null : parseInt(sizes[1]);
@@ -62,28 +63,37 @@ exports.handler = async (event) => {
6263
fit = 'cover';
6364
break;
6465
}
65-
const result = await Sharp(data.Body, {failOnError: false})
66+
const sharp = Sharp({failOn: 'none'})
6667
.resize(width, height, {withoutEnlargement: true, fit})
67-
.rotate()
68-
.toBuffer();
68+
.rotate();
6969

70-
await S3.putObject({
71-
Body: result,
72-
Bucket: BUCKET,
73-
ContentType: data.ContentType,
74-
Key: path,
75-
CacheControl: 'public, max-age=86400'
76-
}).promise();
70+
// This does not work: await s3Client.send(new PutObjectCommand({params})
71+
// Solution: https://github.com/aws/aws-sdk-js-v3/issues/1920#issuecomment-761298908
72+
const upload = new Upload({
73+
client: s3Client,
74+
params: {
75+
Bucket: BUCKET,
76+
Key: path,
77+
Body: originImage.Body.pipe(sharp),
78+
ContentType: originImage.ContentType,
79+
CacheControl: 'public, max-age=86400'
80+
},
81+
});
82+
await upload.done();
7783

7884
return {
7985
statusCode: 301,
8086
headers: {"Location" : `${URL}/${path}`}
8187
};
8288
} catch (e) {
83-
return {
84-
statusCode: e.statusCode || 400,
85-
body: 'Exception: ' + e.message,
86-
headers: {"Content-Type": "text/plain"}
87-
};
89+
return errorResponse('Exception: ' + e.message, e.statusCode || 400);
90+
}
91+
}
92+
93+
function errorResponse(body, statusCode = 400) {
94+
return {
95+
statusCode,
96+
body,
97+
headers: {"Content-Type": "text/plain"}
8898
}
8999
}

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
{
22
"name": "s3-resizer",
3-
"version": "3.0.1",
3+
"version": "4.0.0",
44
"dependencies": {
5-
"sharp": "^0.23.3"
5+
"sharp": "^0.32.0"
66
},
77
"devDependencies": {
8-
"aws-sdk": "^2.36.0"
9-
}
8+
"@aws-sdk/client-s3": "^3.304.0",
9+
"@aws-sdk/lib-storage": "^3.304.0"
10+
},
11+
"type": "module"
1012
}

0 commit comments

Comments
 (0)