Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add Metadata, headers (Expires, CacheControl) to a file uploaded to Amazon S3 using the Laravel 5.0 Storage facade

I am trying to find out how to add in Metadata or headers (Expires, CacheControl etc.) to a file uploaded using the Laravel 5.0 Storage facade. I have use the page here as reference.

http://laravel.com/docs/5.0/filesystem

The following code works correctly:

Storage::disk('s3')->put('/test.txt', 'test');

After digging I also found that there is a 'visibility' parameter which sets the ACL to 'public-read' so the following also works correctly.

Storage::disk('s3')->put('/test.txt', 'test', 'public');

But I would like to be able to set some other values to the header of the file. I have tried the following:

Storage::disk('s3')->put('/index4.txt', 'test', 'public', array('Expires'=>'Expires, Fri, 30 Oct 1998 14:19:41 GMT'));

Which doesn't work, I have also tried:

Storage::disk('s3')->put('/index4.txt', 'test', array('ACL'=>'public-read'));

But that creates an error where the 'visibility' parameter can not be converted from a string to an array. I have checked the source of AwsS3Adapter and it seems there is code for options but I can not seem to see how to pass them correctly. I think it takes the following:

protected static $metaOptions = [
    'CacheControl',
    'Expires',
    'StorageClass',
    'ServerSideEncryption',
    'Metadata',
    'ACL',
    'ContentType',
    'ContentDisposition',
    'ContentLanguage',
    'ContentEncoding',
];

Any help on how to accomplish this would be appreciated.

like image 556
alexmcfarlane Avatar asked Mar 11 '15 14:03

alexmcfarlane


3 Answers

First, you need to call getDriver so you can send over an array of options. And then you need to send the options as an array.

So for your example:

Storage::disk('s3')->getDriver()->put('/index4.txt', 'test', [ 'visibility' => 'public', 'Expires' => 'Expires, Fri, 30 Oct 1998 14:19:41 GMT']);

Be aware that if you're setting Cache-Control it has to be passed as CacheControl. This may well be true for other keys with non-alphanumierc characters.

like image 80
Matt McDonald Avatar answered Nov 17 '22 13:11

Matt McDonald


If you want to have global defaults with headers, this works in Laravel 5.4. Change your config/filesystems.php file like so:

s3' => [
    'driver' => 's3',
    'key' => env('AWS_KEY'),
    'secret' => env('AWS_SECRET'),
    'region' => env('AWS_REGION'),
    'bucket' => env('AWS_BUCKET'),
    'options' => ['CacheControl' => 'max-age=315360000, no-transform, public', 
                  'ContentEncoding' => 'gzip']
],
like image 41
Paras Avatar answered Nov 17 '22 14:11

Paras


After attempting the above answers and failing to be able to add customer user-metadata it turns out that after digging through the SDK code it is a bit easier than I thought (Assume $path is a path to an image file). I didn't appear to need to call the getDriver() method either, not too sure if that makes any difference with the current version of the AWS SDK.

Storage::put(
    'image.jpg',
    file_get_contents($path),
    [
        'visibility' => 'public',
        'Metadata' => [
            'thumb' => '320-180',
        ],
    ]
);

So now if you view the newly uploaded file in S3 you will see the custom metadata:

enter image description here

Hope this helps someone.

like image 9
Countach Avatar answered Nov 17 '22 13:11

Countach