2008-11-06 29 views
31

Tôi đã tải lên một loạt các hình ảnh lên Amazon S3, và bây giờ muốn thêm một tiêu đề Cache-Control cho chúng.Có thể thay đổi tiêu đề trên đối tượng S3 mà không cần tải xuống toàn bộ đối tượng không?

Tiêu đề có thể được cập nhật mà không cần tải xuống toàn bộ hình ảnh không? Nếu vậy, làm thế nào?

+0

tiêu đề x-amz-metadata-directive không hoạt động. Nó kết quả trong một không khớp chữ ký mỗi lần. Tất cả các tiêu đề x-amz khác hoạt động tốt. –

Trả lời

34

Chức năng beta, nhưng bạn có thể chỉ định dữ liệu meta mới khi bạn copy an object. Chỉ định cùng một nguồn và đích cho bản sao và điều này có tác dụng chỉ cập nhật dữ liệu meta trên đối tượng của bạn.

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 
+6

đừng quên đưa vào loại Nội dung của đối tượng trong tham số tiêu đề, vì yêu cầu PUT ghi đè tất cả các tiêu đề gốc. –

+0

Nói chung, thao tác sao chép ghi lại tất cả siêu dữ liệu với siêu dữ liệu bạn cung cấp khi nguồn và đích giống nhau. Xem [tài liệu] (http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html) cho '' 'x-amz-metadata-directive''', yêu cầu các yêu cầu sao chép với cùng một đích để chỉ định '' 'REPLACE'''.Nếu bạn muốn bảo vệ người dùng hiện tại hoặc siêu dữ liệu S3, bạn sẽ cần phải nhận siêu dữ liệu của đối tượng hiện có, thêm/thay đổi mục nhập và cung cấp siêu dữ liệu cập nhật trong yêu cầu sao chép của bạn. – pauljm

10

Đây là phiên bản beta và có sẵn bằng cách thực hiện lệnh đặt và sao chép đối tượng là documented here. Nó cũng có sẵn trong SDK của họ. Ví dụ: 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); 
+0

Cảm ơn bạn đã cập nhật. :) – Scott

+0

@Scott hi, nhận được "Một nỗ lực đã được thực hiện để sử dụng một đối tượng mà không phải là, hoặc không còn, có thể sử dụng." Với API mới –

2

với amazon aws-sdk, Thực hiện copy_object với tiêu đề phụ có vẻ như làm mẹo để đặt tiêu đề bộ nhớ đệm cho đối tượng S3 hiện có.

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

7

Đây là cách bạn làm điều đó với AWS SDK cho 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; 
} 
?> 
+0

Điều này làm việc cho tôi với SDK 2. Cảm ơn một bó. – mishka

1

Trong Java, hãy thử này

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

Bạn cũng có thể thử đối tượng sao chép. Ở đây siêu dữ liệu sẽ không sao chép trong khi sao chép một đối tượng. Bạn phải nhận siêu dữ liệu gốc và được đặt để sao chép yêu cầu. Phương pháp này được đề nghị cao hơn để chèn hoặc cập nhật siêu dữ liệu của một đối tượng 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); 
1

Tôi có nhu cầu tương tự và vì vậy tôi đã viết này cho môi trường nodeJS tôi.

https://github.com/newbreedofgeek/s3-bucket-cache-control

Tôi đã thử nghiệm nó, nhưng xin làm do siêng năng của bạn đầu tiên khi nó thay đổi rủi ro.

+0

vẻ đơn giản, tôi đã thực hiện tất cả các thiết lập và cố gắng chạy nhưng nhận được các lỗi này: Cant hoàn .copyObject cho image.jpg, chi tiết lỗi là: {[AccessDenied: Access Denied] thông điệp: 'Access Denied', mã: 'AccessDenied', khu vực: null, thời gian: Thu 28 Tháng một 2016 10:51:24 GMT + 0530 (IST), requestId: 'XXXXXXXXXX', extendedRequestId: 'XXXXXX', statusCode: 403, retryable: false, retryDelay: 30} 'AccessDenied: Access Denied tại Request.extractError (/s3-bucket-cache-control/node_modules/aws-sdk/lib/services/s3.js:329:35) i Hà đã cho quản trị viên n s3fullacess cho người dùng IAM, bất kỳ trợ giúp nào? – thekosmix

0

Đây là mã trợ giúp bằng 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 
 

 

Giải thích: Mã cho biết thêm siêu dữ liệu mới vào khóa hiện tại và sau đó sao chép các tập tin tương tự.

Các vấn đề liên quan