AWS S3 #aws
/**
* index
* Date: 12.09.14
* Vitaliy V. Makeev (w.makeev@gmail.com)
*/
var _ = require('lodash')
, AWS = require('aws-sdk')
, path = require('path')
, url = require('url');
function encodeSpecialCharacters(filename) {
// Note: these characters are valid in URIs, but S3 does not like them for
// some reason.
return encodeURI(filename).replace(/[!'()* ]/g, function (char) {
return '%' + char.charCodeAt(0).toString(16);
});
}
function getPublicUrl(bucket, key, bucketLocation) {
var nonStandardBucketLocation = (bucketLocation && bucketLocation !== 'us-east-1');
var hostnamePrefix = nonStandardBucketLocation ? ("s3-" + bucketLocation) : "s3";
var parts = {
protocol: "https:",
hostname: hostnamePrefix + ".amazonaws.com",
pathname: "/" + bucket + "/" + encodeSpecialCharacters(key)
};
return url.format(parts);
}
function getPublicUrlHttp(bucket, key) {
var parts = {
protocol: "http:",
hostname: bucket + ".s3.amazonaws.com",
pathname: "/" + encodeSpecialCharacters(key)
};
return url.format(parts);
}
var awsStorage = function (sb) {
var log = sb.log;
/**
* Local file upload
* @param data
* @param options
* @param cb
*/
var upload = function (data, options, cb) {
var s3 = new AWS.S3(options.config);
// http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property
var response = s3.putObject(_.extend({}, options.params, {
Key : data.key,
Body : data.body,
ContentType : data.contentType
}), function (err, result) {
if (err) return cb(err);
result.url = getPublicUrlHttp(options.params.Bucket, data.key);
cb(null, result);
});
// http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html
// AWS S3 limitation - https://github.com/aws/aws-sdk-js/issues/94
response.on('httpUploadProgress', function(progress) {
sb.emit('upload/progress', {
key: data.key,
loaded: progress.loaded,
total: progress.total,
progress: Math.round(progress.loaded / (progress.total / 100))
});
});
};
return {
init: function (options) {
AWS.config.apiVersions.s3 = options.apiVersion || '2006-03-01';
sb.on('upload/file', function (data, channel, reply) {
upload(data, options, reply);
});
}
}
};
module.exports = awsStorage;