aws-amplify / aws-sdk-ios

AWS SDK for iOS. For more information, see our web site:
https://aws-amplify.github.io/docs
Other
1.68k stars 885 forks source link

When using us-west-2 the object upload fails for my S3 bucket. #5290

Closed greater-c closed 4 months ago

greater-c commented 7 months ago

The SDK automatically signs server requests with the us-east-1 region for some reason. I've been dealing with this issue for days and needed server logs to discover this.

Code:

func uploadMP4ToS3(filePath: URL, key: String) { let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .USWest2, identityPoolId: "US-WEST-2 IDENTITY_POOL_ID") // Set up the service configuration let configuration = AWSServiceConfiguration(region: .USWest2, credentialsProvider: credentialsProvider)

    // Apply the service configuration
    AWSServiceManager.default().defaultServiceConfiguration = configuration

    // Load the file data
    do {
        let fileData = try Data(contentsOf: filePath)

        // Get the default S3 Transfer Utility
        let transferUtility = AWSS3TransferUtility.default()

        let systemID = YuhmmyVars.yuhmmyMember?.yuhmID ?? ""

        // Perform the file upload
        transferUtility.uploadData(fileData,
                                   bucket: "US-WEST-2-BUCKET",
                                   key: key,
                                   contentType: "video/mp4",
                                   expression: nil,
                                   completionHandler: { (task, error) in
            DispatchQueue.main.async {
                if let error = error {
                    // Cast the error to an NSError
                    let nsError = error as NSError

                    // Extract the requestID from the userInfo dictionary if available
                    if let requestID = nsError.userInfo["requestID"] as? String {
                        print("[uploadMP4ToS3] Error occurred during upload: \(nsError.localizedDescription) | Request ID: \(requestID)")
                    } 
                    else {
                        print("[uploadMP4ToS3] Error occurred during upload: \(nsError.localizedDescription)")
                    }

                    // You can also try to retrieve the requestID from the response object of the task
                    if let httpResponse = task.response as? HTTPURLResponse {
                        let requestID = httpResponse.allHeaderFields["x-amz-request-id"] as? String ?? "unknown"
                        print("[uploadMP4ToS3] Task completed with error. Request ID: \(requestID)")
                    }
                }

                if (error == nil) {

                    // Task completed successfully
                    print("[uploadMP4ToS3] Upload successful. Task: \(task)")

                    if let httpResponse = task.response as? HTTPURLResponse {
                        let requestID = httpResponse.allHeaderFields["x-amz-request-id"] as? String ?? "unknown"
                        print("[uploadMP4ToS3] Upload successful. Request ID: \(requestID)")
                    }
                }
            }
        })
    } catch {
        print("[uploadMP4ToS3] Unable to load file data: \(error.localizedDescription)")
    }
}
phantumcode commented 7 months ago

@greater-c Thanks for submitting the issue. We'll investigate the issue and provide updates here.

phantumcode commented 7 months ago

@greater-c Can you provide the code that demonstrates how you're upload to S3 for reference and help us reproduce your issue.

phantumcode commented 7 months ago

@greater-c Can you also verify if you have the file awsconfiguration.json is your project?

greater-c commented 7 months ago

@greater-c Can you also verify if you have the file awsconfiguration.json is your project?

I have not created that file, is it not in use and it's not in my Xcode project.

greater-c commented 7 months ago

@greater-c Can you provide the code that demonstrates how you're upload to S3 for reference and help us reproduce your issue.

I've provided the code. It failed to upload files until I created a bucket in the us-east-1 region and set it as the upload target.

phantumcode commented 7 months ago

@greater-c I was able to upload to us-west-1 without any issues based on the provided code sample:

let credentialProvider = AWSCognitoCredentialsProvider(regionType: .USWest1, identityPoolId: "us-west-1:xxxx-xxx-xxxx")
let configuration = AWSServiceConfiguration(region: .USWest1, credentialsProvider: credentialProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
let transferUtility = AWSS3TransferUtility.default()

Here are couple things to try to debug further on why it's not working for you:

  1. Ensure that you don't have any local configuration that's getting picked up at initialization by default i.e. amplifyconfiguration.json or awsconfiguration.json
  2. Do you have a default region setting somewhere? i.e. info.plist file
  3. Double check that you're not setting the AWSServiceManager.default().defaultServiceConfiguration more than once since the documentation says that it's a one-time setter https://github.com/aws-amplify/aws-sdk-ios/blob/main/AWSCore/Service/AWSService.h#L71-L73
  4. Verify that your credential provider and its associate role has access to the S3 bucket or ensure that the S3 bucket has public access
  5. Ensure that the S3 bucket you're uploading to is in the right region as well.
  6. You can look at the error code returned from the completion handler as well
    transferUtility.uploadData(data,
                           bucket: "testbucket",
                           key: "testkey",
                           contentType: "application/octet-stream",
                           expression: nil,
                           completionHandler: { (task, error) in
    if let error = error {
        print("*** Error: \(error.localizedDescription)")
    }
    })