Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Stream file from S3 to browser, assume Laravel Filesystem usage
* Get File Information
// Assuming these come from some data source in your app
$s3FileKey = 's3/key/path/to/file.ext';
$fileName = 'file.ext';
// Create temporary download link and redirect
$adapter = Storage::disk('s3')->getAdapter();
$client = $adapter->getClient();
$object = $client->headObject([
'Bucket' => $adapter->getBucket(),
'Key' => /*$adapter->getPathPrefix() . */$s3FileKey,
* Set headers to allow browser to force a download
header('Last-Modified: '.$object['LastModified']);
// header('Etag: '.$object['ETag']); # We are not implementing validation caching here, but we could!
header('Accept-Ranges: '.$object['AcceptRanges']);
header('Content-Length: '.$object['ContentLength']);
header('Content-Type: '.$object['ContentType']);
header('Content-Disposition: attachment; filename='.$fileName);
* Stream file to the browser
// Open a stream in read-only mode
if (!($stream = fopen("s3://{$adapter->getBucket()}/{$s3FileKey}", 'r'))) {
throw new \Exception('Could not open stream for reading file: ['.$s3FileKey.']');
// Check if the stream has more data to read
while (!feof($stream)) {
// Read 1024 bytes from the stream
echo fread($stream, 1024);
// Be sure to close the stream resource when you're done with it

This comment has been minimized.

Copy link
Owner Author

commented Aug 7, 2017


Docs on HeadObject S3 API call:

Example streaming file and explanation on "$client->registerStreamWrapper()" method:

Force file download via Content-Disposition header:


This comment has been minimized.

Copy link

commented Mar 23, 2018

Hey @fideloper, I bought your Scaling Laravel course and slowly but surely implementing all that good stuff into my app! I've just implemented your S3FileStream class, but not 100% sure how to test (or specially how to mock S3). Can you share any ideas your have re: testing against that class?


This comment has been minimized.

Copy link

commented Apr 18, 2018

hey @fideloper . There's an extra paranthesis at the end of

header('Content-Disposition: attachment; filename='.$fileName));

causing a syntax error

Fideloper Update: Fixed that, thanks!


This comment has been minimized.

Copy link

commented May 29, 2018

@fideloper thanks so much, saved me hours.


This comment has been minimized.

Copy link

commented Nov 18, 2018

@fideloper thanks for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.