From 391d227f7facda0ed843ef1b45fdf10c12ba4636 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 8 Aug 2023 12:10:03 +0200 Subject: [PATCH 1/4] @uppy/aws-s3-multipart: pass the `uploadURL` back to the caller --- packages/@uppy/aws-s3-multipart/src/index.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/@uppy/aws-s3-multipart/src/index.js b/packages/@uppy/aws-s3-multipart/src/index.js index 1145ae3a30..20f6b5d4e8 100644 --- a/packages/@uppy/aws-s3-multipart/src/index.js +++ b/packages/@uppy/aws-s3-multipart/src/index.js @@ -666,7 +666,13 @@ export default class AwsS3Multipart extends UploaderPlugin { // NOTE This must be allowed by CORS. const etag = ev.target.getResponseHeader('ETag') + const location = ev.target.getResponseHeader('Location') + if (location === null) { + // Not being able to read the Location header is not a fatal error. + // eslint-disable-next-line no-console + console.warn('AwsS3/Multipart: Could not read the Location header. This likely means CORS is not configured correctly on the S3 Bucket. See https://uppy.io/docs/aws-s3-multipart#S3-Bucket-Configuration for instructions.') + } if (etag === null) { reject(new Error('AwsS3/Multipart: Could not read the ETag header. This likely means CORS is not configured correctly on the S3 Bucket. See https://uppy.io/docs/aws-s3-multipart#S3-Bucket-Configuration for instructions.')) return @@ -675,6 +681,7 @@ export default class AwsS3Multipart extends UploaderPlugin { onComplete?.(etag) resolve({ ETag: etag, + location, }) }) From f41df9e1cd0be236e98e576ca1dc0496ccacbfeb Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 8 Aug 2023 13:08:51 +0200 Subject: [PATCH 2/4] fix multipart upload --- packages/@uppy/aws-s3-multipart/src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@uppy/aws-s3-multipart/src/index.js b/packages/@uppy/aws-s3-multipart/src/index.js index 20f6b5d4e8..23493e6c5d 100644 --- a/packages/@uppy/aws-s3-multipart/src/index.js +++ b/packages/@uppy/aws-s3-multipart/src/index.js @@ -668,7 +668,7 @@ export default class AwsS3Multipart extends UploaderPlugin { const etag = ev.target.getResponseHeader('ETag') const location = ev.target.getResponseHeader('Location') - if (location === null) { + if (method === 'POST' && location === null) { // Not being able to read the Location header is not a fatal error. // eslint-disable-next-line no-console console.warn('AwsS3/Multipart: Could not read the Location header. This likely means CORS is not configured correctly on the S3 Bucket. See https://uppy.io/docs/aws-s3-multipart#S3-Bucket-Configuration for instructions.') @@ -681,7 +681,7 @@ export default class AwsS3Multipart extends UploaderPlugin { onComplete?.(etag) resolve({ ETag: etag, - location, + ...(location ? { location } : undefined), }) }) From 63bc7a309b6bae52b45358e4e53865affd4b5e53 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 8 Aug 2023 13:26:26 +0200 Subject: [PATCH 3/4] add test --- .../@uppy/aws-s3-multipart/src/index.test.js | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/@uppy/aws-s3-multipart/src/index.test.js b/packages/@uppy/aws-s3-multipart/src/index.test.js index 53eb7194b8..b3f59d3d7a 100644 --- a/packages/@uppy/aws-s3-multipart/src/index.test.js +++ b/packages/@uppy/aws-s3-multipart/src/index.test.js @@ -39,6 +39,61 @@ describe('AwsS3Multipart', () => { }) }) + describe('non-multipart upload', () => { + it('should handle POST uploads', async () => { + const core = new Core() + core.use(AwsS3Multipart, { + shouldUseMultipart: false, + limit: 0, + getUploadParameters: () => ({ + method: 'POST', + url: 'https://bucket.s3.us-east-2.amazonaws.com/', + fields: {}, + }), + }) + const scope = nock( + 'https://bucket.s3.us-east-2.amazonaws.com', + ).defaultReplyHeaders({ + 'access-control-allow-headers': '*', + 'access-control-allow-method': 'POST', + 'access-control-allow-origin': '*', + 'access-control-expose-headers': 'ETag, Location', + }) + + scope.options('/').reply(204, '') + scope + .post('/') + .reply(201, '', { ETag: 'test', Location: 'http://example.com' }) + + const fileSize = 1 + + core.addFile({ + source: 'jest', + name: 'multitest.dat', + type: 'application/octet-stream', + data: new File([new Uint8Array(fileSize)], { + type: 'application/octet-stream', + }), + }) + + const uploadSuccessHandler = jest.fn() + core.on('upload-success', uploadSuccessHandler) + + await core.upload() + + expect(uploadSuccessHandler.mock.calls).toHaveLength(1) + expect(uploadSuccessHandler.mock.calls[0][1]).toStrictEqual({ + body: { + ETag: 'test', + location: 'http://example.com', + }, + uploadURL: 'http://example.com', + }) + + scope.done() + }) + }) + describe('without companionUrl (custom main functions)', () => { let core let awsS3Multipart From 0a32ae12da39a6f43fd000e98d41563d796f3ad4 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 14 Aug 2023 16:16:25 +0200 Subject: [PATCH 4/4] fix HTTP method string compare --- packages/@uppy/aws-s3-multipart/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@uppy/aws-s3-multipart/src/index.js b/packages/@uppy/aws-s3-multipart/src/index.js index 516decac38..42dea6fe8e 100644 --- a/packages/@uppy/aws-s3-multipart/src/index.js +++ b/packages/@uppy/aws-s3-multipart/src/index.js @@ -668,7 +668,7 @@ export default class AwsS3Multipart extends UploaderPlugin { const etag = ev.target.getResponseHeader('ETag') const location = ev.target.getResponseHeader('Location') - if (method === 'POST' && location === null) { + if (method.toUpperCase() === 'POST' && location === null) { // Not being able to read the Location header is not a fatal error. // eslint-disable-next-line no-console console.warn('AwsS3/Multipart: Could not read the Location header. This likely means CORS is not configured correctly on the S3 Bucket. See https://uppy.io/docs/aws-s3-multipart#S3-Bucket-Configuration for instructions.')