5

I am facing an issue with S3. After 3h of troubleshooting (in the meantime i learnt about IAM roles & managed to create them) I am stuck trying to upload a fb profile picture to amazon S3.

My code:

if let imageData = NSData(contentsOf: NSURL(string: url) as! URL) {

                            let fileName = ProcessInfo.processInfo.globallyUniqueString + ".jpg"
                            let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileName)
                            let image = UIImage(data: imageData as Data)
                            let imageData = UIImageJPEGRepresentation(image!, 1.0)!
                            do {
                                try imageData.write(to: fileURL! as URL)
                            } catch _ {
                                self.log.error("Could not write to file.")
                            }

                            let transferManager = AWSS3TransferManager.default()
                            let uploadRequest = AWSS3TransferManagerUploadRequest()
                            uploadRequest?.bucket = "app-files"
                            uploadRequest?.key = "user-data/" + awsId! + "_primary_profile_picture.jpg"
                            uploadRequest?.body = fileURL!

                            transferManager.upload(uploadRequest!).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in

                                if let error = task.error as? NSError {
                                    if error.domain == AWSS3TransferManagerErrorDomain, let code = AWSS3TransferManagerErrorType(rawValue: error.code) {
                                        switch code {
                                        case .cancelled, .paused:
                                            break
                                        default:
                                            print("Error uploading: \(uploadRequest?.key) Error: \(error)")
                                        }
                                    } else {
                                        print("Error uploading: \(uploadRequest?.key) Error: \(error)")
                                    }
                                    return nil
                                }

                                let uploadOutput = task.result
                                print("Upload complete for: \(uploadRequest?.key)")
                                return nil
                            })
                        }

**Problem** I am continuously getting a The request body terminated unexpectedly error from S3 which looks like this:

Error uploading: Optional("user-data/eu-west-1:xxxx-xxxx-xxxx-xxxx-xxxxxxxxxx_primary_profile_picture.jpg") 
Error: Error Domain=com.amazonaws.AWSS3ErrorDomain Code=0 "(null)" 
UserInfo={HostId=XXX, 
Message=The request body terminated unexpectedly, 
Code=IncompleteBody, 
RequestId=1485A0FFBD7819D7}

I am not sure what is going wrong, i have debugged, and fileName, fileURL, imageData seem to be fine

Sebastian Flückiger
  • 5,525
  • 8
  • 33
  • 69
  • 3
    There is a bug in v2.5.1 of the SDK try downgrading to 2.5.0 if you can. – donkon Feb 21 '17 at 19:46
  • i had to upgrade because of swift 3 support :/ with 2.5 nothing worked (cognito, dynamo,...) – Sebastian Flückiger Feb 21 '17 at 20:15
  • Swift 3 support was introduced in 2.5.0 The change should not break any of the listed services...theoretically. Can you give some details on how cognito and dynamo didn't work? – donkon Feb 21 '17 at 22:34
  • It was an issue in 2.5.0: https://github.com/aws/aws-sdk-ios/issues/590 i will try to selectively only downgrade S3 and see if it works – Sebastian Flückiger Feb 22 '17 at 07:27
  • I also had this issue with 2.5.1. Dropped AWSiOSSDKv2 and AWSCognito back to 2.5 and all is well. For me, my app is Objective-C, not Swift (not that that would make any difference for this issue it appears.) – icefield Feb 23 '17 at 15:29
  • sadly this issue (last comment) is related to swift 3 & 2.5.0 so i cannot downgrade. might have to wait out a fix :/ – Sebastian Flückiger Feb 23 '17 at 16:57

2 Answers2

7

There is a bug with the 2.5.1 SDK, I explain a bit about it here.

Basically, the AWSSignature creates the wrong signature for the upload...

You have two ways to get around it:

1) Revert to using 2.5.0 by declaring all the pods you need explicitly like so: (Edit: I just noticed you can't do that because of the SWIFT problem. Try option 2 maybe)

pod 'AWSCore', '2.5.0'
pod 'AWSCognito', '2.5.0'
pod 'AWSLambda', '2.5.0'
pod 'AWSSNS', '2.5.0'
pod 'AWSS3', '2.5.0'

2) Change the code yourself to fix the problem until Amazon fix it. All you need to do is comment out lines 783-785 in the AWSCore/Authentication/AWSSignature.m file - you should get a message that the file is locked if you try, just unlock it.

if (self.endOfStream) {
    return NO;
}
0

Indeed there is a bug with the current AWSS3 SDK. IF you are using cocoapods you can install the 2.5.0 (Swift 3 compatible) with:

pod 'AWSS3', '2.5.0'
Larry Mickie
  • 441
  • 4
  • 9
  • This does not work, as: - `AWSCore (= 2.5.1)` required by `Podfile` - `AWSCore (= 2.5.0)` required by `AWSS3 (2.5.0)` - `AWSCore (= 2.5.1)` required by `AWSSNS (2.5.1)` - `AWSCore (= 2.5.1)` required by `AWSCognito (2.5.1)` - `AWSCore (= 2.5.1)` required by `AWSLambda (2.5.1)` the other modules have to be 2.5.1 to work (see last comments from me). – Sebastian Flückiger Mar 01 '17 at 09:43
  • I actually ran into the same issue. a Pod Update for all related AWS pods to be 2.5.0. Or if you prefer remove the AWS pods then pod install with only AWSS3 as pod 'AWSS3', '2.5.0' will install all the AWS pods as 2.5.0 – Larry Mickie Mar 01 '17 at 17:57
  • please see my other comment. my other aws services will not work in 2.5.0 due to an issue with cognito. i cannot downgrade – Sebastian Flückiger Mar 02 '17 at 08:06