Skip to content

Commit

Permalink
[AlamofireBackend] Fix a critical issue about multipart data form enc…
Browse files Browse the repository at this point in the history
…oding
  • Loading branch information
jasl committed May 1, 2016
1 parent 795b057 commit 71f8020
Showing 1 changed file with 46 additions and 7 deletions.
53 changes: 46 additions & 7 deletions Sources/Backends/AlamofireBackend.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,7 @@ public class AlamofireBackend: Backend {
self.manager.upload(request,
multipartFormData: {
multipartFormData in
for (key, value) in endpoint.parameters {
if let value = value as? AlamofireMultipartFormDataEncodable {
value.encode(toAlamofireMultipartFormData: multipartFormData, forName: key)
} else {
multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name: key)
}
}
self.encodeMultipartFormData(to: multipartFormData, parameters: endpoint.parameters)
},
encodingMemoryThreshold: self.multipartFormDataEncodingMemoryThreshold,
encodingCompletion: {
Expand Down Expand Up @@ -201,6 +195,51 @@ public class AlamofireBackend: Backend {
return (request, AlamofireBackendError.errorWithCode(.UnsupportParameterEncoding, failureReason: "\(parameterEncoding) can't encode by Alamofire's ParameterEncoding."))
}
}

private func encodeMultipartFormData(to multipartFormData: Alamofire.MultipartFormData, parameters: [String: AnyObject]) {
var components: [(String, AnyObject)] = []

for key in parameters.keys.sort(<) {
let value = parameters[key]!
components += self.flattenQueryComponents(key, value)
}

for (key, value) in components {
switch value {
case let value as AlamofireMultipartFormDataEncodable:
value.encode(toAlamofireMultipartFormData: multipartFormData, forName: key)
case let value as String:
let data = self.escape(value).dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
multipartFormData.appendBodyPart(data: data, name: key)
default:
continue
}
}
}

private func flattenQueryComponents(key: String, _ value: AnyObject) -> [(String, AnyObject)] {
var components: [(String, AnyObject)] = []

if let dictionary = value as? [String: AnyObject] {
for (nestedKey, value) in dictionary {
components += flattenQueryComponents("\(key)[\(nestedKey)]", value)
}
} else if let array = value as? [AnyObject] {
for value in array {
components += flattenQueryComponents("\(key)[]", value)
}
} else if let placeholder = value as? AlamofireMultipartFormDataEncodable {
components.append((escape(key), placeholder))
} else {
components.append((escape(key), escape("\(value)")))
}

return components
}

private func escape(string: String) -> String {
return Alamofire.ParameterEncoding.URL.escape(string)
}
}

public struct AlamofireBackendError {
Expand Down

0 comments on commit 71f8020

Please sign in to comment.