0

I am trying to download a file from outside of my root directory however every time I try, it tries to take it from the root directory. I will need the user of my site to be able to download these files.

The file has initially been uploaded to Amazon S3 and I have accessed it using the getObject function.

Here is my code:

app.get('/test_script_api', function(req, res){
    var fileName = req.query.File;
    s3.getObject(
        { Bucket: "bucket-name", Key: fileName },
        function(error, s3data){
            if(error != null){
                console.log("Failed to retrieve an object: " + error);
            }else{
                //I have tried passing the S3 data but it asks for a string
                res.download(s3data.Body);

                //So I have tried just passing the file name & an absolute path
                res.download(fileName);
            }
        }
    );
});

This returns the following error: Error: ENOENT: no such file or directory, stat '/home/ec2-user/environment/test2.txt'

When I enter an absolute path it just appends this onto the end of /home/ec2-user/environment/

How can I change the directory res.download is trying to download from?

Is there an easier way to download your files from Amazon S3?

Any help would be much appreciated here!

Alex Morrison
  • 186
  • 5
  • 18

1 Answers1

1

I had the same problem and I found this answer: NodeJS How do I Download a file to disk from an aws s3 bucket?

Based on that, you need to use createReadStream() and pipe(). R here more about stream.pipe() - https://nodejs.org/en/knowledge/advanced/streams/how-to-use-stream-pipe/

res.attachment() will set the headers for you. -> https://expressjs.com/en/api.html#res.attachment.

This code should work for you (based on the answer in the above link):

app.get('/test_script_api', function (req, res) {
  var fileName = req.query.File;
  res.attachment(fileName);
  var file = s3.getObject({
    Bucket: "bucket-name",
    Key: fileName
    }).createReadStream()
      .on("error", error => {
      });
   file.pipe(res);
});

In my case, on the client side, I used <a href="URL to my route" download="file name"></a> This made sure that the file is downloading.

Irene
  • 11
  • 3