Hi.
I am not sure if this is a bug but i expected this behavior because other object data is copied. Please if i am wrong, is it documented what object data is not copied?
This is the code i use to test it:
<?php
// Upload a file & copy it using v2.7.0
$bucket = 'my-bucket';
$localFile = '/path/to/local/image.jpg';
$keyOriginal = 'key-original.jpg';
$keyCopy = 'key-copy.jpg';
function debugObject($s3, $bucket, $key)
{
$object = $s3->getObject(['Bucket' => $bucket, 'Key' => $key]);
$objectAcl = $s3->getObjectAcl(['Bucket' => $bucket, 'Key' => $key]);
$publicGrant = array_filter($objectAcl['Grants'], function ($element) {
return array_key_exists('URI', $element['Grantee']) &&
$element['Grantee']['URI'] === 'http://acs.amazonaws.com/groups/global/AllUsers' &&
$element['Permission'] === 'READ';
});
$isPublic = count($publicGrant) === 1;
echo $key . ': ' . $object['ContentLength'] . ' - ' . $object['CacheControl'] . ' - ' .
$object['Expires'] . ' - ' . $object['ContentType'] . ' - ' .
json_encode($object['Metadata']) . ' - ' .
($isPublic ? 'public' : 'private') . "\n";
}
$s3->putObject([
'Bucket' => $bucket,
'Key' => $keyOriginal,
'SourceFile' => $localFile,
'ACL' => 'public-read',
'CacheControl' => 'max-age=1800',
'Expires' => '1',
'Metadata' => [
'param1' => 'value1',
'param2' => 'value2'
]
]);
debugObject($s3, $bucket, $keyOriginal);
$s3->copyObject([
'Bucket' => $bucket,
'Key' => $keyCopy,
'CopySource' => "{$bucket}/{$keyOriginal}"
]);
debugObject($s3, $bucket, $keyCopy);
And the output:
key-orig.jpg: 27599 - max-age=1800 - Thu, 01 Jan 1970 00:00:01 GMT - image/jpeg - {"param1":"value1","param2":"value2"} - public
key-copy.jpg: 27599 - max-age=1800 - Thu, 01 Jan 1970 00:00:01 GMT - image/jpeg - {"param1":"value1","param2":"value2"} - private
Regards,
Armando
Hey Armando, thanks for the detailed bug report! :smile:
I made sure to double check the S3 object copy docs, and this is not an actual bug. The docs say:
When copying an object, you can preserve most of the metadata (default) or specify new metadata. However, the ACL is not preserved and is set to private for the user making the request.
So, with that in mind, you can just add 'ACL' to your CopyObject request.
$s3->copyObject([
'Bucket' => $bucket,
'Key' => $keyCopy,
'CopySource' => "{$bucket}/{$keyOriginal}",
'ACL' => 'public-read'
]);
Closing as "no-issue", but please reopen if you need additional help. Thanks.
Thanks for clarifying and the quick response!
We are using a library (FlySystem) and found this behavior using the "rename" & "copy" methods, but we can not set any additional options (so the object is always copied as private). So we decide to investigate first this great SDK and clarify it it was a bug or not. Now we will ask for support to the FlySystem team, or look for workarounds.
Regards,
Armando
No problem! FlySystem is a pretty cool library, but it's definitely a tough job to handle all of the little edge cases in each of the adapters. @FrenkyNet, the FlySystem author, knows where to find me though, if he needs help with any S3 questions.
Most helpful comment
Hey Armando, thanks for the detailed bug report! :smile:
I made sure to double check the S3 object copy docs, and this is not an actual bug. The docs say:
So, with that in mind, you can just add
'ACL'to your CopyObject request.