亚马逊s3与AFAmazonS3Manager + AFNetworking

时间:2014-03-05 21:22:02

标签: ios iphone amazon-s3 afnetworking-2

我正在尝试使用AFAmazonS3Manager将一些文件上传到亚马逊s3,但我有403禁止错误,我尝试列出存储桶中的所有对象,同样的错误。

所有人都可以读/写。

代码:

AFAmazonS3Manager *s3Mamanager=[[AFAmazonS3Manager alloc]initWithAccessKeyID:@"XXXXXX" secret:@"xxxxxx"];

[s3Mamanager getBucket:@"aBucket" success:^(id responseObject) {

} failure:^(NSError *error) {

}];

错误:

 Error Domain=AFNetworkingErrorDomain Code=-1011 "Request failed:
 forbidden (403)" UserInfo=0x170272580
 {AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse:
 0x1782212e0> { URL: https://s3.amazonaws.com/aBucket } { status code:
 403, headers {
     "Content-Type" = "application/xml";
     Date = "Wed, 05 Mar 2014 21:01:55 GMT";
     Server = AmazonS3;
     "Transfer-Encoding" = Identity;
     "x-amz-id-2" = "xxxxxxxxxxxxxx";
     "x-amz-request-id" = xxxxxxxxxxxxxx; } }, NSLocalizedDescription=Request failed: forbidden (403),
 NSErrorFailingURLKey=https://s3.amazonaws.com/aBucket}

我使用传输(mac)和亚马逊s3 iOS API的样本,它工作正常,我想使用NSURLSession上传文件(使用AFNetworking)。

PS:在AFAmazonS3Manager中,一些竞争块有'long long'作为参数,但AFNetwoking使用NSIteger,所以我修改它们,我不认为这是问题,但我真的堆栈就这样......

2 个答案:

答案 0 :(得分:0)

使用putObjectWithFile方法时遇到了同样的问题。

我没有设置存储桶,而是在目标路径上传递存储桶名称,AFAmazonS3Manager似乎打算支持它。桶属性设置或在路径上传递。

我在这里提交了一个拉取请求,其中包含对我有用的修复https://github.com/AFNetworking/AFAmazonS3Client/pull/38

你必须将长长度更改为NSInteger也是正确的。

答案 1 :(得分:0)

这是失败的原因是因为在AFAmazonS3RequestSerializer中如何计算签名存在错误。它尝试使用以下方式创建签名:

NSString *canonicalizedResource = [NSString stringWithFormat:@"/%@%@", self.bucket, request.URL.path];

此时,self.bucket为null,request.URL.path包含存储桶。您可以通过执行以下操作解决该问题:

AFAmazonS3Manager *s3Manager = [[AFAmazonS3Manager alloc]
                                initWithAccessKeyID:@"<accessKeyID>" secret:@"<secret>"];
[[s3Manager requestSerializer] setBucket:@"<YOUR BUCKET HERE>"];
[s3Manager getBucket:@"/" success:^(id responseObject) {}
             failure:^(NSError *error) {}];

或者这个:

AFAmazonS3Manager *s3Manager = [[AFAmazonS3Manager alloc]
                                initWithAccessKeyID:@"<accessKeyID>" secret:@"<secret>"];
[[s3Manager requestSerializer] setBucket:@"<YOUR BUCKET HERE>"];
[s3Manager enqueueS3RequestOperationWithMethod:@"GET" path:@"/" parameters:nil
                                       success:^(id responseObject) {}
                                       failure:^(NSError *error) {}];