forked from chilts/connect-stream-s3
-
Notifications
You must be signed in to change notification settings - Fork 1
/
connect-stream-s3.js
98 lines (83 loc) · 3.35 KB
/
connect-stream-s3.js
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
// --------------------------------------------------------------------------------------------------------------------
//
// connect-stream-s3.js - Middleware to stream a file to Amazon S3
//
// Copyright (c) 2012 AppsAttic Ltd - http://www.appsattic.com/
// Written by Andrew Chilton <[email protected]>
//
// License: http://opensource.org/licenses/MIT
//
// --------------------------------------------------------------------------------------------------------------------
var fs = require('fs');
var async = require('async');
var awssum = require('awssum');
var amazon = awssum.load('amazon/amazon');
var S3 = awssum.load('amazon/s3').S3;
module.exports = function(options) {
options = options || {};
// remember these (by taking local variables)
var accessKeyId = options.accessKeyId;
var secretAccessKey = options.secretAccessKey;
var awsAccountId = options.awsAccountId;
var region = options.region;
var bucketName = options.bucketName;
var concurrency = options.concurrency || 3;
// create the S3 API
var s3 = new S3({
'accessKeyId' : accessKeyId,
'secretAccessKey' : secretAccessKey,
'awsAccountId' : awsAccountId,
'region' : region
});
return function handler(req, res, next) {
// check that each uploaded file has a s3ObjectName property (and quit early)
for(var fieldname in req.files) {
if ( !req.files[fieldname].s3ObjectName ) {
next('Error: The s3ObjectName field has not been set on the uploaded file "' + fieldname + '".');
return;
}
}
// remember what happened to each of these files
var allOk = true;
// create an async function to upload the file
var upload = function(fieldname, callback) {
// open the file as a read stream
var bodyStream = fs.createReadStream( req.files[fieldname].path );
// create the data for s3.PutObject()
var data = {
'BucketName' : bucketName,
'ObjectName' : req.files[fieldname].s3ObjectName,
'ContentLength' : req.files[fieldname].size,
'Body' : bodyStream,
};
s3.PutObject(data, function(err, data) {
// remember what happened
req.files[fieldname].s3 = {
'err' : err,
'data' : data,
};
if (err) {
allOk = false;
} // else, everything was ok
// tell the queue we're finished with this file
callback();
});
}
// create a queue so we can do all of the uploaded files to S3
var q = async.queue(upload, concurrency);
// now, add all of these fields onto the queue
for(var fieldname in req.files) {
q.push(fieldname);
}
// once the queue is completely empty, call the next middleware
q.drain = function() {
if ( allOk ) {
next();
}
else {
next('One or more of the files failed to upload to S3.');
}
};
};
};
// --------------------------------------------------------------------------------------------------------------------