diff --git a/lib/controllers/object.js b/lib/controllers/object.js index b4acc48f..4db1edd7 100644 --- a/lib/controllers/object.js +++ b/lib/controllers/object.js @@ -313,10 +313,14 @@ exports.postObject = async function postObject(ctx) { break; } }; - const fileHandler = (fieldname, file) => { + const fileHandler = (fieldname, file, filename) => { if (fieldname !== 'file' || fileCount++) { return file.resume(); } + // S3 strips leading spaces from filename here, even though their docs + // don't mention it. I have raised this as an issue with AWS Enterprise support + // eslint-disable-next-line no-template-curly-in-string + key = key.replace('${filename}', filename.replace(/^ +/, '')); resolve(new S3Object(ctx.params.bucket, key, file, metadata)); }; @@ -406,7 +410,7 @@ exports.postObject = async function postObject(ctx) { if (!location.pathname.endsWith('/')) { location.pathname += '/'; } - location.pathname += object.key; + location.pathname += encodeURIComponent(object.key); ctx.set('Location', location.href); } diff --git a/test/controllers/object.spec.js b/test/controllers/object.spec.js index a669e61e..c2276ee1 100644 --- a/test/controllers/object.spec.js +++ b/test/controllers/object.spec.js @@ -378,7 +378,7 @@ describe('Operations on Objects', () => { describe('POST Object', () => { it('stores a text object for a multipart/form-data request', async function () { const form = new FormData(); - form.append('key', 'text'); + form.append('key', 'my_files/${filename}'); form.append('file', 'Hello!', 'post_file.txt'); const res = await request.post('bucket-a', { baseUrl: s3Client.endpoint.href, @@ -387,7 +387,7 @@ describe('Operations on Objects', () => { }); expect(res.statusCode).to.equal(204); const object = await s3Client - .getObject({ Bucket: 'bucket-a', Key: 'text' }) + .getObject({ Bucket: 'bucket-a', Key: 'my_files/post_file.txt' }) .promise(); expect(object.ContentType).to.equal('binary/octet-stream'); expect(object.Body).to.deep.equal(Buffer.from('Hello!'));