Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload image to S3 using presigned URL

I've been having a hell of a time getting a simple test to work. I am working on a mobile app in react native. I want to generate a presigned URL and use that url to upload a video file to s3. I'm currently just trying to test this approach by doing:

const file = fs.readFileSync('./video.mp4')
s3.getSignedUrl('putObject', {Bucket: 'mybucket', Key: 'video.mp4'}, (err, url) => {
  if (err) { console.log(err); }
  else {
    fetch(url, {
       method: 'PUT',
       body: file
    })
    .then(success => console.log(success.status))
    .catch(e => console.log(e))
  })
})

I get a 200 status code, but the 'file' that appears on S3 has 0 bytes. I noticed the same thing happens when I try to upload ANY file that I received via fs.readFileSync. I managed to work around this temporarily be doing fs.readFileSync('./video.mp4', 'base64'), but this won't work in my app, because I need to access the video in it's original format, not as a base64 string. I also successfully used s3.upload, but that won't work in my app either, because I want to authenticate all my user's actions on my server before I give them permission to do an interaction with s3. I'd really appreaciate some advice. I've been fiddling around with ContentTypes and ContentLengths all day.

like image 326
user2689931 Avatar asked Dec 06 '22 18:12

user2689931


1 Answers

You need to use FormData to wrap your file with parameter named file like following:

var body = new FormData();
body.append('file', file);
fetch(url, { method: 'PUT', body: body });
like image 178
Yi Feng Xie Avatar answered Dec 24 '22 19:12

Yi Feng Xie