I'm trying to upload a file as an attachment to my Frappe instance and running into a couple of problems. The first of which is the server reporting a padding error.
I'm attempting to read a file (on iPad simulator) as data, then convert to a base64 encoded string, and then using this as part of my httpbody. I've tried this with a couple of different file types, but for the purpose of this example i'm just using a local settings file.
The Frappe instance is (sometimes depending on the data) returning the following error:
File \"/usr/lib/python3.7/base64.py\", line 87, in b64decode\n return binascii.a2b_base64(s)\nbinascii.Error: Incorrect padding
Get data from local URL:
let settingsLocation = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("SettingsList.plist")
let fileData = try Data.init(contentsOf: settingsLocation)
This is then passed to the following function:
public func attachFileToCloudResource(resourceType: String, resourceName: String, attachment: Data) {
let fileAsString = attachment.base64EncodedString().replacingOccurrences(of: "+", with: "%2B")
var request = URLRequest(url: URL(string: FRAPPE_INSTANCE + FRAPPE_METHODS + FRAPPE_UPLOAD_ATTACHMENT)!)
var components = URLComponents(url: request.url!, resolvingAgainstBaseURL: false)!
components.queryItems = [
URLQueryItem(name: FRAPPE_DOCTYPE, value: resourceType),
URLQueryItem(name: FRAPPE_DOCNAME, value: resourceName),
URLQueryItem(name: FRAPPE_FILENAME, value: "testFile.xml"),
URLQueryItem(name: FRAPPE_DATA, value: fileAsString),
URLQueryItem(name: FRAPPE_PRIVATE, value: "1"),
URLQueryItem(name: FRAPPE_DECODE_BASE64, value: "1")
]
let query = components.url!.query
request.httpMethod = "POST"
request.addValue("token \(API_KEY):\(API_SECRET)", forHTTPHeaderField: "Authorization")
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpBody = Data(query!.utf8)
// Session and dataTask send request below but not relevant to example
}
After a bit of googling, I discovered I can resolve the error by appending "==" to the file string, but this feels nasty/wrong.
let fileAsString = (attachment.base64EncodedString().replacingOccurrences(of: "+", with: "%2B") + "==")
Can someone please point out where I might be going wrong and how to do this properly?