Alamofire and Digest-Auth - ios

I am trying to implement in my Apps Digest-auth but i am struggling, or is not working properly.
I have setup my request as you describe in your AuthenticationTestCase and looks like the following code:
let userName = "***********"
let password = "***********"
let qop = "auth"
let xmlStr: String = "<?xml version=\"1.0\" encoding=\"utf-8\"?><methodCall><methodName>authenticate.login</methodName></methodCall>"
let postData:Data = xmlStr.data(using: String.Encoding.utf8, allowLossyConversion: true)!
let url = URL(string: "https://app.**********.co.uk/service/mobile/digest-auth/\(qop)/\(userName)/\(password)")
var request = URLRequest(url: url!)
request.httpShouldHandleCookies = true
request.setValue("\(String(describing: xmlStr))", forHTTPHeaderField: "Content-Length")
request.setValue("application/xml", forHTTPHeaderField: "Content-Type")
request.setValue("IOS133928234892nil", forHTTPHeaderField: "User-Agent")
request.setValue("application/xml", forHTTPHeaderField: "Accept")
request.httpMethod = "POST"
request.httpBody = postData
AF.request(request)
.authenticate(username: userName, password: password)
.response { response in ........
When I run the above code, I am receiving the following response from the remote server:
Response XML Error:
You must be authenticated to access this resource
Response Error Code: 401
Response Headers:
Optional([AnyHashable("X-Powered-By"): PHP/7.1.33, AnyHashable("Pragma"): no-cache, AnyHashable("Content-Length"): 310, AnyHashable("Date"): Fri, 22 May 2020 09:15:48 GMT, AnyHashable("Server"): Apache/2.4.41 () OpenSSL/1.0.2k-fips PHP/7.1.33, AnyHashable("Cache-Control"): no-store, no-cache, must-revalidate, AnyHashable("Content-Type"): Content-Type: application/xml, AnyHashable("Www-Authenticate"): Digest realm="Mobile",nonce="31JEmMdeSVfXWQ:OT/ndHY6ch/PjqFwA6uutg",opaque="c81e728d9d4c2f636f067f89cc14864c",qop="auth",algorithm="MD5", Digest realm="Mobile",nonce="31JEmMdeSVfXWQ:OT/ndHY6ch/PjqFwA6uutg",opaque="c81e728d9d4c2f636f067f89cc14864c",qop="auth",algorithm="SHA-512-256", Digest realm="Mobile",nonce="31JEmMdeSVfXWQ:OT/ndHY6ch/PjqFwA6uutg",opaque="c81e728d9d4c2f636f067f89cc14864c",qop="auth",algorithm="SHA-256", AnyHashable("Connection"): Keep-Alive, AnyHashable("Keep-Alive"): timeout=5, max=100, AnyHashable("Expires"): Thu, 19 Nov 1981 08:52:00 GMT])
Note: If I do the same request via Postman, it works properly.
It looks like the Alamofire is not properly handling the Digest challenge.
Please could you help me on this issue?

Related

iOS app calling redirected domain

I'm creating rest based app and when I make requests to server url:
Example : 107.XXX.XXX.XXX:8080/taxi - it`s working, returns me JSON.
But when I make request to domain forwarded to that ip my app shows me that exception:
2017-04-18 20:23:53.063 Project X[4121:301275] http://107.XXX.XXX.XXX:8080/taxi
2017-04-18 20:23:53.065 Project X[4121:301275] fireGetWebserviceCall finally
2017-04-18 20:23:53.252 Project X[4121:301275] Error: Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: not found (404)" UserInfo={NSUnderlyingError=0x600000240600 {Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo={com.alamofire.serialization.response.error.response= { URL: http://107.XXX.XXX.XXX:8080/taxi } { status code: 404, headers {
"Content-Language" = en;
"Content-Length" = 977;
"Content-Type" = "text/html;charset=utf-8";
Date = "Tue, 18 Apr 2017 17:23:51 GMT";
Server = "Apache-Coyote/1.1";
} }
When I paste that URL into a browser I get normal JSON response.
Can someone explain to me why returned info is text/html and how to fix it?
I use the code below to ensure that I get JSON responses back from URLs:
Swift
var request = URLRequest(url: self.url!)
request.httpMethod = self.httpMethod
request.httpBody = body
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")

Sending data to PHP server

I'm trying to set up sending data to a PHP server but I'm having no luck at all.
Here is my PHP code.
<?php
require_once "../config/config.php";
var_dump($_POST);
var_dump($_REQUEST);
// Read request parameters
if(isset($_REQUEST)){
$username = $db->escape($_REQUEST["username"]);
$email = $db->escape($_REQUEST["email"]);
$password = $db->escape($_REQUEST["password"]);
$id = MD5($email);
echo $username;
//$db->query("INSERT INTO user ('id','username','email','password') VALUES ('$id','$username','$email',PASSWORD('$password'))");
$returnValue = $id;
}else{
$returnValue = "No data received";
}
// Send back request in JSON format
echo json_encode($returnValue);
?>
Here is my Swift Code
let request = NSMutableURLRequest(URL: NSURL(string: "http://***************/register.php")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
let data = "username=JoeBloggs&email=joe#bloggs.com&password=12345"
request.HTTPBody = (data as NSString).dataUsingEncoding(NSUTF8StringEncoding)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
print(response)
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(strData)
print(error)
}
task.resume()
I'm not concerned about getting a result back yet (I have that working fine). I just can't get any data to the server.
Here is the result from the above script.
Optional(<NSHTTPURLResponse: 0x7ff9b3d6ea90> { URL: http://iep.almartin.co.uk/register.php } { status code: 200, headers {
"Cache-Control" = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
Connection = close;
"Content-Type" = "text/html; charset=UTF-8";
Date = "Tue, 01 Sep 2015 09:02:46 GMT";
Expires = "Thu, 19 Nov 1981 08:52:00 GMT";
Pragma = "no-cache";
Server = nginx;
"Set-Cookie" = "PHPSESSID=8j2d7oobg9plvdik1dcbqtoq70; path=/";
"Transfer-Encoding" = Identity;
} })
Optional(array(0) {
}
array(0) {
}
<br />
<b>Notice</b>: Undefined index: username in <b>/home/linweb34/i/iep.almartin.co.uk/user/htdocs/register.php</b> on line <b>7</b><br />
<br />
<b>Notice</b>: Undefined index: email in <b>/home/linweb34/i/iep.almartin.co.uk/user/htdocs/register.php</b> on line <b>8</b><br />
<br />
<b>Notice</b>: Undefined index: password in <b>/home/linweb34/i/iep.almartin.co.uk/user/htdocs/register.php</b> on line <b>9</b><br />
"d41d8cd98f00b204e9800998ecf8427e")
nil
As you can see both $_REQUEST and $_POST are returning empty arrays.
What am I doing wrong?
The error clearly says that there is problem with your MySQL usage.
Following are the working code template. It uses PDO for DB connection.
function __construct() {
$this->conn = new PDO('mysql:host=<your hostnam>;dbname=<dbname>', '<user>', '<pass>');
// Generate stack trace on failure.
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
/*
* Write a function and pass your variables
*/
function get_data_from_db($id,$username,$password,$email) {
$stmt = $this->conn->prepare("INSERT INTO `user`(`id`,`username`,`email`,`password`) VALUES (:id,:username,:email,PASSWORD(:password))");
$stmt->execute(array(':id' => $id, ':username' => $username, ':email' => $email, ':password' => $password));
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
return $data;
}
Now in your code, just add a function call and you are done:
if(isset($_REQUEST)){
$username = $db->escape($_REQUEST["username"]);
$email = $db->escape($_REQUEST["email"]);
$password = $db->escape($_REQUEST["password"]);
$id = MD5($email);
$result = get_result_from_db($id,$username,$password,$email);
echo json_encode($result);
}
Note : Not tested, but it should work.
Found the problem.
It seems these lines are the culprit in my app.
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
It worked fine when I removed them.
Which brings up another question, how do I set up PHP to accept header type "application/json" ?
To send JSON to a server with POST you have to put the data to be sent into a dictionary and serialize the dictionary with NSJSONSerialization
let request = NSMutableURLRequest(URL: NSURL(string: "http://***************/register.php")!)
let session = NSURLSession.sharedSession()
let postData = ["username" : "JoeBloggs", "email" : "joe#bloggs.com", "password" : "12345"]
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(postData, options: NSJSONWritingOptions())
request.HTTPMethod = "POST"
request.setValue("\(jsonData.length)", forHTTPHeaderField:"Content-Length")
request.setValue("application/json", forHTTPHeaderField:"Accept")
request.setValue("application/json", forHTTPHeaderField:"Content-Type")
request.HTTPBody = jsonData
let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
print(response)
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(strData)
print(error)
}
task.resume()
} catch let error as NSError {
print(error)
}
So I followed #vadian answer which didn't work initially. I did some research into why PHP wasn't accepting application/json.
I got it to work by using $HTTP_RAW_POST_DATA instead of $_POST or $_REQUEST in the php file.
However! $HTTP_RAW_POST_DATA is now depreciated but the following code works
$json = file_get_contents('php://input');
$obj = json_decode($json);
Seems like a PHP hack to me but at least it works.

Office 365 iOS SDK - How to invoke SharePoint REST API

All the iOS SDK samples provide working code for accessing Mail, Calendar, ODfB FIles, but none show how to access SharePoint list items. So I am trying a simple REST call in Swift, but keep getting the following error:
[0] (null) #"error_description" : #"Unsupported security token.
Here is a subset of my code when my App starts:
var resourceID : String = "https://mytenant.sharepoint.com"
var authorityURL : String = "https://login.windows.net/common/"
var clientID : String = "xxd4200eb-7284-41be-a434-abb269b82f0f"
var redirectURI : NSURL = NSURL(string: "http://www.mycompanywebsite.com")!
override func viewDidLoad() {
super.viewDidLoad()
var defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
var er : ADAuthenticationError? = nil
var authContext:ADAuthenticationContext = ADAuthenticationContext(authority: authorityURL, error: &er)
authContext.acquireTokenWithResource(resourceID, clientId: clientID, redirectUri: redirectURI) { (result: ADAuthenticationResult!) -> Void in
if (result.accessToken == nil) {
println("token nil")
} else {
defaults.setObject(result.accessToken, forKey: "accessTokenDefault")
defaults.synchronize()
println("accessToken: \(result.accessToken)")
}
}
}
Then, once I get the Token, I invoke the following code that tries an http GET but fails:
var resolver : MSODataDefaultDependencyResolver = MSODataDefaultDependencyResolver()
var credentials : MSODataOAuthCredentials = MSODataOAuthCredentials()
var defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
credentials.addToken(defaults.objectForKey("accessTokenDefault") as! String)
var credentialsImpl : MSODataCredentialsImpl = MSODataCredentialsImpl()
credentialsImpl.setCredentials(credentials)
resolver.setCredentialsFactory(credentialsImpl)
//build API string to get a sample list info
let request = NSMutableURLRequest(URL: NSURL(string: "https://umaknow.sharepoint.com/_api/web?$select=Title")!)
request.HTTPMethod = "GET"
let token = defaults.stringForKey("accessTokenDefault")
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.setValue("application/json; odata=verbose", forHTTPHeaderField: "accept")
//make the call to the SharePoint REST API
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error:NSError? = nil
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: &error) as? NSDictionary
if (jsonResult != nil) {
//parse the json into File objects in the table view
let results:NSArray = (jsonResult["d"] as! NSDictionary)["results"] as! NSArray
And this is where it fails with the error message. Monitoring the web traffic, the following is a bit more details about what is going on:
This is my request (RAW):
GET /_api/web?$select=Title HTTP/1.1
Host: mytenant.sharepoint.com
Connection: keep-alive
Proxy-Connection: keep-alive
Accept: application/json; odata=verbose
User-Agent: O365Demo/1 CFNetwork/711.3.18 Darwin/14.3.0
Accept-Language: en-us
Authorization: Bearer Optional("eyJ0eXAiOiJKV1QiLDJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSIsImtpZCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSJ9.eyJhdWQiOiJodHRwczovL3VtYWtub3cuc2hhcmVwb2ludC5jb20iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC81NmZjOTc3OC04YWFjLTQ1ZDItOTMwNS1iOTE3MWZmYWZhOGMvIiwiaWF0IjoxNDM1MjI3Nzk1LCJuYmYiOjE0MzUyMjc3OTUsImV4cCI6MTQzNTIzMTY5NSwidmVyIjoiMS4wIiwidGlkIjoiNTZmYzk3NzgtOGFhYy00NWQyLTkzMDUtYjkxNzFmZmFmYThjIiwib2lkIjoiOGUyZTBlZDQtYmEzNC00YWM4LTkwYmMtNWQ3NGQ3MzE4YjkyIiwidXBuIjoicGllcnJlQHVtYWtub3cuY29tIiwicHVpZCI6IjEwMDMwMDAwODUyMUY3NjYiLCJzdWIiOiJqR3BHQ1VDdDNYTnM2b0pjSkgxVldQOUwyV1JLa3lIOHhxWHlKbVFaSV8wIiwiZ2l2ZW5fbmFtZSI6IlBpZXJyZSIsImZhbWlseV9uYW1lIjoiQm91cmFzc2EiLCJuYW1lIjoiUGllcnJlIEJvdXJhc3NhIiwiYW1yIjpbInB3ZCJdLCJ1bmlxdWVfbmFtZSI6InBpZXJyZUB1bWFrbm93LmNvbSIsImFwcGlkIjoiNmQ0MjAwZWItNzI4NC00MWJlLWE0MzQtYWJiMjY5YjgyZjBmIiwiYXBwaWRhY3IiOiIwIiwic2NwIjoiQWxsU2l0ZXMuTWFuYWdlIEFsbFNpdGVzLlJlYWQgQ2FsZW5kYXJzLlJlYWRXcml0ZSBGaWxlcy5SZWFkIEdyb3VwLlJlYWQuQWxsIEdyb3VwLlJlYWRXcml0ZS5BbGwgTXlGaWxlcy5SZWFkIE15RmlsZXMuV3JpdGUgU2l0ZXMuUmVhZC5BbGwgU2l0ZXMuU2VhcmNoLkFsbCBUZXJtU3RvcmUuUmVhZC5BbGwgVXNlci5SZWFkIFVzZXIuUmVhZFdyaXRlIFVzZXIuUmVhZFdyaXRlLkFsbCIsImFjciI6IjEifQ.aAkaEIFuOeiI0ZRydzaOBTl5wyqLDYBHfvbSj6nZAk4jQKBZF6BhJsAAnhu9qj8oMR2gUdVr3vCNgzefvlZxcf3u0k6R8g4176M-bU3rAABri9DjyaZJ24jMs1u-kL0h5Ee8mvNXSI7BF7Qv9JoeHIiXLei_SXba1s8mhdwMaw9Se9tl8MbBFPLDDBLXUa4YgC_rYWO7G7rw3JEe3GmEV9NffZ7zklXxd55P8fxtbz0-KhI0wbRHIXN69wAuC0jiqhJ4FCCGzLvTuuUbirhURrhi4UizYpLWqqnr0I8zWAMvr8WUXCWtZhPkzOZ5teqbvBwp1UwYui42O6S0PfYKzQ")
Accept-Encoding: gzip, deflate
And finally the RAW response from the site
HTTP/1.1 401 Unauthorized
Server: Microsoft-IIS/8.5
x-ms-diagnostics: 3000006;reason="Token contains invalid signature.";category="invalid_client"
SPRequestGuid: 84c9139d-807c-2000-0e59-4caf75bd097f
request-id: 84c9139d-807c-2000-0e59-4caf75bd097f
SPRequestDuration: 19
SPIisLatency: 1
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 16.0.0.4107
X-Content-Type-Options: nosniff
X-MS-InvokeApp: 1; RequireReadOnly
P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
WWW-Authenticate: Bearer realm="56fc9778-8aac-45d2-9305-b9171ffafa8c",client_id="00000003-0000-0ff1-ce00-000000000000",trusted_issuers="00000001-0000-0000-c000-000000000000#*,https://sts.windows.net/*/,00000003-0000-0ff1-ce00-000000000000#90140122-8516-11e1-8eff-49304924019b",authorization_uri="https://login.windows.net/common/oauth2/authorize"
Date: Thu, 25 Jun 2015 11:12:40 GMT
Content-Length: 51
{"error_description":"Unsupported security token."}
So there is something obviously wrong with the way I use the Token provided, but with my very limited OAuth2 knowledge and the lack of samples, I am at a lost.
Any help is greatly appreciated!
In case anyone gets the same issue, I finally found what was wrong. It has nothing to do with ADAL or SharePoint REST, but a syntactic error in Swift. The line that read:
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
generates the following in the HTTP request:
Authorization: Bearer Optional("eyJ0eXAiOi....
The "Optional("...") has something to do with the insertion of the token variable in the string. By just replacing the statement with:
request.setValue("Bearer " + token!, forHTTPHeaderField: "Authorization")
now generates the correct header in the HTTP request:
Authorization: Bearer eyJ0eXAiOi...
and I get the data I want back from the call.
So this is really a newbie Swift programmer error! :-)

Custom HTTP Request from iOS is rejected

I am trying to send an HTTP request to a php script on iOS. I use multipart/form-data because I also need to be able to send JPEGs. The user agent is curl sending a request from curl in terminal works every time. Here is the request I end up generating from the code I have below.
POST /Folder/GetData.php HTTP/1.1
Host: website_goes_here
Content-Type: multipart/form-data; boundary=This12#
Expect: 100-continue
Content-Length: 146
Accept: */*
User-Agent: curl/7.37.1
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive
--This12#
Content-Disposition: form-data; name=uname
ThisIsTheUserNameHere
--This12#
Content-Disposition: form-data; name=pass
PasswordGoesHere
--This12#--
Here is the swift code I use to generate this request (data is a variable sent to the function with an array of dictionaries.):
var request=NSMutableURLRequest(URL: NSURL(string: “website-HERE”)!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 60)
request.timeoutInterval=NSTimeInterval(60)
request.HTTPMethod="POST";
var end="This12#";
request.addValue("multipart/form-data; boundary="+end, forHTTPHeaderField: "Content-Type")
request.setValue("*/*" , forHTTPHeaderField: "Accept")
request.setValue("close" , forHTTPHeaderField: "Connection")
request.setValue("100-continue", forHTTPHeaderField: "Expect")
request.setValue("curl/7.37.1", forHTTPHeaderField: "User-Agent")
var body=NSMutableData()
body.appendData(("\r\n--"+end+"\r\n").dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!)
var first=true
for object in data{
if !(first){
body.appendData(("\r\n--"+end+"\r\n").dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!)
}
first=false
if((object[“Content-Type”] as! String)=="text/plain"){
body.appendData(("Content-Disposition: form-data; name="+(object[“name”] as! String)+"\r\n\r\n"+(object[“TextToSend”] as! String)).dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!)
}else{
var part1="Content-Disposition: attatchment; name="+(object[“name”] as! String)
var part2="; filename="+(object[“FileName”] as! String)+";\r\nContent-Type: "
body.appendData((part1+part2+(object[“Content-Type”] as! String)+"\r\n\r\n").dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!)
body.appendData(object[“Data”] as! NSData);
}
}
body.appendData(("\r\n--"+end+"--\r\n").dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!)
request.HTTPBody=body
What happens is my GoDaddy website returns a valid response for the first few times and then the connection starts getting reset for the next minute and this repeats. Is there any reason for this? Please respond with either corrections for the code or the HTTP request. If this helps, the connection is sent with:
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response, data, error) ->
Void in
println(NSString(data: data, encoding: NSASCIIStringEncoding));
}
Thanks,
You don't show your code for actually sending the request and handling the response.
My guess though is that you're not reading to the end of the response, and so the connection is not being closed. That will leave you with lots of connections held open, until GoDaddy decides to throttle you.
It turns out that GoDaddy has a post limit per ip in a certain amount of time. Shared Hosting plans have a limit.

Put request IOS

I try to update a object in the database trough a API call. I do this action with a PUT request. A Post request was already made and is working fine. I thought it is just copy paste...
The API part works fine because if I execute the following curl command than it updates the row I wanted in the database
$ curl -H 'Accept: application/json' -i -X PUT -d 'UserLogin=Ub0D&EndDate=2014-01-17 00:00:00.0000000&Sport=Fietsen&Distance=1000&Duration=10&Achieved=true&DateCreated=2015-05-09 12:01:00.000000' http://localhost:8089/api/goal/ub0d -k -u ub0d:test123
But now the part in swift gives me a bad request error (400)...
This is my code
var url : NSURL
url = NSURL(string: _apiUrl + connectToApi(apiCall) + String("\(AccountRepository.Instance.getCurrentUserName())"))!
let request = NSMutableURLRequest(URL: url)
if postString != nil {
let postData : NSData = ("UserLogin=Ub0D&EndDate=2014-01-1700:00:00.0000000&Sport=Fietsen&Distance=1000&Duration=10&Achieved=true&DateCreated=2014-01-1700:00:00.0000000").dataUsingEncoding(NSUTF8StringEncoding)!
// create the request
request.HTTPMethod = "PUT"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
request.setValue("application/json", forHTTPHeaderField: "Content-type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPBody = postData
}
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)!
I'm really stuck on it:(
You request can't have two different content types at the same time:
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
request.setValue("application/json", forHTTPHeaderField: "Content-type")
The data you are sending are obviously not JSON, so I guess you want only
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
and remove the "application/json" line.
There is also a difference between your date formats:
CURL
EndDate=2014-01-17 00:00:00.0000000
Swift
EndDate=2014-01-1700:00:00.0000000
Note the missing space between date and time, probably should be URL encoded (+):
EndDate=2014-01-17+00:00:00.0000000
In general, most REST APIs send error messages in response body, so it is always good to log the response for failed requests.

Resources