I am trying to upload a file to S3 using the new AWS SDK for iOS 2.0. The upload works fine as long as I don't set a contentMD5 in the request.
First, I create a filepath and a URL:
NSString *tempFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"s3tmp"];
NSURL *tempFileURL = [NSURL fileURLWithPath:tempFilePath];
Next, I create the request:
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.bucket = S3_BUCKETNAME;
uploadRequest.key = s3Key;
uploadRequest.body = tempFileURL;
Then I create the md5. Conveniently, there is a github project here: https://github.com/JoeKun/FileMD5Hash which is creating the md5 from a file. However, I cross checked with bashs md5 and it's returning the same md5 string. Additionally, if I don't set contentMD5 in the request, the upload succeeds and in the console the same md5 string is shown as eTag. So I think the md5 calculated in the next line is correct.
NSString *md5 = [FileHash md5HashOfFileAtPath:tempFilePath];
Finally, I add the md5 to the uploadRequest:
uploadRequest.contentMD5 = md5;
and start the upload:
[[transferManager upload:uploadRequest] continueWithBlock:^id(BFTask *task) {
NSError *error = task.error;
if (error) {
NSDictionary *errorUserInfo = error.userInfo;
NSLog(@"Error %@: %@",[errorUserInfo objectForKey:@"Code"],[errorUserInfo objectForKey:@"Message"]);
dispatch_sync(dispatch_get_main_queue(), ^{
[weakSelf uploadFinishedUnsuccessful];
});
}
else {
NSLog(@"Upload success for file \n%@ to \n%@/%@",[tempFileURL absoluteString],S3_BUCKETNAME,s3Key);
dispatch_sync(dispatch_get_main_queue(), ^{
[weakSelf uploadFinishedSuccessful];
});
}
return nil;
}];
This always returns an error: Error InvalidDigest: The Content-MD5 you specified was invalid.
So I tried wrapping the md5 into base64, using the builtin method of iOS:
NSString *base64EncodedString = [[md5 dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
I cross checked this with another base64 library. It returns the same base64 string, so I think the base64 string is correct. I tried setting this as contentMD5:
uploadRequest.contentMD5 = base64EncodedString;
I get the same error: Error InvalidDigest: The Content-MD5 you specified was invalid.
Any idea what I am doing wrong?
Thanks for any reply!