Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

s3

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

s3 - npm Package Compare versions

Comparing version 4.2.0 to 4.3.0

9

CHANGELOG.md

@@ -0,1 +1,10 @@

### 4.3.0
* fix open file descriptor leak. Thanks
[Ross Wilson](https://github.com/wilsonwc)
* add downloadBuffer API
* uploadDir: add 'fileUploadStart', 'fileUploadEnd' events
* downloadDir: add 'fileDownloadStart', 'fileDownloadEnd' events
* update aws-sdk to 2.0.19
### 4.2.0

@@ -2,0 +11,0 @@

119

lib/index.js

@@ -15,2 +15,3 @@ var AWS = require('aws-sdk');

var mime = require('mime');
var StreamSink = require('streamsink');

@@ -154,2 +155,5 @@ var MAX_PUTOBJECT_SIZE = 5 * 1024 * 1024 * 1024;

localFileSlicer.on('error', handleError);
localFileSlicer.on('close', function() {
uploader.emit('fileClosed');
});

@@ -192,2 +196,6 @@ // keep an extra reference alive until we decide that we're completely

if (err) return handleError(err);
if (localFileSlicer) {
localFileSlicer.unref();
localFileSlicer = null;
}
uploader.emit('end', data);

@@ -739,2 +747,95 @@ }

Client.prototype.downloadBuffer = function(s3Params) {
var self = this;
var downloader = new EventEmitter();
s3Params = extend({}, s3Params);
downloader.progressAmount = 0;
doWithRetry(doDownloadWithPend, self.s3RetryCount, self.s3RetryDelay, function(err, buffer) {
if (err) {
downloader.emit('error', err);
return;
}
downloader.emit('end', buffer);
});
return downloader;
function doDownloadWithPend(cb) {
self.s3Pend.go(function(pendCb) {
doTheDownload(function(err, buffer) {
pendCb();
cb(err, buffer);
});
});
}
function doTheDownload(cb) {
var errorOccurred = false;
var request = self.s3.getObject(s3Params);
var hashCheckPend = new Pend();
request.on('build', function() {
request.httpRequest.headers.Expect = '100-continue';
});
request.on('httpHeaders', function(statusCode, headers, resp) {
if (statusCode >= 300) {
handleError(new Error("http status code " + statusCode));
return;
}
var contentLength = parseInt(headers['content-length'], 10);
downloader.progressTotal = contentLength;
downloader.progressAmount = 0;
downloader.emit('progress');
downloader.emit('httpHeaders', statusCode, headers, resp);
var eTag = cleanETag(headers.etag);
var eTagCount = getETagCount(eTag);
var outStream = new StreamSink();
var multipartETag = new MultipartETag({size: contentLength, count: eTagCount});
var httpStream = resp.httpResponse.createUnbufferedStream();
httpStream.on('error', handleError);
outStream.on('error', handleError);
hashCheckPend.go(function(cb) {
multipartETag.on('end', function() {
if (multipartETag.bytes !== contentLength) {
handleError(new Error("Downloaded size does not match Content-Length"));
return;
}
if (eTagCount === 1 && !multipartETag.anyMatch(eTag)) {
handleError(new Error("ETag does not match MD5 checksum"));
return;
}
cb();
});
});
multipartETag.on('progress', function() {
downloader.progressAmount = multipartETag.bytes;
downloader.emit('progress');
});
outStream.on('finish', function() {
if (errorOccurred) return;
hashCheckPend.wait(function() {
cb(null, outStream.toBuffer());
});
});
httpStream.pipe(multipartETag);
httpStream.pipe(outStream);
multipartETag.resume();
});
request.send(handleError);
function handleError(err) {
if (!err) return;
if (errorOccurred) return;
errorOccurred = true;
cb(err);
}
}
};
function syncDir(self, params, directionIsToS3) {

@@ -948,6 +1049,8 @@ var ee = new EventEmitter();

ee.progressTotal += s3Object.Size;
upDownFileParams.s3Params.Key = s3Object.Key;
var fullKey = s3Object.Key;
upDownFileParams.s3Params.Key = fullKey;
upDownFileParams.localFile = fullPath;
var downloader = self.downloadFile(upDownFileParams);
var prevAmountDone = 0;
ee.emit('fileDownloadStart', fullPath, fullKey);
downloader.on('error', handleError);

@@ -961,3 +1064,6 @@ downloader.on('progress', function() {

});
downloader.on('end', checkDoMoreWork);
downloader.on('end', function() {
ee.emit('fileDownloadEnd', fullPath, fullKey);
checkDoMoreWork();
});
}

@@ -999,3 +1105,4 @@ }

ee.progressTotal += localFileStat.size;
upDownFileParams.s3Params.Key = prefix + localFileStat.s3Path;
var fullKey = prefix + localFileStat.s3Path;
upDownFileParams.s3Params.Key = fullKey;
upDownFileParams.localFile = fullPath;

@@ -1005,2 +1112,3 @@ var uploader = self.uploadFile(upDownFileParams);

var prevAmountTotal = localFileStat.size;
ee.emit('fileUploadStart', fullPath, fullKey);
uploader.on('error', handleError);

@@ -1019,3 +1127,6 @@ uploader.on('progress', function() {

});
uploader.on('end', checkDoMoreWork);
uploader.on('end', function() {
ee.emit('fileUploadEnd', fullPath, fullKey);
checkDoMoreWork();
});
}

@@ -1022,0 +1133,0 @@ }

7

package.json
{
"name": "s3",
"version": "4.2.0",
"version": "4.3.0",
"description": "high level amazon s3 client. upload and download files and directories",

@@ -37,3 +37,3 @@ "main": "lib/index.js",

"dependencies": {
"aws-sdk": "~2.0.17",
"aws-sdk": "~2.0.19",
"findit": "~2.0.0",

@@ -45,3 +45,4 @@ "graceful-fs": "~3.0.2",

"fd-slicer": "~0.1.0",
"mime": "~1.2.11"
"mime": "~1.2.11",
"streamsink": "~1.2.0"
},

@@ -48,0 +49,0 @@ "bugs": {

@@ -246,2 +246,3 @@ # High Level Amazon S3 Client

`createReadStream(options)`. See the fd-slicer README for more information.
* `'fileClosed'` - emitted when `localFile` has been closed.

@@ -276,6 +277,32 @@ And these methods:

* `'error' (err)`
* `'end'` - emitted when the file is uploaded successfully
* `'end'` - emitted when the file is downloaded successfully
* `'progress'` - emitted when `progressAmount` and `progressTotal`
properties change.
### client.downloadBuffer(s3Params)
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property
* `s3Params`: params to pass to AWS SDK `getObject`.
The difference between using AWS SDK `getObject` and this one:
* This works with a buffer only.
* If the reported MD5 upon download completion does not match, it retries.
* Retry based on the client's retry settings.
* Progress reporting.
Returns an `EventEmitter` with these properties:
* `progressAmount`
* `progressTotal`
And these events:
* `'error' (err)`
* `'end' (buffer)` - emitted when the file is downloaded successfully.
`buffer` is a `Buffer` containing the object data.
* `'progress'` - emitted when `progressAmount` and `progressTotal`
properties change.
### client.listObjects(params)

@@ -401,2 +428,6 @@

* `'progress'` - emitted when any of the above progress properties change.
* `'fileUploadStart' (localFilePath, s3Key)` - emitted when a file begins
uploading.
* `'fileUploadEnd' (localFilePath, s3Key)` - emitted when a file successfully
finishes uploading.

@@ -465,4 +496,8 @@ `uploadDir` works like this:

* `'error' (err)`
* `'end'` - emitted when all files are uploaded
* `'end'` - emitted when all files are downloaded
* `'progress'` - emitted when any of the progress properties above change
* `'fileDownloadStart' (localFilePath, s3Key)` - emitted when a file begins
downloading.
* `'fileDownloadEnd' (localFilePath, s3Key)` - emitted when a file successfully
finishes downloading.

@@ -469,0 +504,0 @@ `downloadDir` works like this:

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc