Cannot upload zip file with multipart with URLSession

Hello, I am experiencing a really strange issue with uploading zip file to s3… Here is my sample code and all details:

 private func uploadZipFile(_ photos:URL,_ step:String,_ presignedUrlModel: PresignedUrlModel) {
        
        var uploadingBackgroundTask = UIBackgroundTaskIdentifier(rawValue: 3)
        uploadingBackgroundTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
            UIApplication.shared.endBackgroundTask(uploadingBackgroundTask)
            uploadingBackgroundTask = .invalid
        })
        let success: () -> Void = {
            DispatchQueue.main.async {
                UIApplication.shared.endBackgroundTask(uploadingBackgroundTask)
                uploadingBackgroundTask = .invalid
            }
            
        }
        let failure: (ErrorResponse) -> Void = { error in
            DispatchQueue.main.async {
                UIApplication.shared.endBackgroundTask(uploadingBackgroundTask)
                uploadingBackgroundTask = .invalid
            }
        }
        
        let boundary = "Boundary-\(UUID().uuidString)"
        
        let uploadingRequest = URL(string: presignedUrlModel.url)!
        var request = APIhelper().getMultipartRequestBody(_type: "POST", _url: uploadingRequest, boundary: boundary)
        
        let body = self.formBackgroundPhotoData(presignedUrlModel, step, photos, boundary)
        
        request.httpBody = body
        
        self.session.configuration.shouldUseExtendedBackgroundIdleMode = true
        let task = session.dataTask(with: request, completionHandler: { (data, response, error) in

            guard let data = data else {
                return
            }
            
            if let httpResponse = response as? HTTPURLResponse {
                
                if(httpResponse.statusCode==200)
                {
                    success()
                }
                else if(httpResponse.statusCode>=400 && httpResponse.statusCode<500)
                {
                 //getting 403 errorr
                 let error = ErrorResponse(message:
                        self.errorFormatingClass.getLocalizedErrorMessage(identifier: self.errorFormatingClass.ERROR)
                        ,
                                                   identifier: self.errorFormatingClass.ERROR)
                    failure(error)
                }
            }
        }
        )
        task.resume()
    }

I always getting 403 response:<?xml version="1.0" encoding="UTF-8"?>AccessDeniedInvalid according to Policy: Policy Condition failed: [“eq”, “$Content-Type”, “application/zip”]

Here is how I form data:

private func formBackgroundPhotoData(_ presignedUrlModel: PresignedUrlModel,_ step: String,_ zip: URL,_ boundary: String) -> Data {
        var body = Data()
        
        var key = "key"
        var value = presignedUrlModel.key
        body.append("--\(boundary)\r\n")
        body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
        body.append("\(value)\r\n")
        
        key = "AWSAccessKeyId"
        value = presignedUrlModel.AWSAccessKeyId
        body.append("--\(boundary)\r\n")
        body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
        body.append("\(value)\r\n")
        
        key = "signature"
        value = presignedUrlModel.signature
        body.append("--\(boundary)\r\n")
        body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
        body.append("\(value)\r\n")
        
        key = "policy"
        value = presignedUrlModel.policy
        body.append("--\(boundary)\r\n")
        body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
        body.append("\(value)\r\n")
        
        let filename = zip.lastPathComponent
        guard let data = try? Data(contentsOf: zip) else {
            #if DEBUG
            debugPrint("backgroundupload", "dataisnull")
            #endif
            return Data()
        }
        
        let mimetype = mimeTypeForPath(url: zip)
        
        body.append("--\(boundary)\r\n")
        body.append("Content-Disposition: form-data; name=\"file\"; filename=\"\(filename)\"\r\n")
        body.append("Content-Type: \(mimetype)\r\n\r\n")
        body.append(data)
        body.append("\r\n")
        
        body.append("--\(boundary)--\r\n")
        return body
    }

Here is multipart request:

 public func getMultipartRequestBody(_type: String, _url: URL, boundary: String) ->URLRequest
    {
        var request = URLRequest(url: _url)
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
        request.timeoutInterval = 300
        request.httpMethod = _type
        return request
    }

Now, I know this tons of code, and perhaps nobody will take a look… All I am asking: please provide an example for uploading zip or images to AWS S3, without adding S3 framework for uploading files

Our whole team does not know what to do :frowning:

Hi @wellbranding, sorry to hear that you’re having trouble with AWS S3. Unfortunately I do not have any sample code to share but if you haven’t already, I would check out the documentation for a POST policy, https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html.

This topic was automatically closed after 166 days. New replies are no longer allowed.