rowanwins / vue-dropzone

A Vue.js component for Dropzone.js - a drag’n’drop file uploads utility with image previews
https://rowanwins.github.io/vue-dropzone/docs/dist
MIT License
2.02k stars 1.4k forks source link

S3 : file uploaded damaged/corrupted #568

Open Geminii opened 4 years ago

Geminii commented 4 years ago

Hi :)

I followed the getting started to integrate it into my project . Code looks like :

<dropzone
        id="foo"
        ref="el"
        :options="options"
        :awss3="awss3"
        :destroy-dropzone="true"
        @vdropzone-s3-upload-error="s3UploadError"
        @vdropzone-s3-upload-success="s3UploadSuccess"
      />

data () {
    return {
      awss3: {
        signingURL: 'http://localhost:9999/scan/signedUrl',
        headers: {
          Authorization: 'Bearer ...'
        },
        params: {},
        sendFileToServer: false, // Not working if it true value
        withCredentials: false
      },
      options: {
        method: 'PUT', // Doesn't work in POST method
        url: 'http://localhost:9999/scan/attachments'
      }
    }
  },

Problem : Upload of my file (pdf, png) works and is present on my S3 bucket but when i try to download it, the file is always corrupted/damaged :( How can i fix it ? Did i miss something into the configuration ?

Capture d’écran 2020-07-31 à 13 30 54

The call on http://localhost:9999/scan/signedUrl return :

{
   "signature":{
      "Content-Type":"",
      "acl":"public-read-write",
      "success_action_status":"201",
      "policy":"*",
      "X-amz-credential":"AKIAIM3ZELP3PLQLOYDQ\/20171012\/us-west-2\/s3\/aws4_request",
      "X-amz-algorithm":"AWS4-HMAC-SHA256",
      "X-amz-date":"20171012T054729Z",
      "X-amz-signature":"5220d84360d92ef8al47549905b3746f2f1d6641df8986aamcr939c35513cd7c",
      "key":""
   },
   "postEndpoint":"https://my-bucket.s3.eu-central-1.amazonaws.com/test/test.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20171012T054729Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=AKIAIM3ZELP3PLQLOYDQ\/20171012\/us-west-2\/s3\/aws4_request&X-Amz-Signature=5220d84360d92ef8al47549905b3746f2f1d6641df8986aamcr939c35513cd7c""
}

Thanks a lot for your help :) Thanks for this great intregration of DropzoneJs.

tommykamkcm commented 3 years ago

Hi @Geminii and @rowanwins , I faced the same problem when getting a signed url (operation: putObject) using AWS Javascript SDK. FYR: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property

After looking into this issue, my understandings are:

  1. If you compare the content of the corrupted file (in my case it's a PNG) with the form data with a text editor, you should find that they're the same. It seems like AWS S3 stores the entire form data into the file rather than just the PNG content
  2. If you go to sendS3Handler(response, file), you will see this plugin always send file to S3 bucket (or postEndpoint) using POST method.

Here is the idea to get things work:

For instance:

// urlsigner.js - line 59
request.open('PUT', response.putEndpoint);
// urlsigner.js - line 85
request.send(file);

I'll try to implement the above solution in the next couple of days, will update the result here. 🤞

tommykamkcm commented 3 years ago

Hi @Geminii and @rowanwins, I did a PoC and it kind of works except the response has a non-201 status code.

I reckon adding success_action_status: 201 to URL signer's response will resolve the issue.

Here is code of my PoC (I know it's not perfect, so I'm not going to create any PR) image

Finally, I'd recommend this article which discuss the difference between PUT and POST pre-signed url pretty well.