How to escape the HTTP params in Swift

code-injection, ios, swift

Solution

If you can target iOS 8 (thanks @Rob), use `NSURLComponents` to escape your parameters instead:

import Foundation

func encodeParameters(#params: [String: String]) -> String {
    var queryItems = map(params) { NSURLQueryItem(name:$0, value:$1)}
    var components = NSURLComponents()
    components.queryItems = queryItems
    return components.percentEncodedQuery ?? ""
}

Now `encodeParameters(params:["hello":"world","inject":"param1=value1&param2=value2"])` returns `hello=world&inject=param1%3Dvalue1%26param2%3Dvalue2` as you would expect.

Otherwise, the best way to create the character set that will let you escape your values properly is this:

var safeCharacterSet = NSCharacterSet.URLQueryAllowedCharacterSet().mutableCopy()
safeCharacterSet.removeCharactersInString("&=")

and see @rintaro's answer to use filter/map properly to perform the encoding in a nice way.

Problem

I'm trying to make a post to an HTTP server By the way this is my code: ``` func sendPostToUrl(url:String, withParams params: [String: String?] ) { var request = NSMutableURLRequest(URL: NSURL(string: url)!) var session = NSURLSession.sharedSession() request.HTTPMethod = "POST" var err: NSError? var bodyData = "" for (key,value) in params{ if (value==nil){ continue } let scapedKey = key.stringByAddingPercentEncodingWithAllowedCharacters( .URLHostAllowedCharacterSet())! let scapedValue = value!.stringByAddingPercentEncodingWithAllowedCharacters( .URLHostAllowedCharacterSet())! bodyData += "\(scapedKey)=\(scapedValue)&" } request.HTTPBody = bodyData.dataUsingEncoding (NSUTF8StringEncoding, allowLossyConversion: true) var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in println("Response: \(response)") let dataString = NSString(data: data, encoding: NSUTF8StringEncoding) println("Data: \(dataString)") }) task.resume() } ``` It works but is not perfect. If I call the function this way: ``` client.sendPostToUrl("http://novagecko.com/tests/test.php", withParams: ["hello":"world","inject":"param1=value1&param2=value2"]); ``` The server detects 3 post fields (with keys `hello`,`inject` and `param2`) instead of 2. How can I escape the key and values? Is there something more I could do for improving the method?

Original source

Related problems