Browse Source

s3: Use XHRUpload plugin internally.

Renée Kooi 7 years ago
parent
commit
89486e00c4
3 changed files with 62 additions and 70 deletions
  1. 0 2
      examples/aws-presigned-url/main.js
  2. 34 32
      src/plugins/AwsS3/index.js
  3. 28 36
      website/src/docs/aws-s3.md

+ 0 - 2
examples/aws-presigned-url/main.js

@@ -1,6 +1,5 @@
 const Uppy = require('uppy/lib/core/Core.js')
 const Dashboard = require('uppy/lib/plugins/Dashboard')
-const XHRUpload = require('uppy/lib/plugins/XHRUpload')
 const AwsS3 = require('uppy/lib/plugins/AwsS3')
 
 const uppy = Uppy({
@@ -12,7 +11,6 @@ uppy.use(Dashboard, {
   inline: true,
   target: 'body'
 })
-uppy.use(XHRUpload)
 uppy.use(AwsS3, {
   getUploadParameters (file) {
     // Send a request to our PHP signing endpoint.

+ 34 - 32
src/plugins/AwsS3/index.js

@@ -1,4 +1,5 @@
 const Plugin = require('../Plugin')
+const XHRUpload = require('../XHRUpload')
 
 module.exports = class AwsS3 extends Plugin {
   constructor (core, opts) {
@@ -47,37 +48,6 @@ module.exports = class AwsS3 extends Plugin {
       })
     })
 
-    this.core.setState({
-      xhrUpload: Object.assign({}, this.core.state.xhrUpload, {
-        responseUrlFieldName: 'location',
-        getResponseData (xhr) {
-          // If no response, we've hopefully done a PUT request to the file
-          // in the bucket on its full URL.
-          if (!xhr.responseXML) {
-            return { location: xhr.responseURL }
-          }
-          function getValue (key) {
-            const el = xhr.responseXML.querySelector(key)
-            return el ? el.textContent : ''
-          }
-          return {
-            location: getValue('Location'),
-            bucket: getValue('Bucket'),
-            key: getValue('Key'),
-            etag: getValue('ETag')
-          }
-        },
-        getResponseError (xhr) {
-          // If no response, we don't have a specific error message, use the default.
-          if (!xhr.responseXML) {
-            return
-          }
-          const error = xhr.responseXML.querySelector('Error > Message')
-          return new Error(error.textContent)
-        }
-      })
-    })
-
     return Promise.all(
       fileIDs.map((id) => {
         const file = this.core.getFile(id)
@@ -106,7 +76,6 @@ module.exports = class AwsS3 extends Plugin {
           method,
           formData: method.toLowerCase() === 'post',
           endpoint: url,
-          fieldName: 'file',
           metaFields: Object.keys(fields)
         }
 
@@ -134,9 +103,42 @@ module.exports = class AwsS3 extends Plugin {
 
   install () {
     this.core.addPreProcessor(this.prepareUpload)
+
+    this.core.use(XHRUpload, {
+      fieldName: 'file',
+      responseUrlFieldName: 'location',
+      getResponseData (xhr) {
+        // If no response, we've hopefully done a PUT request to the file
+        // in the bucket on its full URL.
+        if (!xhr.responseXML) {
+          return { location: xhr.responseURL }
+        }
+        function getValue (key) {
+          const el = xhr.responseXML.querySelector(key)
+          return el ? el.textContent : ''
+        }
+        return {
+          location: getValue('Location'),
+          bucket: getValue('Bucket'),
+          key: getValue('Key'),
+          etag: getValue('ETag')
+        }
+      },
+      getResponseError (xhr) {
+        // If no response, we don't have a specific error message, use the default.
+        if (!xhr.responseXML) {
+          return
+        }
+        const error = xhr.responseXML.querySelector('Error > Message')
+        return new Error(error.textContent)
+      }
+    })
   }
 
   uninstall () {
+    const uploader = this.core.getPlugin('XHRUpload')
+    this.core.removePlugin(uploader)
+
     this.core.removePreProcessor(this.prepareUpload)
   }
 }

+ 28 - 36
website/src/docs/aws-s3.md

@@ -6,16 +6,11 @@ permalink: docs/aws-s3/
 ---
 
 The `AwsS3` plugin can be used to upload files directly to an S3 bucket.
-
-As of now, the `AwsS3` plugin "decorates" the XHRUpload plugin.
-To upload files directly to S3, both the XHRUpload and AwsS3 plugins must be used:
+Uploads can be signed using [uppy-server][uppy-server docs] or a custom signing function.
 
 ```js
-// No options have to be provided to the XHRUpload plugin,
-// the S3 plugin will configure it.
-uppy.use(XHRUpload)
 uppy.use(AwsS3, {
-  // Options for S3
+  // Options
 })
 ```
 
@@ -26,7 +21,6 @@ uppy.use(AwsS3, {
 When using [uppy-server][uppy-server docs] to sign S3 uploads, set this option to the root URL of the uppy-server.
 
 ```js
-uppy.use(XHRUpload)
 uppy.use(AwsS3, {
   host: 'https://uppy-server.my-app.com/'
 })
@@ -134,35 +128,33 @@ That way, no private keys to the S3 bucket need to be shared on the client.
 For example, there could be a PHP server endpoint that prepares a presigned URL for a file:
 
 ```js
-uppy
-  .use(XHRUpload)
-  .use(AwsS3, {
-    getUploadParameters (file) {
-      // Send a request to our PHP signing endpoint.
-      return fetch('/s3-sign.php', {
-        method: 'post',
-        // Send and receive JSON.
-        headers: {
-          accept: 'application/json',
-          'content-type': 'application/json'
-        },
-        body: JSON.stringify({
-          filename: file.name,
-          contentType: file.type
-        })
-      }).then((response) => {
-        // Parse the JSON response.
-        return response.json()
-      }).then((data) => {
-        // Return an object in the correct shape.
-        return {
-          method: data.method,
-          url: data.url,
-          fields: {}
-        }
+uppy.use(AwsS3, {
+  getUploadParameters (file) {
+    // Send a request to our PHP signing endpoint.
+    return fetch('/s3-sign.php', {
+      method: 'post',
+      // Send and receive JSON.
+      headers: {
+        accept: 'application/json',
+        'content-type': 'application/json'
+      },
+      body: JSON.stringify({
+        filename: file.name,
+        contentType: file.type
       })
-    }
-  })
+    }).then((response) => {
+      // Parse the JSON response.
+      return response.json()
+    }).then((data) => {
+      // Return an object in the correct shape.
+      return {
+        method: data.method,
+        url: data.url,
+        fields: {}
+      }
+    })
+  }
+})
 ```
 
 See the [aws-presigned-url example in the uppy repository](https://github.com/transloadit/uppy/tree/master/examples/aws-presigned-url) for a small example that implements both the server-side and the client-side.