PHP AWS api raw request to PUT bucket lifecycle

可紊 提交于 2019-12-24 08:57:53

问题


I am creating a website, in which there is a feature that if user delete a image/video it will be archived, I am using AWS S3 for storing and on delete want to move it on Glacier, I dont want to use AWS SDK, so i am creating Raw request using PHP cURL, from this link i tried to Put bucket lifecycle on an object, http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html and done some code, but it give me error of mismatch signature,

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

This is my code, in this i want to apply lifecycle on x.php which is inside a bucket, apply lifecycle for expire it, What i am doing wrong? Help me,

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

回答1:


I think you do not fully understand how the lifecycle policy works.

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

You do not move individual files. You configure a prefix. that should be in your XML document. You already have this

<Prefix>/</Prefix>

  1. PUT lifecycle should always be to /?lifecycle. And you put it as /x.php
  2. It would probably be better to use AWS Signature V4 as opposed to V2 as some newer regions do not support Signature V2 but all regions support Signature V4. More info here: http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
  3. With Signature V4, even if you do see the error message SignatureDoesNotMatch you should also see other messages, <StringToSignBytes></StringToSignBytes> and <CanonicalRequest></CanonicalRequest>. These should be more than enough for you to isolate and solve this issue.
  4. You mention you want to move it to GLACIER but you do not mention this in your XML content. Refer to "Example 1: Add lifecycle configuration - bucket not versioning-enabled" section on this page for http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html You would need <StorageClass>GLACIER</StorageClass> in your XML.

Hope this helps.



来源:https://stackoverflow.com/questions/42692610/php-aws-api-raw-request-to-put-bucket-lifecycle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!