たくさんの画像をAmazonS3にアップロードしましたが、それらにCache-Controlヘッダーを追加したいと思います。
画像全体をダウンロードせずにヘッダーを更新できますか?もしそうなら、どのように?
これはベータ機能ですが、 オブジェクトをコピーする のときに新しいメタデータを指定できます。コピーに同じソースと宛先を指定すると、オブジェクトのメタデータを更新するだけの効果があります。
PUT /myObject HTTP/1.1
Host: mybucket.s3.amazonaws.com
x-amz-copy-source: /mybucket/myObject
x-amz-metadata-directive: REPLACE
x-amz-meta-myKey: newValue
これはベータ版ではなく、putコマンドを実行し、オブジェクトを ここに記載 としてコピーすることで利用できます。 SDKでも利用できます。たとえば、C#の場合:
var s3Client = new AmazonS3Client("publicKey", "privateKey");
var copyRequest = new CopyObjectRequest()
.WithDirective(S3MetadataDirective.REPLACE)
.WithSourceBucket("bucketName")
.WithSourceKey("fileName")
.WithDestinationBucket("bucketName")
.WithDestinationKey("fileName)
.WithMetaData(new NameValueCollection { { "x-amz-meta-yourKey", "your-value }, { "x-amz-your-otherKey", "your-value" } });
var copyResponse = s3Client.CopyObject(copyRequest);
これは、AWS SDK for PHP 2:
<?php
require 'vendor/autoload.php';
use Aws\Common\Aws;
use Aws\S3\Enum\CannedAcl;
use Aws\S3\Exception\S3Exception;
const MONTH = 2592000;
// Instantiate an S3 client
$s3 = Aws::factory('config.php')->get('s3');
// Settings
$bucketName = 'example.com';
$objectKey = 'image.jpg';
$maxAge = MONTH;
$contentType = 'image/jpeg';
try {
$o = $s3->copyObject(array(
'Bucket' => $bucketName,
'Key' => $objectKey,
'CopySource' => $bucketName . '/'. $objectKey,
'MetadataDirective' => 'REPLACE',
'ACL' => CannedAcl::PUBLIC_READ,
'command.headers' => array(
'Cache-Control' => 'public,max-age=' . $maxAge,
'Content-Type' => $contentType
)
));
// print_r($o->ETag);
} catch (Exception $e) {
echo $objectKey . ': ' . $e->getMessage() . PHP_EOL;
}
?>
amazon aws-sdkを使用して、追加のヘッダーを使用してcopy_objectを実行すると、既存のS3オブジェクトのキャッシュ制御ヘッダーを設定するためのトリックが実行されるようです。
===================== x ============================ ===================
<?php
error_reporting(-1);
require_once 'sdk.class.php';
// UPLOAD FILES TO S3
// Instantiate the AmazonS3 class
$options = array("key" => "aws-key" , "secret" => "aws-secret") ;
$s3 = new AmazonS3($options);
$bucket = "bucket.3mik.com" ;
$exists = $s3->if_bucket_exists($bucket);
if(!$exists) {
trigger_error("S3 bucket does not exists \n" , E_USER_ERROR);
}
$name = "cows-and-aliens.jpg" ;
echo " change headers for $name \n" ;
$source = array("bucket" => $bucket, "filename" => $name);
$dest = array("bucket" => $bucket, "filename" => $name);
//caching headers
$offset = 3600*24*365;
$expiresOn = gmdate('D, d M Y H:i:s \G\M\T', time() + $offset);
$headers = array('Expires' => $expiresOn, 'Cache-Control' => 'public, max-age=31536000');
$meta = array('acl' => AmazonS3::ACL_PUBLIC, 'headers' => $headers);
$response = $s3->copy_object($source,$dest,$meta);
if($response->isOk()){
printf("copy object done \n" );
}else {
printf("Error in copy object \n" );
}
?>
======================= x ========================== ======================
Javaでは、これを試してください
S3Object s3Object = amazonS3Client.getObject(bucketName, fileKey);
ObjectMetadata metadata = s3Object.getObjectMetadata();
Map customMetaData = new HashMap();
customMetaData.put("yourKey", "updateValue");
customMetaData.put("otherKey", "newValue");
metadata.setUserMetadata(customMetaData);
amazonS3Client.putObject(new PutObjectRequest(bucketName, fileId, s3Object.getObjectContent(), metadata));
オブジェクトのコピーを試すこともできます。ここでは、オブジェクトのコピー中にメタデータはコピーされません。オリジナルのメタデータを取得し、リクエストをコピーするように設定する必要があります。このメソッドは、AmazonS3オブジェクトのメタデータを挿入または更新することをお勧めします
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);
これがPythonのヘルプコードです。
import boto
one_year = 3600*24*365
cckey = 'cache-control'
s3_connection = S3Connection()
bucket_name = 'my_bucket'
bucket = s3_connection.get_bucket(bucket_name validate=False)
for key in bucket:
key_name = key.key
if key.size == 0: # continue on directories
continue
# Get key object
key = bucket.get_key(key_name)
if key.cache_control is not None:
print("Exists")
continue
cache_time = one_year
#set metdata
key.set_metadata(name=cckey, value = ('max-age=%d, public' % (cache_time)))
key.set_metadata(name='content-type', value = key.content_type)
# Copy the same key
key2 = key.copy(key.bucket.name, key.name, key.metadata, preserve_acl=True)
continue
説明:コードは、既存のキーに新しいメタデータを追加してから、同じファイルをコピーします。