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

fideloper 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

kingsloi 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

skmetaly 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

robfrancken commented May 29, 2018

@fideloper thanks so much, saved me hours.


This comment has been minimized.

Copy link

nwaughachukwuma 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.