我一直在尝试使用 AWS“官方”命令行工具 s3curl.pl 来测试最近宣布的多对象删除功能。以下是我所做的:
首先,我使用一组凭证顺利地测试了 s3curl.pl:
$ s3curl.pl --id=s3 -- http://testbucket-0.s3.amazonaws.com/|xmllint --format -
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 884 0 884 0 0 4399 0 --:--:-- --:--:-- --:--:-- 5703
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>testbucket-0</Name>
<Prefix/>
<Marker/>
<MaxKeys>1000</MaxKeys>
<IsTruncated>false</IsTruncated>
<Contents>
<Key>file_1</Key>
<LastModified>2012-03-22T17:08:17.000Z</LastModified>
<ETag>"ee0e521a76524034aaa5b331842a8b4e"</ETag>
<Size>400000</Size>
<Owner>
<ID>e6d81ea69572270e58d3814ab674df8c8f1fd5d502669633a4951bdd5185f7f4</ID>
<DisplayName>zackp</DisplayName>
</Owner>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>file_2</Key>
<LastModified>2012-03-22T17:08:19.000Z</LastModified>
<ETag>"6b32cbf8219a59690a9f69ba6ff3f590"</ETag>
<Size>600000</Size>
<Owner>
<ID>e6d81ea69572270e58d3814ab674df8c8f1fd5d502669633a4951bdd5185f7f4</ID>
<DisplayName>zackp</DisplayName>
</Owner>
<StorageClass>STANDARD</StorageClass>
</Contents>
</ListBucketResult>
然后,我按照 s3curl.pl 的使用说明进行操作:
s3curl.pl --help
Usage /usr/local/bin/s3curl.pl --id friendly-name (or AWSAccessKeyId) [options] -- [curl-options] [URL]
options:
--key SecretAccessKey id/key are AWSAcessKeyId and Secret (unsafe)
--contentType text/plain set content-type header
--acl public-read use a 'canned' ACL (x-amz-acl header)
--contentMd5 content_md5 add x-amz-content-md5 header
--put <filename> PUT request (from the provided local file)
--post [<filename>] POST request (optional local file)
--copySrc bucket/key Copy from this source key
--createBucket [<region>] create-bucket with optional location constraint
--head HEAD request
--debug enable debug logging
common curl options:
-H 'x-amz-acl: public-read' another way of using canned ACLs
-v verbose logging
然后,我尝试了以下操作,但总是返回错误。如果有人能指出我哪里犯了错误,我将不胜感激。
$ s3curl.pl --id=s3 --post multi_delete.xml -- http://testbucket-0.s3.amazonaws.com/?delete
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><StringToSignBytes>50 4f 53 54 0a 0a 0a 54 68 75 2c 20 30 35 20 41 70 72 20 32 30 31 32 20 30 30 3a 35 30 3a 30 38 20 2b 30 30 30 30 0a 2f 7a 65 74 74 61 72 2d 74 2f 3f 64 65 6c 65 74 65</StringToSignBytes><RequestId>707FBE0EB4A571A8</RequestId><HostId>mP3ZwlPTcRqARQZd6gU4UvBrxGBNIVa0VVe5p0rqGmq5hM65RprwcG/qcXe+pmDT</HostId><SignatureProvided>edkNGuugiSFe0ku4eGzkh8kYgHw=</SignatureProvided><StringToSign>POST
Thu, 05 Apr 2012 00:50:08 +0000
文件 multi_delete.xml 包含以下内容:
cat multi_delete.xml
<?xml version="1.0" encoding="UTF-8"?>
<Delete>
<Quiet>true</Quiet>
<Object>
<Key>file_1</Key>
<VersionId> </VersionId>>
</Object>
<Object>
<Key>file_2</Key>
<VersionId> </VersionId>
</Object>
</Delete>
谢谢你的帮助!
--扎克
答案1
这对我有用(Amazon Linux AMI v2012.03; us-east-1):
下载并解压最新的 s3curl.zip
wget http://s3.amazonaws.com/doc/s3-example-code/s3-curl.zip
unzip s3-curl.zip
使可执行文件:
cd s3-curl
chmod +x s3-curl
创建凭证文件(.s3curl):
%awsSecretAccessKeys = (
# personal account
personal => {
id => 'XXXXXXXXXXXXXXXXXXXX',
key => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
},
);
限制凭证权限:
chmod 600 .s3curl
创建 POST 请求主体(multidelete.xml):
<?xml version="1.0" encoding="UTF-8"?>
<Delete>
<Object>
<Key>file1.txt</Key>
</Object>
<Object>
<Key>file2.txt</Key>
</Object>
</Delete>
计算 POST 主体的 base64 编码 MD5 和:
cat multidelete.xml | openssl dgst -md5 -binary | base64
cD8Q8KTug5P8Hj7oyOW8iQ==
构建请求,并启用 curl 的详细显示(我已将上述命令包含在内联中,而不是 MD5 总和本身):
./s3curl.pl --id=personal --post multidelete.xml --contentMd5 `cat multidelete.xml | openssl dgst -md5 -binary | base64` -- -v http://s3.amazonaws.com/BUCKET?delete
笔记:
尝试使用 PUT (而不是 POST) 会导致405 Method Not Allowed
:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>MethodNotAllowed</Code><Message>The specified method is not allowed against this resource.</Message><ResourceType>MULTI_OBJECT_DELETE</ResourceType><Method>PUT</Method><RequestId>XXXXXXXXXXXXXXXX</RequestId><HostId>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</HostId></Error>
尝试使用不带 Content-MD5 标头的 POST 会导致400 Bad Request
:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>InvalidRequest</Code><Message>Missing required header for this request: Content-MD5</Message><RequestId>XXXXXXXXXXXXXXXX</RequestId><HostId>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</HostId></Error>
使用十六进制 md5 和的结果是400 Bad Request
:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>InvalidDigest</Code><Message>The Content-MD5 you specified was invalid.</Message><RequestId>XXXXXXXXXXXXXXXX</RequestId><Content-MD5>703f10f0a4ee8393fc1e3ee8c8e5bc89</Content-MD5><HostId>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</HostId></Error>
有效的请求/响应如下所示:
./s3curl.pl --id=personal --post multidelete.xml --contentMd5 `cat multidelete.xml | openssl dgst -md5 -binary | base64` -- -v http://s3.amazonaws.com/BUCKET?delete
* About to connect() to s3.amazonaws.com port 80 (#0)
* Trying 72.21.194.31... connected
* Connected to s3.amazonaws.com (72.21.194.31) port 80 (#0)
> POST /BUCKET?delete HTTP/1.1
> User-Agent: curl/7.19.7 (i386-redhat-linux-gnu) libcurl/7.19.7 NSS/3.12.9.0 zlib/1.2.3 libidn/1.18 libssh2/1.2.2
> Host: s3.amazonaws.com
> Accept: */*
> Date: Thu, 05 Apr 2012 01:50:53 +0000
> Authorization: AWS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
> Content-MD5: cD8Q8KTug5P8Hj7oyOW8iQ==
> Content-Length: 172
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< x-amz-id-2: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
< x-amz-request-id: XXXXXXXXXXXXXXXX
< Date: Thu, 05 Apr 2012 01:50:55 GMT
< Content-Type: application/xml
< Transfer-Encoding: chunked
< Server: AmazonS3
<
<?xml version="1.0" encoding="UTF-8"?>
* Connection #0 to host s3.amazonaws.com left intact
* Closing connection #0
<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Deleted><Key>file1.txt</Key></Deleted><Deleted><Key>file2.txt</Key></Deleted></DeleteResult>
使用<Quiet>true</Quiet>
成功删除后返回的结果如下:
<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"></DeleteResult>
我唯一能复制您的错误消息的方法是使用我的凭证文件中的无效密钥。但是,与你的不同,存储桶列表也不起作用。