Timeout error when post public key string with URLSession - ios

I am creating a rsa key pair and send the public key to my api. But the post request fails with Timeout error. Following is my function for the request:
func perform<T: Decodable>(reqData: Data, with completion: #escaping (T?) -> Void) {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
// insert json data to the request
request.httpBody = reqData
print("jsonData: ", String(data: request.httpBody!, encoding: .utf8) ?? "no body data")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let error = error else {
print(error)
completion(nil)
return
}
guard let data = data else {
completion(nil)
return
}
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
completion(try? decoder.decode(T.self, from: data))
}
task.resume()
}
JSON Object sent in POST:
{
"publicKey" : "MIIBCgKCAQEA4lS13W+TXZhUXy5yB2NpeulCVb1ZSaReopeKrahjKmUx4NQxVXruEYCY3LpjZcSy8xiudVG3GBIMnPLtaMbc5WAYDj1M2OwnpNHdQ8SKtZ1tdA6iRjfOXGUa1n8FMIMKU5ynTSAiSoh+8gGrY0L6jTsCSdLO5ZU53LQFHSESM8JuBeNZozolb\/cKb38ylercVeVpo8egoA8UqHezK23VUJ23faxMmMZDJxVn5pfFedxBTLxwU65KQY8Z4izaFjuPLoGe5JZkXyYNMcrYloDCBG5m9BFiXVkoLEDmGFGfWLMJcqL+D2CszqJ4h712ZR6LYRNtIbo\/HG9KR7XCtap3QwIDAQAB"
}
I have tested the url in Postman and it works good there. But it is giving my follwoing error when I call it from my app:
Task <6AB1B692-9CBF-4E37-80C6-4F37FD43264B>.<1> finished with error [-1001] Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={_kCFStreamErrorCodeKey=-2102, NSUnderlyingError=0x280299c50 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <6AB1B692-9CBF-4E37-80C6-4F37FD43264B>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <6AB1B692-9CBF-4E37-80C6-4F37FD43264B>.<1>"
), NSLocalizedDescription=The request timed out., NSErrorFailingURLStringKey=http://192.168.178.205:3000/savepublickey, NSErrorFailingURLKey=http://192.168.178.205:3000/savepublickey, _kCFStreamErrorDomainKey=4}
Following is my server side code in Node.js:
app.post('/savepublickey', (req, res) => {
console.log("savepublickey");
console.log(req.body);
let data = JSON.parse(JSON.stringify(req.body, null, 2));
if (data['publicKey'] != null && data['publicKey'] != "") {
console.log("Success");
publicKey = data['publicKey'];
res.status(200).json({
"Status": "Success"
}).send();
} else {
console.log("Fail");
res.status(500).json({
"Status": "Invalid request"
}).send();
}
})

Related

Swift problem with URLSession in Watchkit XCode

I got a problem with UrlSession and a .local domain.
When I send a Request to the IP address of the device in my home network it works. But when I use the .local domain for example "http://esp8266.local" it don't work and there are some errors.
On the IOS App it works fine.
This doesn't work on Watchkit but on IPhone App it works fine:
PDTask .<1> finished with error [-1001] Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataPDTask .<1>, NSLocalizedDescription=The request timed out., _kCFStreamErrorCodeKey=-2102, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataPDTask .<1>",
"LocalDataTask .<1>"
), NSErrorFailingURLStringKey=http://esp8266.local/, _kCFStreamErrorDomainKey=4, NSErrorFailingURLKey=http://esp8266.local/}
let url = URL(string: "http://esp8266.local")
var request = URLRequest(url: url!)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
print(response!)
if error != nil {
print("FAIL")
print(error!)
} else {
print("OKEY")
print(data!)
}
}
task.resume()
And this works fine:
let url = URL(string: "http://192.168.0.109")
var request = URLRequest(url: url!)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
print(response!)
if error != nil {
print("FAIL")
print(error!)
} else {
print("OKEY")
print(data!)
}
}
task.resume()

swift http request can't get non-200 response

I am using below swift code to make a http request. If the server response 200 OK response, swift can work properly. However, the completionHandler callback never get called until timeout when the server response other than 200 status. Is there any other setting on swift to prevent receiving other status response?
let urlStr = "http://xxxxx"
let url = NSURL(string: urlStr)!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "post"
let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {(data, response, error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
// no response code
print("response")
return
}
print("get response from register service \(data) \(error)")
})
task.resume()
If that happens, I get timeout error below:
get login response nil error:Optional(Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSErrorFailingURLStringKey=http://XXXXX, NSErrorFailingURLKey=http://localhost:8080/nurse/login, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2103, NSLocalizedDescription=The request timed out.})
Also I tested with curl command and I was able to get the response as below. So the server side works fine for me. I believe the problem is on the client side.
$ curl -i -X POST -d 'mobile=1234' http://localhost:8080/nurse/login
HTTP/1.1 10029
Server: Apache-Coyote/1.1
X-Application-Context: application
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Allow-Headers: access_token
Content-Type: text/plain;charset=UTF-8
Content-Length: 18
Date: Thu, 24 Mar 2016 02:39:09 GMT
This seems like a server side problem. The code below works (in Playground):
Try using this url and see if this is happening for you.
Also, I would use a simple tool like curl to test manually your server side before debugging Swift code:
curl -i -X POST -d 'name=yoyo' http://putsreq.com/vccZnwiNpP23RF7nwOPE
EDIT
Here is a function that does what you want. I hardcoded your URL and things are working now.
func postSomeStuff(data: String, completion: (data: NSData?, error: NSError?)->Void) {
let post: NSString = "data=\(data)"
let url = NSURL(string: "http://123.56.184.207:8080/nurse/login")!
let postData = post.dataUsingEncoding(NSUTF8StringEncoding)!
let postLength = String(postData.length)
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = postData
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("*/*", forHTTPHeaderField: "Accept")
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
config.timeoutIntervalForRequest = 120
config.timeoutIntervalForResource = 240
let session = NSURLSession(configuration: config)
let task = session.dataTaskWithRequest(request) { urlData, response, reponseError in
if let receivedData = urlData {
let res = response as! NSHTTPURLResponse!;
NSLog("Response code: %ld", res.statusCode);
if 200..<300 ~= res.statusCode {
completion(data: receivedData, error: nil)
} else {
let returnedError = NSError(domain: "getSomeStuff", code: 1, userInfo: [:])
completion(data: nil, error: returnedError)
}
} else {
var userInfo: [NSObject: AnyObject] = [:]
if let error = reponseError {
userInfo["message"] = error.localizedDescription
userInfo["cause"] = error
}
let returnedError = NSError(domain: "myFunc", code: 2, userInfo: userInfo)
completion(data: nil, error: returnedError)
}
}
task.resume()
}
postSomeStuff("yoyo") { data , err in
if let data = data { print(data) }
if let err = err { print(err) }
}
let sema = dispatch_semaphore_create(0);
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
// Used only in Playground
XCPSetExecutionShouldContinueIndefinitely(true)

Unsupported URL swift ios sending Http request

I'm trying to send an http request in swift.
I got a method (sendHttpRequest) that take as argument a dictionary<String,AnyObject> and trying to send a request to localhost with a little server in php. When I tap button that call this function an error occur
"Optional(Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSErrorFailingURLStringKey=46.101.145.122/salvobertoncini.com/servo.php, NSErrorFailingURLKey=46.101.145.122/salvobertoncini.com/servo.php, NSLocalizedDescription=unsupported URL, NSUnderlyingError=0x1763cef0 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}})"
Here is the code:
func sendHttpRequests(data : Dictionary<String, AnyObject>)
{
let session = NSURLSession.sharedSession()
do
{
let request = try NSJSONSerialization.dataWithJSONObject(data, options: .PrettyPrinted)
let url = NSURL ( string : "127.0.0.1/Server/servo.php")
let finalRequest = NSMutableURLRequest(URL: url!)
finalRequest.HTTPMethod = "POST"
finalRequest.HTTPBody = request
let task = session.dataTaskWithRequest(finalRequest){ data,response,error in
if error != nil
{
print("Error -> \(error)")
}
do
{
let result = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String:AnyObject]
print("Result -> \(result)")
}
catch
{
print("Error -> \(error)")
}
}
task.resume()
}
catch
{
print(error)
}
}

Swift: HTTP request executed correctly, but HTTPS not working

I try to execute GET request via HTTP by this code:
func httpGet(request: NSURL, callback: (String, String) -> Void) {
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(request) {
(data,response,error) -> Void in
if (error != nil) {
callback("", error!.localizedDescription)
} else {
let result = NSString(data: data!, encoding: NSASCIIStringEncoding)
callback(result! as String, "")
}
}
task.resume()
}
func updateIssueList () {
httpGet(NSURL(string: "http://www.google.com")!) {
(data, error) -> Void in
print("error: \(error)")
print("data: \(data)")
}
}
It's executed correctly, and returns data without error. But when I change protocol to HTTPS (https://www.google.com"), request fails. When I tried to run application on device (iPhone 4s), I recieved
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo=0x17579730 {NSErrorFailingURLStringKey=https://www.google.com, NSErrorFailingURLKey=https://www.google.com, NSLocalizedDescription=The network connection was lost., NSUnderlyingError=0x1758e470 "The network connection was lost."}
On simulator both variants work correctly. What I doing wrong?

iOS Basic Auth completion error first time

I have implemented this piece of code for basic auth and sometimes doesn't work on first time:
func doRequestWithBasicAuth(completion : (success : Bool, html: String?, error : NSError?) -> Void) {
if let user = self.user {
let loginString = NSString(format: "%#:%#", user.login!, user.pwd!)
let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
let base64LoginString = loginData.base64EncodedStringWithOptions(nil)
let url = NSURL(string: user.service!.getURL())
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
if error == nil {
let htmlString = NSString(data: data, encoding: NSUTF8StringEncoding)
completion(success: true, html: htmlString as? String, error: nil)
} else {
completion(success: false, html: nil, error: error)
}
}
} else {
completion(success: false, html: nil, error: NSError())
}
}
This method is attached to a button, so on first tap I get this error:
BASIC AUTH ERROR: Error Domain=NSURLErrorDomain Code=-1012 "The
operation couldn’t be completed. (NSURLErrorDomain error -1012.)"
UserInfo=0x7bad5770
{NSErrorFailingURLKey=https:///auth/Logon.do,
NSErrorFailingURLStringKey=https:///auth/Logon.do,
NSUnderlyingError=0x7b9c47f0 "The operation couldn’t be completed.
(kCFErrorDomainCFNetwork error -1012.)"}
On second tap, call works fine... I can't understand why.. I print user login, psw and url: are the same on twice calls..
Any idea?

Resources