From d18e90a741af515da6130ad413b94df12436c394 Mon Sep 17 00:00:00 2001 From: shruthied Date: Tue, 2 Jan 2018 22:16:41 -0600 Subject: [PATCH 1/6] putObject supports the upload of an empty file. Fixes #657 --- src/main/object-uploader.js | 43 ++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/main/object-uploader.js b/src/main/object-uploader.js index 0344b50d..a22a5805 100644 --- a/src/main/object-uploader.js +++ b/src/main/object-uploader.js @@ -1,4 +1,4 @@ -/* +/* * Minio Javascript Library for Amazon S3 Compatible Cloud Storage, (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,7 +22,7 @@ import * as querystring from 'querystring' export default class ObjectUploader extends Transform { constructor(client, bucketName, objectName, partSize, contentType, callback) { super() - + this.emptyStream=true; this.client = client this.bucketName = bucketName this.objectName = objectName @@ -58,6 +58,7 @@ export default class ObjectUploader extends Transform { } _transform(chunk, encoding, callback) { + this.emptyStream=false; let method = 'PUT' let headers = { 'Content-Length': chunk.length, @@ -207,7 +208,43 @@ export default class ObjectUploader extends Transform { } _flush(callback) { + if (this.emptyStream) { + let method = 'PUT' + let headers = { + 'Content-Length': 0, + 'Content-Type': this.contentType + } + let options = { + method, headers, + query: '', + bucketName: this.bucketName, + objectName: this.objectName + } + + this.client.makeRequest(options, '', 200, '', true, (err, response) => { + if (err) return callback(err) + + let etag = response.headers.etag + if (etag) { + etag = etag.replace(/^"/, '').replace(/"$/, '') + } + + // Ignore the 'data' event so that the stream closes. (nodejs stream requirement) + response.on('data', () => {}) + + // Give the etag back, we're done! + process.nextTick(() => { + this.callback(null, etag) + }) + + // Because we're sure the stream has ended, allow it to flush and end. + callback() + }) + + return + } // If it has been uploaded in a single packet, we don't have to do anything. + else { if (this.id === null) { return } @@ -227,5 +264,5 @@ export default class ObjectUploader extends Transform { callback() }) } - +} } From eead7ee08b38d03961ce73495426c044ff9abe59 Mon Sep 17 00:00:00 2001 From: shruthied <32338806+shruthied@users.noreply.github.com> Date: Thu, 4 Jan 2018 09:38:38 -0600 Subject: [PATCH 2/6] Update object-uploader.js --- src/main/object-uploader.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/object-uploader.js b/src/main/object-uploader.js index a22a5805..b7b449c4 100644 --- a/src/main/object-uploader.js +++ b/src/main/object-uploader.js @@ -22,7 +22,7 @@ import * as querystring from 'querystring' export default class ObjectUploader extends Transform { constructor(client, bucketName, objectName, partSize, contentType, callback) { super() - this.emptyStream=true; + this.emptyStream=true this.client = client this.bucketName = bucketName this.objectName = objectName @@ -58,7 +58,7 @@ export default class ObjectUploader extends Transform { } _transform(chunk, encoding, callback) { - this.emptyStream=false; + this.emptyStream=false let method = 'PUT' let headers = { 'Content-Length': chunk.length, @@ -208,12 +208,12 @@ export default class ObjectUploader extends Transform { } _flush(callback) { - if (this.emptyStream) { - let method = 'PUT' - let headers = { - 'Content-Length': 0, - 'Content-Type': this.contentType - } + if (this.emptyStream) { + let method = 'PUT' + let headers = { + 'Content-Length': 0, + 'Content-Type': this.contentType + } let options = { method, headers, query: '', @@ -263,6 +263,6 @@ export default class ObjectUploader extends Transform { callback() }) + } } } -} From ad0b472252195567b69b1ba5b20b05f19fde898e Mon Sep 17 00:00:00 2001 From: shruthied <32338806+shruthied@users.noreply.github.com> Date: Thu, 4 Jan 2018 10:22:13 -0600 Subject: [PATCH 3/6] Update object-uploader.js --- src/main/object-uploader.js | 98 ++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/main/object-uploader.js b/src/main/object-uploader.js index b7b449c4..5097fb13 100644 --- a/src/main/object-uploader.js +++ b/src/main/object-uploader.js @@ -208,61 +208,61 @@ export default class ObjectUploader extends Transform { } _flush(callback) { - if (this.emptyStream) { - let method = 'PUT' - let headers = { + if (this.emptyStream) { + let method = 'PUT' + let headers = { 'Content-Length': 0, 'Content-Type': this.contentType - } - let options = { - method, headers, - query: '', - bucketName: this.bucketName, - objectName: this.objectName - } - - this.client.makeRequest(options, '', 200, '', true, (err, response) => { - if (err) return callback(err) - - let etag = response.headers.etag - if (etag) { - etag = etag.replace(/^"/, '').replace(/"$/, '') - } - - // Ignore the 'data' event so that the stream closes. (nodejs stream requirement) - response.on('data', () => {}) - - // Give the etag back, we're done! - process.nextTick(() => { - this.callback(null, etag) - }) - - // Because we're sure the stream has ended, allow it to flush and end. - callback() - }) - - return - } - // If it has been uploaded in a single packet, we don't have to do anything. - else { - if (this.id === null) { + } + let options = { + method, headers, + query: '', + bucketName: this.bucketName, + objectName: this.objectName + } + + this.client.makeRequest(options, '', 200, '', true, (err, response) => { + if (err) return callback(err) + + let etag = response.headers.etag + if (etag) { + etag = etag.replace(/^"/, '').replace(/"$/, '') + } + + // Ignore the 'data' event so that the stream closes. (nodejs stream requirement) + response.on('data', () => {}) + + // Give the etag back, we're done! + process.nextTick(() => { + this.callback(null, etag) + }) + + // Because we're sure the stream has ended, allow it to flush and end. + callback() + }) + return } + // If it has been uploaded in a single packet, we don't have to do anything. + else { + if (this.id === null) { + return + } - // This is called when all of the chunks uploaded successfully, thus - // completing the multipart upload. - this.client.completeMultipartUpload(this.bucketName, this.objectName, this.id, - this.etags, (err, etag) => { - if (err) return callback(err) + // This is called when all of the chunks uploaded successfully, thus + // completing the multipart upload. + this.client.completeMultipartUpload(this.bucketName, this.objectName, this.id, + this.etags, (err, etag) => { + if (err) return callback(err) - // Call our callback on the next tick to allow the streams infrastructure - // to finish what its doing before we continue. - process.nextTick(() => { - this.callback(null, etag) - }) + // Call our callback on the next tick to allow the streams infrastructure + // to finish what its doing before we continue. + process.nextTick(() => { + this.callback(null, etag) + }) - callback() - }) - } + callback() + }) + } } } From dd14e79a999f72a61fb0de6d4f1e6a250a043d1c Mon Sep 17 00:00:00 2001 From: shruthied <32338806+shruthied@users.noreply.github.com> Date: Thu, 4 Jan 2018 14:55:28 -0600 Subject: [PATCH 4/6] Update object-uploader.js --- src/main/object-uploader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/object-uploader.js b/src/main/object-uploader.js index 5097fb13..93381c70 100644 --- a/src/main/object-uploader.js +++ b/src/main/object-uploader.js @@ -22,7 +22,7 @@ import * as querystring from 'querystring' export default class ObjectUploader extends Transform { constructor(client, bucketName, objectName, partSize, contentType, callback) { super() - this.emptyStream=true + this.emptyStream = true this.client = client this.bucketName = bucketName this.objectName = objectName @@ -58,7 +58,7 @@ export default class ObjectUploader extends Transform { } _transform(chunk, encoding, callback) { - this.emptyStream=false + this.emptyStream = false let method = 'PUT' let headers = { 'Content-Length': chunk.length, From fa1848becdf7893e7df03a1690bffc443b75b565 Mon Sep 17 00:00:00 2001 From: shruthied <32338806+shruthied@users.noreply.github.com> Date: Thu, 4 Jan 2018 15:14:23 -0600 Subject: [PATCH 5/6] Update object-uploader.js --- src/main/object-uploader.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/object-uploader.js b/src/main/object-uploader.js index 93381c70..86be4124 100644 --- a/src/main/object-uploader.js +++ b/src/main/object-uploader.js @@ -244,7 +244,6 @@ export default class ObjectUploader extends Transform { return } // If it has been uploaded in a single packet, we don't have to do anything. - else { if (this.id === null) { return } @@ -264,5 +263,4 @@ export default class ObjectUploader extends Transform { callback() }) } - } } From 4c6113e14d6dbd8ec7aaeaa1fad8686786930044 Mon Sep 17 00:00:00 2001 From: shruthied <32338806+shruthied@users.noreply.github.com> Date: Thu, 4 Jan 2018 15:24:54 -0600 Subject: [PATCH 6/6] Update object-uploader.js --- src/main/object-uploader.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/object-uploader.js b/src/main/object-uploader.js index 86be4124..0e617b62 100644 --- a/src/main/object-uploader.js +++ b/src/main/object-uploader.js @@ -244,23 +244,23 @@ export default class ObjectUploader extends Transform { return } // If it has been uploaded in a single packet, we don't have to do anything. - if (this.id === null) { - return - } - - // This is called when all of the chunks uploaded successfully, thus - // completing the multipart upload. - this.client.completeMultipartUpload(this.bucketName, this.objectName, this.id, - this.etags, (err, etag) => { - if (err) return callback(err) + if (this.id === null) { + return + } - // Call our callback on the next tick to allow the streams infrastructure - // to finish what its doing before we continue. - process.nextTick(() => { - this.callback(null, etag) - }) + // This is called when all of the chunks uploaded successfully, thus + // completing the multipart upload. + this.client.completeMultipartUpload(this.bucketName, this.objectName, this.id, + this.etags, (err, etag) => { + if (err) return callback(err) - callback() + // Call our callback on the next tick to allow the streams infrastructure + // to finish what its doing before we continue. + process.nextTick(() => { + this.callback(null, etag) }) - } + + callback() + }) + } }