8

I am using the PHP version of Amazon's AWS SDK. I have a bunch of files with an Expires header; I want to delete that header and add a Cache-control header instead. The update_object function lets me add headers but not remove them.

The answers on this question suggest you can update a file's metadata when you copy it, but I have tried it and it doesn't work. Here is what I used:

$response = $s3->copy_object(
    array(
        'bucket' => $bucket,
        'filename' => $file,
    ),
    array(
        'bucket' => $bucket,
        'filename' => $file2,
    ),
    array(
        'acl' => AmazonS3::ACL_PUBLIC,
        'headers' => array(
            'Content-Type' => 'image/jpeg',
            'Cache-Control' => 'public,max-age=30240000',
        ),
        'meta' => array(
            'x-fake-header' => 'something awesome is happening',
        ),
    )
);

However, the copied object has the exact same headers as the original object (Expires and Content-Type only). I've tried all manner of combinations of the above (with and without Content-Type, Cache-control, meta, etc) and get the same result.

How do I reset the metadata?

Community
  • 1
  • 1
DisgruntledGoat
  • 70,219
  • 68
  • 205
  • 290

3 Answers3

7

I've just found that copying to object to itself actually does change the headers properly. I was copying it to a second file for testing purposes to avoid overwriting the original.

But for some strange reason copying to a different file doesn't change the headers, but copying to the same file does.

DisgruntledGoat
  • 70,219
  • 68
  • 205
  • 290
  • This is worded a bit oddly.. why would copying to a different file "change" any headers? Do you mean that it doesn't set headers on the new file? – alex.pilon Nov 25 '13 at 22:15
  • @alex Sorry if it's not clear. It should change the headers because new headers are set in the request. If you copy to the same filename (e.g. FileA.jpg -> FileA.jpg) with the headers parameter it changes the headers, but if you copy to a different file (e.g. FileA.jpg -> FileB.jpg) the supplied headers are not set. – DisgruntledGoat Nov 26 '13 at 01:37
3

Based on Jeffin P S's answer (which works great), I'm proposing a version that creates the new metadata object by cloning the original one. This way, the AWS-specific (non-user) metadata do not get converted into user metadata. Not sure if that would be a real issue, but seems more legit this way.

ObjectMetadata metadataCopy = amazonS3Client.getObjectMetadata(bucketName, fileKey).clone();
metadataCopy.addUserMetadata("yourKey", "updateValue");
metadataCopy.addUserMetadata("otherKey", "newValue");

CopyObjectRequest request = new CopyObjectRequest(bucketName, fileKey, bucketName, fileKey)
      .withSourceBucketName(bucketName)
      .withSourceKey(fileKey)
      .withNewObjectMetadata(metadataCopy);

amazonS3Client.copyObject(request);
Alex Rosiu
  • 31
  • 1
2

In Java, You can copy object to the same location. Here metadata will not copy while copying an Object. You have to get metadata of original and set to copy request. This method is more recommended to insert or update metadata of an Amazon S3 object

ObjectMetadata metadata = amazonS3Client.getObjectMetadata(bucketName, fileKey);
ObjectMetadata metadataCopy = new ObjectMetadata();
metadataCopy.addUserMetadata("yourKey", "updateValue");
metadataCopy.addUserMetadata("otherKey", "newValue");
metadataCopy.addUserMetadata("existingKey", metadata.getUserMetaDataOf("existingValue"));

CopyObjectRequest request = new CopyObjectRequest(bucketName, fileKey, bucketName, fileKey)
      .withSourceBucketName(bucketName)
      .withSourceKey(fileKey)
      .withNewObjectMetadata(metadataCopy);

amazonS3Client.copyObject(request);