2017-03-09 2 views
1

Je crée un site web, dans lequel il y a une fonctionnalité qui si l'utilisateur supprime une image/vidéo, il sera archivé, j'utilise AWS S3 pour le stockage et sur supprimer vouloir déplacer sur Glacier, je ne veux pas utiliser AWS SDK, donc je crée une requête Raw en utilisant PHP cURL, à partir de ce lien j'ai essayé de mettre le cycle de vie bucket sur un objet, et fait du code, mais ça me donne une erreur de signature mismatch,PHP AWS api demande brute pour PUT bucket lifecycle

SignatureDoesNotMatch-The request signature we calculated does not match the signature you provided. Check your key and signing method.

Ceci est mon code, dans ce que je veux appliquer le cycle de vie sur x.php qui se trouve dans un seau, appliquer le cycle de vie pour d'expirer, Qu'est-ce que je fais mal? Aidez-moi,

$AWSaccessKey = 'xxxxxxxxxxxxxxxx'; 
$AWSsecretKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxx'; 
$AWSregion = 'xxxxxxxxx'; 

// bucket 
$bucket = 'xxxxxxxx'; 
$postdata = $filedata = '<LifecycleConfiguration> 
    <Rule> 
    <Filter> 
     <Prefix>/</Prefix> 
    </Filter> 
    <Status>Enabled</Status> 
    <Expiration> 
     <Days>0</Days> 
    </Expiration> 
    </Rule> 
</LifecycleConfiguration>'; 
$filetype = 'text/plain'; 
$path  = '/x.php'; // file on which i want to put lifecycle to move it to GLACIER 

// file md5 
$file_md5 = base64_encode(md5($filedata, true)); 

// file size 
$filesize = strlen($filedata); 

// date 
$date = gmdate('D, d M Y H:i:s').' +0000'; 

// -> for putting lifecycle config 
$params = array(
    'x-amz-date'   => gmdate('D, d M Y H:i:s \\G\\M\\T'), 
); 
//'x-amz-security-token'=> $auth['Token'] 

// sort and stringify params (different to other requests, this is formatted like headers) 
$params_str = ''; 
uksort($params, 'strcmp'); 
foreach($params as $k=>$v){ 
    $params_str .= $k.': '.$v."\\n"; 
} 

// -> for putting lifecycle config 
$to_sign = "PUT\\n$file_md5\\n$filetype\\n\\n".$params_str.'/'.$bucket.$path; 

// create signature 
// Note: S3 uses SHA1 instead of 256! 
$signature = base64_encode(hash_hmac('SHA1', $to_sign, $AWSsecretKey, true)); 

$headers = "Host: $bucket.s3.amazonaws.com\\n"; // change to your region 
$headers .= $params_str; // note that the params get added to the header 
$headers .= 'Content-MD5: '.$file_md5."\\n"; 
$headers .= 'Authorization: AWS '.$AWSaccessKey.':'.$signature."\\n"; 
$headers .= 'Content-Length: '.$filesize."\\n"; 

$ch = curl_init("http://$bucket.s3-$AWSregion.amazonaws.com"); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 
curl_setopt($ch, CURLOPT_HTTPHEADER, explode('\n', $headers)); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); 
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_VERBOSE, true); 
curl_setopt($ch, CURLOPT_STDERR, fopen(dirname(__FILE__).'/errorlog.txt', 'w')); 

$result = curl_exec($ch); 
var_dump($result); 
+0

Il peut être plus simple de définir une règle de cycle de vie permanent sur un chemin spécifique (par exemple 's3 :: bucket/archive /'). Ensuite, déplacez le fichier vers ce chemin pour le faire archiver. (Bien sûr, il n'y a pas de 'déplacement', cela impliquerait en fait une copie et une suppression.) –

Répondre

1

Je pense que vous ne comprenez pas complètement comment fonctionne la politique de cycle de vie.

$path = '/x.php'; // file on which i want to put lifecycle to move it to GLACIER

Vous ne déplacez pas les fichiers individuels. Vous configurez un préfixe. qui devrait être dans votre document XML. Vous avez déjà ce

<Prefix>/</Prefix>

  1. cycle de vie PUT doit toujours être à /?lifecycle. Et vous le mettez comme /x.php
  2. Il serait probablement préférable d'utiliser AWS Signature V4 par opposition à V2 car certaines régions plus récentes ne prennent pas en charge la signature V2, mais toutes les régions prennent en charge la signature V4. Plus d'informations ici: http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
  3. Avec Signature V4, même si vous voyez le message d'erreur SignatureDoesNotMatch, vous devez également voir les autres messages, <StringToSignBytes></StringToSignBytes> et <CanonicalRequest></CanonicalRequest>. Celles-ci devraient être plus que suffisantes pour isoler et résoudre ce problème.
  4. Vous mentionnez que vous voulez le déplacer vers GLACIER mais vous ne le mentionnez pas dans votre contenu XML. Reportez-vous à la section "Exemple 1: Ajouter une configuration de cycle de vie - bucket not versioning-enabled" de cette page pour http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html Vous avez besoin de <StorageClass>GLACIER</StorageClass> dans votre fichier XML.

Espérons que cela aide.