Gathering detailed insights and metrics for multer-s3-v2
Gathering detailed insights and metrics for multer-s3-v2
Gathering detailed insights and metrics for multer-s3-v2
Gathering detailed insights and metrics for multer-s3-v2
Streaming multer storage engine for AWS S3. This project is mostly an integration piece for existing code samples from Multer's storage engine documentation with s3fs as the substitution piece for file system. Existing solutions I found required buffering the multipart uploads into the actual filesystem which is difficult to scale.
npm install multer-s3-v2
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
107 Commits
6 Forks
1 Watching
1 Branches
15 Contributors
Updated on 08 Jan 2021
JavaScript (100%)
Cumulative downloads
Total Downloads
Last day
88.2%
64
Compared to previous day
Last week
-16.2%
254
Compared to previous week
Last month
36.1%
1,115
Compared to previous month
Last year
-29.4%
15,349
Compared to previous year
3
Streaming multer storage engine for AWS S3.
This project is mostly an integration piece for existing code samples from Multer's storage engine documentation with s3fs as the substitution piece for file system. Existing solutions I found required buffering the multipart uploads into the actual filesystem which is difficult to scale.
1npm install --save multer-s3-v2
1var aws = require("aws-sdk"); 2var express = require("express"); 3var multer = require("multer"); 4var multerS3 = require("multer-s3-v2"); 5 6var app = express(); 7var s3 = new aws.S3({ 8 /* ... */ 9}); 10 11var upload = multer({ 12 storage: multerS3({ 13 s3: s3, 14 bucket: "some-bucket", 15 metadata: function(req, file, cb) { 16 cb(null, { fieldName: file.fieldname }); 17 }, 18 key: function(req, file, cb) { 19 cb(null, Date.now().toString()); 20 }, 21 throwMimeTypeConflictErrors: true 22 }) 23}); 24 25app.post("/upload", upload.array("photos", 3), function(req, res, next) { 26 res.send("Successfully uploaded " + req.files.length + " files!"); 27});
Each file contains the following information exposed by multer-s3
:
Key | Description | Note |
---|---|---|
size | Size of the file in bytes | |
bucket | The bucket used to store the file | S3Storage |
key | The name of the file | S3Storage |
acl | Access control for the file | S3Storage |
contentType | The mimetype used to upload the file | S3Storage |
metadata | The metadata object to be sent to S3 | S3Storage |
location | The S3 url to access the file | S3Storage |
etag | The etag of the uploaded file in S3 | S3Storage |
contentDisposition | The contentDisposition used to upload the file | S3Storage |
storageClass | The storageClass to be used for the uploaded file in S3 | S3Storage |
versionId | The versionId is an optional param returned by S3 for versioned buckets. | S3Storage |
ACL values can be set by passing an optional acl
parameter into the multerS3
object.
1var upload = multer({ 2 storage: multerS3({ 3 s3: s3, 4 bucket: "some-bucket", 5 acl: "public-read", 6 key: function(req, file, cb) { 7 cb(null, Date.now().toString()); 8 } 9 }) 10});
Available options for canned ACL.
ACL Option | Permissions added to ACL |
---|---|
private | Owner gets FULL_CONTROL . No one else has access rights (default). |
public-read | Owner gets FULL_CONTROL . The AllUsers group gets READ access. |
public-read-write | Owner gets FULL_CONTROL . The AllUsers group gets READ and WRITE access. Granting this on a bucket is generally not recommended. |
aws-exec-read | Owner gets FULL_CONTROL . Amazon EC2 gets READ access to GET an Amazon Machine Image (AMI) bundle from Amazon S3. |
authenticated-read | Owner gets FULL_CONTROL . The AuthenticatedUsers group gets READ access. |
bucket-owner-read | Object owner gets FULL_CONTROL . Bucket owner gets READ access. If you specify this canned ACL when creating a bucket, Amazon S3 ignores it. |
bucket-owner-full-control | Both the object owner and the bucket owner get FULL_CONTROL over the object. If you specify this canned ACL when creating a bucket, Amazon S3 ignores it. |
log-delivery-write | The LogDelivery group gets WRITE and READ_ACP permissions on the bucket. For more information on logs. |
The metadata
option is a callback that accepts the request and file, and returns a metadata object to be saved to S3.
Here is an example that stores all fields in the request body as metadata, and uses an id
param as the key:
1var opts = { 2 s3: s3, 3 bucket: config.originalsBucket, 4 metadata: function(req, file, cb) { 5 cb(null, Object.assign({}, req.body)); 6 }, 7 key: function(req, file, cb) { 8 cb(null, req.params.id + ".jpg"); 9 } 10};
The optional cacheControl
option sets the Cache-Control
HTTP header that will be sent if you're serving the files directly from S3. You can pass either a string or a function that returns a string.
Here is an example that will tell browsers and CDNs to cache the file for one year:
1var upload = multer({ 2 storage: multerS3({ 3 s3: s3, 4 bucket: "some-bucket", 5 cacheControl: "max-age=31536000", 6 key: function(req, file, cb) { 7 cb(null, Date.now().toString()); 8 } 9 }) 10});
The optional contentType
option can be used to set Content/mime type of the file. By default the content type is set to application/octet-stream
. If you want multer-s3 to automatically find the content-type of the file, use the multerS3.AUTO_CONTENT_TYPE
constant. Here is an example that will detect the content type of the file being uploaded.
1var upload = multer({ 2 storage: multerS3({ 3 s3: s3, 4 bucket: "some-bucket", 5 contentType: multerS3.AUTO_CONTENT_TYPE, 6 key: function(req, file, cb) { 7 cb(null, Date.now().toString()); 8 } 9 }) 10});
You may also use a function as the contentType
, which should be of the form function(req, file, cb)
.
storageClass values can be set by passing an optional storageClass
parameter into the multerS3
object.
1var upload = multer({ 2 storage: multerS3({ 3 s3: s3, 4 bucket: "some-bucket", 5 acl: "public-read", 6 storageClass: "REDUCED_REDUNDANCY", 7 key: function(req, file, cb) { 8 cb(null, Date.now().toString()); 9 } 10 }) 11});
The optional contentDisposition
option can be used to set the Content-Disposition
header for the uploaded file. By default, the contentDisposition
isn't forwarded. As an example below, using the value attachment
forces the browser to download the uploaded file instead of trying to open it.
1var upload = multer({ 2 storage: multerS3({ 3 s3: s3, 4 bucket: "some-bucket", 5 acl: "public-read", 6 contentDisposition: "attachment", 7 key: function(req, file, cb) { 8 cb(null, Date.now().toString()); 9 } 10 }) 11});
An overview of S3's server-side encryption can be found in the S3 Docs; be advised that customer-managed keys (SSE-C) is not implemented at this time.
You may use the S3 server-side encryption functionality via the optional serverSideEncryption
and sseKmsKeyId
parameters. Full documentation of these parameters in relation to the S3 API can be found here and here.
serverSideEncryption
has two valid values: 'AES256' and 'aws:kms'. 'AES256' utilizes the S3-managed key system, while 'aws:kms' utilizes the AWS KMS system and accepts the optional sseKmsKeyId
parameter to specify the key ID of the key you wish to use. Leaving sseKmsKeyId
blank when 'aws:kms' is specified will use the default KMS key. Note: You must instantiate the S3 instance with signatureVersion: 'v4'
in order to use KMS-managed keys [Docs], and the specified key must be in the same AWS region as the S3 bucket used.
1var upload = multer({ 2 storage: multerS3({ 3 s3: s3, 4 bucket: "some-bucket", 5 acl: "authenticated-read", 6 contentDisposition: "attachment", 7 serverSideEncryption: "AES256", 8 key: function(req, file, cb) { 9 cb(null, Date.now().toString()); 10 } 11 }) 12});
The transforms
option is a function or object with field.
Here is an example with simple transform as function:
1var sharp = require("sharp"); 2 3var opts = { 4 s3: s3, 5 bucket: config.originalsBucket, 6 transforms: () => 7 sharp() 8 .resize(1920, 1080) 9 .max() 10 .withoutEnlargement() 11 .jpeg({ 12 progressive: true, 13 quality: 80 14 }), 15 metadata: function(req, file, cb) { 16 cb(null, Object.assign({}, req.body)); 17 }, 18 key: function(req, file, cb) { 19 cb(null, req.params.id + ".jpg"); 20 } 21};
And here is exemple with field specific transform:
1var sharp = require("sharp"); 2 3var opts = { 4 s3: s3, 5 bucket: config.originalsBucket, 6 transforms: { 7 avatar: () => 8 sharp() 9 .resize(1920, 1080) 10 .max() 11 .withoutEnlargement() 12 .jpeg({ 13 progressive: true, 14 quality: 80 15 }) 16 }, 17 metadata: function(req, file, cb) { 18 cb(null, Object.assign({}, req.body)); 19 }, 20 key: function(req, file, cb) { 21 cb(null, req.params.id + ".jpg"); 22 } 23};
throwMimeTypeConflictErrors: boolean?
If enabled, this will result in an exception (instead of an upload) when the mime-type reported by package file-type does not match the mime-type encoded in the multi-part form data for a given file (see tests for example).
The tests mock all access to S3 and can be run completely offline.
1npm test
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
Found 2/22 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
26 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More