diff --git a/lib/s3/managed_upload.js b/lib/s3/managed_upload.js index f2b2969ac3..07ba7cd409 100644 --- a/lib/s3/managed_upload.js +++ b/lib/s3/managed_upload.js @@ -173,7 +173,11 @@ AWS.S3.ManagedUpload = AWS.util.inherit({ on('end', function() { self.isDoneChunking = true; self.numParts = self.totalPartNumbers; - self.fillQueue.call(self); + if (self.isDoneChunking && self.totalPartNumbers >= 1 && self.doneParts === self.numParts) { + self.finishMultiPart(); + } else { + self.fillQueue.call(self); + } }); } } diff --git a/test/s3/managed_upload.spec.coffee b/test/s3/managed_upload.spec.coffee index cc841defcc..9a38d115f1 100644 --- a/test/s3/managed_upload.spec.coffee +++ b/test/s3/managed_upload.spec.coffee @@ -368,6 +368,60 @@ describe 'AWS.S3.ManagedUpload', -> expect(e.message).to.equal('message') done() + it 'can send a stream that is exactly equal to part size', (done) -> + partSize = 5 * 1024 * 1024 + require('crypto').randomBytes partSize, (err, buf) -> + return done(err) if err + + stream = AWS.util.buffer.toStream buf + reqs = helpers.mockResponses [ + { data: UploadId: 'uploadId' } + { data: ETag: 'ETAG1' } + ] + upload = new AWS.S3.ManagedUpload({ + partSize: partSize, + queueSize: 1, + params: { Body: stream } + }) + upload.send (err) -> + return done(err) if err + + expect(helpers.operationsForRequests(reqs)).to.eql [ + 's3.createMultipartUpload', + 's3.uploadPart', + 's3.completeMultipartUpload' + ] + done() + + it 'can send a stream that is exactly divisible by part size', (done) -> + partSize = 5 * 1024 * 1024 + streamSize = 2 * partSize + require('crypto').randomBytes streamSize, (err, buf) -> + return done(err) if err + + stream = AWS.util.buffer.toStream buf + reqs = helpers.mockResponses [ + { data: UploadId: 'uploadId' } + { data: ETag: 'ETAG1' } + { data: ETag: 'ETAG2' } + { data: ETag: 'FINAL_ETAG', Location: 'FINAL_LOCATION' } + ] + upload = new AWS.S3.ManagedUpload({ + partSize: partSize, + queueSize: 1, + params: { Body: stream } + }) + upload.send (err) -> + return done(err) if err + + expect(helpers.operationsForRequests(reqs)).to.eql [ + 's3.createMultipartUpload' + 's3.uploadPart' + 's3.uploadPart' + 's3.completeMultipartUpload' + ] + done() + if typeof Promise == 'function' describe 'promise', -> thenFunction = (d) ->