Skip to content

Commit 8ae28a6

Browse files
authoredMar 27, 2017
Ensure MultipartUpload locations returned by the managed uploader are URI-decoded to match single part upload locations (#1420)
* Ensure MultipartUpload locations returned by the managed uploader are URI-decoded to match single part upload locations * Add test to ensure location is provided on tagged multipart uploads * Add test to ensure PutObjectTagging errors are propagated
1 parent 6295d62 commit 8ae28a6

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed
 

‎lib/s3/managed_upload.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -618,10 +618,20 @@ AWS.S3.ManagedUpload = AWS.util.inherit({
618618
return self.cleanup(err);
619619
}
620620

621+
if (data && typeof data.Location === 'string') {
622+
data.Location = data.Location.replace(/%2F/g, '/');
623+
}
624+
621625
if (Array.isArray(self.tags)) {
622626
self.service.putObjectTagging(
623627
{Tagging: {TagSet: self.tags}},
624-
self.callback
628+
function(e, d) {
629+
if (e) {
630+
self.callback(e);
631+
} else {
632+
self.callback(e, data);
633+
}
634+
}
625635
);
626636
} else {
627637
self.callback(err, data);

‎test/s3/managed_upload.spec.coffee

+83
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,54 @@ describe 'AWS.S3.ManagedUpload', ->
337337
expect(data.Bucket).to.equal('bucket')
338338
done()
339339

340+
describe 'Location', ->
341+
it 'returns paths with simple string keys for single part uploads', (done) ->
342+
reqs = helpers.mockResponses [
343+
data: ETag: 'ETAG'
344+
]
345+
send {Body: smallbody, ContentEncoding: 'encoding', Key: 'file.ext'}, ->
346+
expect(err).not.to.exist
347+
expect(data.Location).to.equal('https://bucket.s3.mock-region.amazonaws.com/file.ext')
348+
done()
349+
350+
it 'returns paths with simple string keys for multipart uploads', (done) ->
351+
reqs = helpers.mockResponses [
352+
{ data: UploadId: 'uploadId' }
353+
{ data: ETag: 'ETAG1' }
354+
{ data: ETag: 'ETAG2' }
355+
{ data: ETag: 'ETAG3' }
356+
{ data: ETag: 'ETAG4' }
357+
{ data: ETag: 'FINAL_ETAG', Location: 'https://bucket.s3.mock-region.amazonaws.com/file.ext' }
358+
]
359+
send {Body: bigbody, ContentEncoding: 'encoding', Key: 'file.ext'}, ->
360+
expect(err).not.to.exist
361+
expect(data.Location).to.equal('https://bucket.s3.mock-region.amazonaws.com/file.ext')
362+
done()
363+
364+
it 'returns paths with subfolder keys for single part uploads', (done) ->
365+
reqs = helpers.mockResponses [
366+
data: ETag: 'ETAG'
367+
]
368+
send {Body: smallbody, ContentEncoding: 'encoding', Key: 'directory/subdirectory/file.ext'}, ->
369+
expect(err).not.to.exist
370+
expect(data.Location).to.equal('https://bucket.s3.mock-region.amazonaws.com/directory/subdirectory/file.ext')
371+
done()
372+
373+
it 'returns paths with subfolder keys for multipart uploads', (done) ->
374+
reqs = helpers.mockResponses [
375+
{ data: UploadId: 'uploadId' }
376+
{ data: ETag: 'ETAG1' }
377+
{ data: ETag: 'ETAG2' }
378+
{ data: ETag: 'ETAG3' }
379+
{ data: ETag: 'ETAG4' }
380+
{ data: ETag: 'FINAL_ETAG', Location: 'https://bucket.s3.mock-region.amazonaws.com/directory%2Fsubdirectory%2Ffile.ext' }
381+
]
382+
send {Body: bigbody, ContentEncoding: 'encoding', Key: 'folder/file.ext'}, ->
383+
expect(err).not.to.exist
384+
expect(data.Location).to.equal('https://bucket.s3.mock-region.amazonaws.com/directory/subdirectory/file.ext')
385+
done()
386+
387+
340388
if AWS.util.isNode()
341389
describe 'streaming', ->
342390
it 'sends a small stream in a single putObject', (done) ->
@@ -584,6 +632,7 @@ describe 'AWS.S3.ManagedUpload', ->
584632
's3.putObjectTagging'
585633
]
586634
expect(err).not.to.exist
635+
expect(data.Location).to.equal('FINAL_LOCATION')
587636
expect(reqs[6].params.Tagging).to.deep.equal({
588637
TagSet: [
589638
{Key: 'tag1', Value: 'value1'}
@@ -593,6 +642,40 @@ describe 'AWS.S3.ManagedUpload', ->
593642
})
594643
done()
595644

645+
it 'return errors from PutObjectTagging request following a successful multipart upload with tags', (done) ->
646+
reqs = helpers.mockResponses [
647+
{ data: UploadId: 'uploadId' }
648+
{ data: ETag: 'ETAG1' }
649+
{ data: ETag: 'ETAG2' }
650+
{ data: ETag: 'ETAG3' }
651+
{ data: ETag: 'ETAG4' }
652+
{ data: ETag: 'FINAL_ETAG', Location: 'FINAL_LOCATION' }
653+
{ error: { code: 'InvalidRequest' }, data: null }
654+
]
655+
656+
upload = new AWS.S3.ManagedUpload(
657+
service: s3
658+
params: {Body: bigbody}
659+
tags: [
660+
{Key: 'tag1', Value: 'value1'}
661+
{Key: 'tag2', Value: 'value2'}
662+
{Key: 'étiquette', Value: 'valeur à être encodé'}
663+
]
664+
)
665+
666+
send {}, ->
667+
expect(helpers.operationsForRequests(reqs)).to.eql [
668+
's3.createMultipartUpload'
669+
's3.uploadPart'
670+
's3.uploadPart'
671+
's3.uploadPart'
672+
's3.uploadPart'
673+
's3.completeMultipartUpload'
674+
's3.putObjectTagging'
675+
]
676+
expect(err.code).to.equal('InvalidRequest')
677+
done()
678+
596679
it 'should throw when tags are not provided as an array', (done) ->
597680
reqs = helpers.mockResponses [
598681
data: ETag: 'ETAG'

0 commit comments

Comments
 (0)
Please sign in to comment.