Est-il possible de changer les en-têtes d'un objet S3 sans télécharger tout l'objet?

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

  •  06-07-2019
  •  | 
  •  

Question

J'ai importé plusieurs images sur Amazon S3 et je souhaite maintenant leur ajouter un en-tête Cache-Control.

L'en-tête peut-il être mis à jour sans télécharger l'image entière? Si oui, comment?

Était-ce utile?

La solution

Il s'agit d'une fonctionnalité bêta, mais vous pouvez spécifier de nouvelles métadonnées lorsque copier un objet . Spécifiez les mêmes source et destination pour la copie, ce qui a pour effet de simplement mettre à jour les métadonnées sur votre objet.

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

Autres conseils

Ceci n'est plus en version bêta et est disponible en effectuant une commande put et en copiant l'objet comme documenté ici . Il est également disponible dans leur SDK. Par exemple avec 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);

Voici comment procéder avec AWS SDK pour 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;
}
?>

avec amazon aws-sdk, faire un objet copy_object avec des en-têtes supplémentaires semble être une bonne solution pour définir la mise en cache des en-têtes de contrôle pour un objet S3 existant.

===================== 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 ===================== ===========================

En Java, essayez ceci

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));

Vous pouvez également essayer de copier un objet. Ici, les métadonnées ne seront pas copiées lors de la copie d'un objet. Vous devez obtenir les métadonnées de l'original et définir la demande de copie. Cette méthode est plus recommandée pour insérer ou mettre à jour les métadonnées d'un objet 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);

Voici un code d'aide en 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

    

Explication: Le code ajoute de nouvelles métadonnées à la clé existante, puis copie le même fichier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top