0

This is regards users' uploads - which are hosted in an S3 bucket - and the best approach for downloading them. Currently I use the following:

return response()->streamDownload(function(){
    // Fetch the file
    print Storage::disk('s3')->get('file');

}, 'file-name.ext');

This works just fine, but as you can see, the file is first fetched from S3, then streamed via the server to the user's browser. Which, I think, unnecessary work (calls to S3 and bandwidth), since we could just force-download it off S3 servers instead.

I have two questions here: How to force-download the file off s3, and more importantly; am I giving this too much thought? But I really hate the idea of downloading the file twice and putting more pressure on the server!

Dewan159
  • 2,984
  • 7
  • 39
  • 43
  • Is the file publicly available on S3? – Rwd Aug 29 '20 at 09:08
  • 1
    May be worth a read - [Streaming Amazon S3 Objects From a Web Server Using Laravel](https://stackoverflow.com/questions/31685264/streaming-amazon-s3-objects-from-a-web-server-using-laravel) (more covers the idea in general and not a drop in solution). – Nigel Ren Aug 29 '20 at 09:09
  • @Rwd Yes, it's available publicly – Dewan159 Aug 29 '20 at 09:10
  • Perhaps (from the linked question) a Pre-Signed URL might be worth looking at. This is more for private files which you can allow a temporary link to. – Nigel Ren Aug 29 '20 at 09:18
  • 1
    Then (depending on the file type) you should be able to simply add a link to your page that points to that file. It might also be worth having a look at: https://docs.easydigitaldownloads.com/article/1172-how-do-i-force-files-to-download-in-amazon-s3 – Rwd Aug 29 '20 at 09:19
  • @Rwd I want to force-download the file. Stuff like text files and videos will simply be displayed or played by the browser – Dewan159 Aug 29 '20 at 09:21
  • Did you look at the link I put in my last comment? – Rwd Aug 29 '20 at 09:49

1 Answers1

1

The pre-signed urls feature was the way to go! Here is the code:

$url = Storage::disk('s3')->temporaryUrl($path, now()->addMinutes(5), [
    'ResponseContentDisposition' => "attachment; filename=$fileName.txt"
]);

Dewan159
  • 2,984
  • 7
  • 39
  • 43