-
If you use
Storage::download(), it would be saving to your server and only after, your code has to perform the pass through download withreadfile(), i.e. the entire file is not read into your memory, instead, bit by bit for a low resource approach to sending big files. -
To do pass through download from S3, you will have to call the
temporaryUrl()and do areadfile()on the temporary URL. -
https://laravel.com/docs/8.x/filesystem#file-urls The temporary URLs can be made to expire in X minutes, this should be sufficient if you are not overly concerned about link sharing, i.e. the download is not a paid product etc
-
#1 is pointless, furthermore if it is a big file, you can imagine nothing will happen at the downloader's side until the file has been transferred to your server.
-
#2 gives you the best security/control such as single download only etc especially if it is a paid product, it will take up some resources, but that's the price required. I think there are easier ways to protect a paid product such as requiring another small download to "activate" this download.
-
#3 is redirecting the downloader to the S3's temporary URL, which will expire in X minutes. It will not tax your server. Since it expires, leechers cannot abuse the temporary link by posting it all over the internet.
-
I would say go for #3.
File Download
Hi,
I am using Laravel 8.
I wanted to run some ideas by some fellow developers to make sure I am understanding the way the file download works in Laravel.
I am using Amazon S3 as my back end storage system and it's all connected and working fine in my system.
I am providing a button so my customers can download files (invoices, videos, etc).
Option 1: Download via Streams
When I use the stock "download" it looks like (based on the source) that it's using streams as discussed here:
https://laravel.com/docs/8.x/filesystem#downloading-files
I understand this such that when I initiate a download it will connect to Amazon s3 and then read the file in real-time and pass "through" my web server for the entire download. As the bits are read from amazon (private bucket authenticated via the Laravel/s3 connector) they are sent back to the user.
Is that correct? Or does it somehow download the file first to a temp file on my web server and then send that back?
I would think with a lot of downloads going concurrently this approach would take a lot of resources from my web server.
Option 2: Temp URL
The other option is to create a Temp URL from Amazon and essentially hand off the download to Amazon as discussed here:
https://sutherlandboswell.com/force-file-download-from-aws-s3-in-laravel/
This would, I would think, just take my web server resources as it's setting up the temp URL and handing it off.
Any replies or insight would be greatly appreciated.
Thanks!
-Rob
Thanks for the reply. In #3 you suggest, this is how I implemented it and it seems to work great (for amazon s3).
public function download($path, $filename)
{
// $path = "some/path/to/file";
// $filename = "foo.mp4"; // the filename that will be downloaded on the customers computer
return redirect(Storage::cloud()->temporaryUrl(
$path,
now()->addHour(),
['ResponseContentDisposition' => 'attachment; filename ="' . $filename . '"']
));
}
Please or to participate in this conversation.