Можно ли изменить заголовки объекта S3 без загрузки всего объекта?

StackOverflow https://stackoverflow.com/questions/269840

  •  06-07-2019
  •  | 
  •  

Вопрос

Я загрузил кучу изображений на Amazon S3 и теперь хочу добавить к ним заголовок 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

Другие советы

Вот как вы это делаете с AWS SDK для 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));

Вы также можете попробовать скопировать объект. Здесь метаданные не будут копироваться при копировании объекта. Вы должны получить метаданные оригинала и установить копию запроса. Этот метод рекомендуется использовать для вставки или обновления метаданных объекта Amazon S3

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

    

Объяснение:Код добавляет новые метаданные к существующему ключу, а затем копирует тот же файл.

scroll top