Ver Fonte

@uppy/aws-s3-multipart: pass the `uploadURL` back to the caller (#4614)

* @uppy/aws-s3-multipart: pass the `uploadURL` back to the caller

* fix multipart upload

* add test

* fix HTTP method string compare
Antoine du Hamel há 1 ano atrás
pai
commit
0ac6478fcd

+ 7 - 0
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 (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.')
+        }
         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 ? { location } : undefined),
         })
       })
 

+ 55 - 0
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