Specify Content-Type in AWS PHP's upload function
Asked Answered
Y

3

7

I am migrating my code from AWS PHP SDK1 to SDK2 (https://github.com/aws/aws-sdk-php).

I have an image uploader. In my previous version, I would specify the Content-Type of my image like so:

$response = $this->s3->create_object(
                $bucket,
                $key,
                array(
                    'fileUpload'=>$file_resource,
                    'contentType'=>$mime, 
                    'acl' => AmazonS3::ACL_PUBLIC,
                    )
                );

This is my new version:

$response = $this->s3->upload(
                    $bucket, 
                    $key, 
                    $file_resource, 
                    'public-read',
                    array('params' => array('Metadata' => array('ContentType'=>$mime)))
                    );

I've tried different spellings of ContentType, in the S3 site it modifies the name to look like 'x-amz-meta-contenttype', while the value of 'Content-Type' is the default 'binary/octet-stream'.

I've also tried using the EntityBody feature, but same results:

$response = $this->s3->upload(
                    $this->bucket, 
                    $to, 
                    EntityBody::factory($file_resource), 
                    'public-read',
                    array('params' => array('Metadata' => array('ContentType'=>$mime)))
                    );

How do I set the content-type in this new API?

EDIT: I see somewhere in the documentation:

The AWS SDK for PHP will attempt to automatically determine the most appropriate Content-Type header used to store the object. If you are using a less common file extension and your Content-Type header is not added automatically, you can add a Content-Type header by passing a ContentType option to the operation.

First off, I am uploading simple images, yet according to my S3 dashboard, they are uploaded as 'binary/octet-stream'. About their second point, I've tried many combinations of arrays with 'ContentType' I'm not sure why it's not working...

Yolandayolande answered 19/2, 2014 at 21:1 Comment(0)
Y
18

At the end, this set of options worked:

array('params' => array('ContentType' => $mime))

No need for Metadata

Yolandayolande answered 21/2, 2014 at 6:21 Comment(0)
N
4
  1. Well, using AWS\S3\S3Client::putObject() directly would definitely give you the control you need.

  2. File extensions need to be lowercase for the automatic detection to work.

  3. You can find the list of supported mime types in Guzzle\Http\Mimetypes.

Namesake answered 20/2, 2014 at 9:40 Comment(4)
1) From what I understand, upload() uses putObject behind the scenes, and is the recommended solution for file uploads. 2) Is it the file extension of the source, or of the destination name? My destination are lowercase, and the source are from PHP's temporary location for uploads - which I think have no extensions. 3) As expected, most image extensions are in that list.Yolandayolande
The "source" file is $_FILES["avatar-file"]["tmp_name"], using PHP's handling of uploaded files. Correct me if I am wrong, but I believe the temp names generated by PHP do not keep the file extension...Yolandayolande
I personally use finfo(FILEINFO_MIME_TYPE) to detect mime type, which I used to pass on to the AWS SDK. Worked fine until I switched to the new SDK.Yolandayolande
It's a really strange. Works fine with aws-sdk-php-3.19.8, ubuntu 14.04. php-5.5.9Xenogamy
B
3

I believe the more recent AWS API versions require that the content type be set directly, e.g.

$client->putObject([
       'Bucket'      => $sBucket,
       'Key'         => $sPath,
       'SourceFile'  => $sData,
       'ContentType' => $sMimeType]);
Belford answered 18/2, 2021 at 22:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.