我正在为MAC(OS X)编写程序,需要检索并向AWS S3发送对象。亚马逊为iOS提供了一个很好的库,但是如果没有大量的重新编译等,我就无法知道如何使用。
我已经决定使用SwiftHTTP库了(非常感动btw)。它似乎对GET操作非常有效。然而,我在PUT方面遇到了挑战。
AWS v4签名协议要求将有效负载的SHA256哈希值作为标头值提供 - 这意味着我必须在创建HTTP请求之前计算该有效负载。
然而,看起来SwiftHTTP正在向有效载荷添加一些其他内容,从而弄乱了我的哈希。我非常确定SHA256算法是正确的,因为它从AWS样本中提供了相同的值。
以下示例代码:
// build our headers
var ourHeaders: [String: String] = [String: String]()
ourHeaders["Host"] = s3url
ourHeaders["x-amz-date"] = MakeAWSxDateString(NSDate())
let payloadHash: String = SHA256ToHex(objectString)
ourHeaders["x-amz-content-sha256"] = payloadHash
// add the headers into the SwiftHTTP structures
var request = HTTPTask()
request.requestSerializer = HTTPRequestSerializer()
for (key, value) in ourHeaders {
request.requestSerializer.headers[key] = value
}
// compute our authorization string
var authString: String = MakeAuthorizationString("PUT", url: s3url, absPath: absPath, headers_us: ourHeaders, payloadhash: payloadHash)
request.requestSerializer.headers["Authorization"] = authString
// convert the in memory string to a format that SwiftHTTP wants
let objectValueD: NSData = objectValue.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
// make the call to upload the object
request.PUT(
"http://" + s3url + absPath,
parameters: ["file": HTTPUpload(data: objectValueD, fileName: objectName, mimeType: "application/octet-stream") ],
completionHandler: {(response: HTTPResponse) in
if let err = response.error {
let descr: String = response.description
println("Description: " + descr)
}
if let data = response.responseObject as? NSData {
if let str = NSString(data: data, encoding: NSUTF8StringEncoding) {
// do the xml parsing of 'str' here...
}
}
})
我很确定我错过了一些明显的东西。但是在遵循SwiftHTTP的源代码之后,看起来SwiftHTTP总是为数据创建一个多部分包络,因此有不同的有效负载(使用不同的哈希值)。