Skip to content

Commit

Permalink
feat(object): add about multi part upload
Browse files Browse the repository at this point in the history
  • Loading branch information
ferhatelmas committed Apr 21, 2023
1 parent f834192 commit 21ae917
Show file tree
Hide file tree
Showing 6 changed files with 399 additions and 70 deletions.
27 changes: 27 additions & 0 deletions lib/controllers/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,33 @@ exports.initiateMultipartUpload = async function initiateMultipartUpload(ctx) {
};
};

/**
* Abort Multipart Upload
* This action aborts a multipart upload. After a multipart upload is aborted,
* no additional parts can be uploaded using that upload ID. The storage consumed by
* any previously uploaded parts will be freed. However, if any part uploads are
* currently in progress, those part uploads might or might not succeed. As a result,
* it might be necessary to abort a given multipart upload multiple times in order to
* completely free all storage consumed by all parts.
* @param {Koa.Context} ctx
* @link {https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html}
*/
exports.abortMultipartUpload = async function abortMultipartUpload(ctx) {
try {
await ctx.store.abortObjectMultipart(ctx.params.bucket, ctx.query.uploadId);
ctx.status = 204;
} catch (err) {
ctx.logger.error(
'Error deleting multipart for object "%s" on bucket "%s" for multipart "%s"',
ctx.params.key,
ctx.params.bucket,
ctx.query.uploadId,
err,
);
ctx.status = 500;
}
};

/**
* Upload Part
* This operation uploads a part in a multipart upload. Part numbers can be any number from 1 to
Expand Down
2 changes: 2 additions & 0 deletions lib/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ router
.use('/:bucket/:key+', bucketCtrl.bucketExists, queryMethod(objectMethods))
.delete('/:bucket/:key+', (ctx) => {
switch (ctx.params.queryMethod) {
case 'uploadId':
return objectCtrl.abortMultipartUpload(ctx);
case undefined:
return objectCtrl.deleteObject(ctx);
case 'tagging':
Expand Down
19 changes: 14 additions & 5 deletions lib/stores/filesystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
readdirSync,
promises: fs,
} = require('fs');
const { rimraf } = require('rimraf');
const { pipeline, Transform } = require('stream');
const { pick, pickBy, sortBy, zip } = require('lodash');
const path = require('path');
Expand Down Expand Up @@ -377,11 +378,11 @@ class FilesystemStore {
const parts = key.split('/');
// the last part isn't a directory (it's embedded into the file name)
parts.pop();
while (
parts.length &&
!readdirSync(path.join(bucketPath, ...parts)).length
) {
await fs.rmdir(path.join(bucketPath, ...parts));
while (parts.length) {
await fs.rmdir(path.join(bucketPath, ...parts)).catch((err) => {
if (err.code !== 'ENOENT' && err.code !== 'ENOTEMPTY') throw err;
parts.length = 0;
});
parts.pop();
}
}
Expand Down Expand Up @@ -437,6 +438,14 @@ class FilesystemStore {
return result;
}

async abortObjectMultipart(bucket, uploadId) {
const uploadDir = path.join(
this.getResourcePath(bucket, undefined, 'uploads'),
uploadId,
);
await rimraf(uploadDir);
}

async getSubresource(bucket, key, resourceType) {
const resourcePath = this.getResourcePath(
bucket,
Expand Down
Loading

0 comments on commit 21ae917

Please sign in to comment.