I am creating the iOS app that uses rest API's that is hosted on HTTPS. This domain have valid CA approved certificate for SSL and TLS. But when I make a NSURL request from my app it works fine first time but after half an hour when I will make NSURL Request it returns NSURL Error -1012.
I also tried to handle Authentication Challenges and TLS Chain Validation using the below mentioned methods:
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
The process I used that is mentioned on below link:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/AuthenticationChallenges.html#//apple_ref/doc/uid/TP40009507-SW3
When I debug the canAuthenticateAgainstProtectionSpace and checked the protectionspace value it displays request have NSURLAuthenticationMethodServerTrust problem.
I tried different different scenarios to handle the problem.
1. In canAuthenticateAgainstProtectionSpace method if I found NSURLAuthenticationMethodServerTrust validation then I returned NO, then didReceiveAuthenticationChallenge method never called but API returns blank string.
2. In canAuthenticateAgainstProtectionSpace method if I found NSURLAuthenticationMethodServerTrust validation then I returned YES, then didReceiveAuthenticationChallenge method called and when I used continueWithoutCredentialForAuthenticationChallenge, performDefaultHandlingForAuthenticationChallenge and cancelAuthenticationChallenge methods one by one but nothing happening always I am getting the same result blank string and on cancelAuthenticationChallenge I am getting the NSURL Error -1012.
Our API is hosted on http://uat-exchange.vrmco.com/
Please help me what I am missing or is any thing that we need to used to resolve this error.
Thanks in Advance.
I don't think this is a TLS problem if it works the first time. IIRC, unless you're providing custom TLS handler methods (returning YES for the server trust protection space in your canAuthenticateAgainst... method), a 1012 error typically means a failure to authenticate the user to the server rather than the other way around. (There are other error codes for TLS failures—1202 in particular.)
My first guess would be that your server is requiring some kind of cookie-based authentication, and is returning an HTTP 401 error code when that cookie expires. If so, you should probably treat that as an indication that you need to redo the login process.
Related
I am sending a request to server, which is handling the request and responsding. However on my app I am receiving:
Error Domain=NSURLErrorDomain Code=-1017 "cannot parse response" UserInfo=0x167668d0
{NSErrorFailingURLStringKey=https://***, _kCFStreamErrorCodeKey=-1,
NSErrorFailingURLKey=https://***/, NSLocalizedDescription=cannot
parse response, _kCFStreamErrorDomainKey=4, NSUnderlyingError=0x16731990 "cannot parse
response"
Accept field in http request is adequate.
I cannot even see what messege is arriving, because NSHTTPURLResponse object is null.
What can be an issue and in what way I can see what message is coming not using things like wireshark.
Thank You!
I got the same problem, and the reason is that the API require GET http method, and I need pass a parameter, I send it by the following code:
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
When I execute the request with GET method, it will report the error.
My solution is when the API need GET method, the parameter should add on the URL, such as http://apiserver/api?paramName=paramValue, when the API method is POST, then use the code above, set the HTTPBody for the request object.
If iOS cannot parse response, the problem must be in improper format http response from server, even if You are said, that everything is 100% correct, bacause other services communicate with it.
In my case an Android app communicated successfully, because network framework used there was not so restrictive and even if the content-length of http response does not fit the actual length of data, it could read this message, unlike ios.
Use tcpdump to check http communication!
I got the same issue when I tried to call a web method using http GET method instead of http POST. The web service method was expecting POST request not GET. Hope this information will help some one.
If you are using (iOS8 has a problem with this but works in iOS7)
NSData *dataToSend = [jsonData dataUsingEncoding:NSUTF16BigEndianStringEncoding]
to send to the server, please make it as per below:
NSData *dataToSend = [jsonData dataUsingEncoding:NSUTF8StringEncoding]
I was seeing this error because a framework I was using was trying to send URL parameters in a GET request inside a JSON encoded body (instead of as URL-encoded parameters in the URL string as it should have been). That was causing the server send back an "invalid parameters message" which the client couldn't handle and instead aborted mid-request. Switching from body parameters to URL-encoded parameters for GET requests fixed the problem.
First I would ensure you are sending the correct parameters both in the body and the headers. I was receiving this error and after moving one of the parameters from the body into the header I received the correct response.
If there is any documentation for the api make sure you follow it properly.
I'm developing an iOS app that makes frequent requests to a web server, and I'm using AFNetworking (which I very much like). However, I'm running into a problem with authorization that I just can't solve.
The server requires me to provide an authorization header in order to get the response that I want. Specifically, the authorization headers should be like so:
Authorization = "ApiKey some-user-name:someNumericalApiKey"
I'm using AFNetworking throughout the project, and everything works fine, except for this authorization issue. I'm using the following code:
[myClient setDefaultHeader:#"Authorization" value:#"ApiKey some-user-name:someNumericalApiKey"];
where myClient points to an AFHTTPClient object. Strange enough, when I log the request in XCode using AFHTTPRequestOperationLogger, the logger claims that I have the correct headers set. However, the authorization header does not seem to reach the server - I can't see it in the server log.
To isolate the problem, I've tried to make the exact same request using good old NSURLRequest, as well as curl, and the requests library in Python - all of these work fine, i.e. the authorization header is sent & received (i.e. I can see it in the server log), and the server response is what it should be.
If anyone has run into the same problem (and has found a solution) I would very much appreciate to hear from you.
Thanks.
Sometimes (especially with Django) this is caused by redirection stripping of header parameters. For instance, /Object redirects to /Object/ in the background and removes the necessary auth parameter during the switch.
If you're using AFNetworkActivityLogger with level AFLoggerLevelDebug then you should be able to check this out in the console. If you see a POST request with /Object and the response with /Object/ then this might indicate redirection stripping is taking place.
If you construct your operation manually then the defaultHeaders are not applied, that might be the cause of your problem.
Does anybody know where an iOS app can see the default headers that NSUrlRequest sets for an HTTP request?
Just creating NSUrlRequest with "http://.." NSURL and then asking: [request allHTTPHeaderFields] returns an empty dictionary. But I know that for example "Accept-Encoding" is set to "gzip". So I want to get all that fields and show them in a HTTP request demo.
I've also tried to swizzle [NSMutableURLRequest setValue:forHTTPHeaderField:], but it seems that it is not used by underlying API (NSURLRequest or NSURLConnection) to set those default fields I'm hunting for.
I'm making just a simple iOS demo which shows HTTP request and response information, so it doesn't really matters if it will be a public or private API used for that.
Your app cannot. It's done all down in CFNetwork - Communicating with HTTP Servers. I believe it just adds missing header values not supplied by NSURLRequest.
The defaults are:
USER-AGENT "AppName - Eng/1.0 CFNetwork/485.13.9 Darwin/10.7.0"
ACCEPT "*/*"
ACCEPT-LANGUAGE "en-us"
ACCEPT-ENCODING "gzip, deflate"
CONNECTION "keep-alive"
hmm... maybe you might want to try within
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse
method in your custom nsurlconnection class. although the documentation mentions something about redirects, this is certainly worth looking into.
That may be an overkill, but based on Matt Gallagher's blog post I've created even more simpler local HTTP listener and sent a separate [mutableCopy]ed request to it to be able to read and output all HTTP headers that this request has.
Better solution must be to setup a local HTTP request catcher, it must look nicer I think, but for the scope of simple demo just to show all sent/received headers this solution is OK.
I've been creating a Credential Provider DLL that authenticates via the internet before allowing login. However this hasn't worked as well as I expected because my WinHTTP request isn't getting sent. I've confirmed this using wire shark. but I can't figure out why it's not sending any requests off. I've checked that my code is actually calling the functions properly - and they are. But the http request never makes it off. I'm slightly confused at this point and I'm seeking to know if there is some blanket block against https Requests at login.
If you are using C++ CP-V2, so you can use easily from CPPRESTSDK library.
Note: You must note the DNS address and the digital certificate you are using must be valid.
I have an application where the html/javascript code executes fine in a standalone browser safari, but when the ajax calls are executed in PhoneGap, they all fail with the Network Error 101.
I am requesting XML documents
Yes.
BUT, it does not gracefully handle certificate errors with the HTTPS protocol. I ended up writing my own code to establish the initial connection with the server and ignore the cert errors
here is the code
http://blog.clearlyinnovative.com/post/1012434483/phonegap-and-iphone-development
Phonegap does support HTTPS ajax requests, but like Aaron mention it does not gracefully handle certificate errors. In my case, we have valid certs in our production environment; but for our dev environment we overrode one of the NSUrl methods:
#implementation NSURLRequest (IgnoreSSL)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
return YES;
}
#end
This has been tested with phonegap 1.7(and 1.9) and it worked well. You can put this code in your MainViewController.m.
Note that I recommend this code only for development environment. This most likely will not be accepted by the app store; since we are overriding a private api. Just use valid certs in production.