AFURLSessionManager downloadTaskWithRequest cancels immediately - ios

I'm using the exact sample code from the AFNetworking README to download a file, but the request is immediately cancelled:
File downloaded to: (null) with response = (null) and error = Error Domain=NSURLErrorDomain Code=-999 "cancelled"
I thought another request might be canceling this one out in my larger application, so I created a new sample project with just one button that just does this download. So I know that isn't the case.
Googling for a solution only returned information about how to voluntarily cancel an existing request.

It is a problem about redirections. Happens with 302 and 301 redirections.
I resolve the problem setting on the AFURLSessionManager object this block:
[manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition (NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential) {
return NSURLSessionAuthChallengePerformDefaultHandling;
}];
I found the solution here: AFNetworking 2.0: NSURLSessionDownloadTask is cancelled when received 302 to AWS S3

The server was responding with a 302 and the request was canceling itself. I had no way of knowing that unfortunately until I did a curl on the command line.

Related

Parse custom value from NSError

When API request fails, I need to know number of failed attempts. Backend has added a property ‘attempts’ to error object. How can I find this value, since NSError is not KV pairing compliant and I don’t see it when I log the error object to console.
If you are using NSURLSession for urlrequest , then you will have delegate methods for NSURLSession responses , they are:
->didReceiveResponse = here you receive the response that urlrequest has completed and response received status
->didReceiveData = here you get the SUCCESS response date for your request
->didCompleteWithError = here you get the FAILURE response (i.e) ERROR callback ,this is called every time when request fails , which gives you error data

AFNetworking 2.0 - unexpected NSURLErrorDomain error -1012

We ran into the following issue with our app that uses AFNetworking 2.0.
When using AFHTTPRequestOperationManager's GET method, we got an error NSURLErrorDomain code -1012. The request used HTTPS and the server does not require user authentication. The request never reached the server by the way.
We have run several tests and this is the first time the error was produced and we are wondering how this error can get produced because it does not seem relevant.
Setup of AFHTTPRequestOperationManager :
httpOperationManager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:
[NSURL URLWithString: HTTPS_URL)]];
httpOperationManager.responseSerializer =
[AFXMLParserResponseSerializer serializer];
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled: YES];
GET REQUEST
AFHTTPRequestOperation *op =[httpOperationManager GET:
[NSString stringWithFormat:SOME_PATH]
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
//code to setup NSXMLParser ...
}
failure: ^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error %#", [error localizedDescription]);
}];
I think you already solved the problem, but if you are trying to authenticate in a server that doesn't have a valid certificate you have to set YES for property allowInvalidCertificates in your AFHTTPRequestOperationManager object:
[yourManager.requestSerializer setAuthorizationHeaderFieldWithUsername:#"your_username" password:#"your_password"];
[yourManager.securityPolicy setAllowInvalidCertificates:YES];
Also, as #a1phanumeric said, it can be necessary to include this line:
[yourManager.securityPolicy setValidatesDomainName:NO];
Cheers.
NSURLErrorDomain -1012 is NSURLErrorUserCancelledAuthentication. (See the error code list and search for -1012.)
You state, "the server does not require user authentication". But this error would not be called if that were true.
Possible causes:
Your server is erroneously requesting authorization (a server bug)
The URL formed with HTTPS_URL and SOME_PATH is not what you expect, and some other server is requesting authorization
Some intermediary (like a proxy server, or an access point) is requiring authorization.
Some debugging tips:
Set breakpoints inside the AFNetworking implementation to see which URL is being hit
Configure AFHTTPRequestOperationLogger so you can see the actual request body and response in your console log
Make the same request with curl or Advanced Rest Client and observe the server's response
Side note: I think [NSString stringWithFormat:SOME_PATH] is pointless - why not just use SOME_PATH?

NSURLConnection sendSynchronousRequest response is nil upon invalid credential

I'm getting a weird behavior where using sendSynchronousRequest or sendAsynchronousRequest with invalid credential will make the nsurlresponse nil. But the old way with the [[NSURLConnection alloc] initWithRequest:request delegate:self]; I get the 401 response code.
The error value using the sendSynchronousRequest or sendAsynchronousRequest is
Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be
completed. (NSURLErrorDomain error -1012.)" UserInfo=0x756ecb0
{NSErrorFailingURLKey=myurl,
NSErrorFailingURLStringKey=myurl,
NSUnderlyingError=0x75704d0 "The operation couldn’t be completed.
(kCFErrorDomainCFNetwork error -1012.)"
Does someone have a clue as to why it is like that? Any information on this is appreciated. I was expecting to get a 401 response from sendSynchronousRequest or sendAsynchronousRequest
Thanks,
This error is caused when a WWW-Authenticate: HTTP header is returned with the 401 response, asking for user-interaction to enter valid credentials. The NSURLConnection processes the HTTP headers and the response body, returning the response data correctly as an NSData object, but leaving the returningResponse object as nil.
According to Apple's Foundation Constants Reference, the error -1012 is:
NSURLErrorUserCancelledAuthentication
Returned when an asynchronous request for authentication is cancelled by the user.
This is typically incurred by clicking a “Cancel” button in a username/password dialog, rather than the user making an attempt to
authenticate.
I am speculating that it automatically treats the WWW-Authenticate: header as a request for credentials that was cancelled by the user (since it is headless) and generates the error. Then some other part of the code-path that should set the response is not executed because there was an error. Personally I think this is either a bug or bad design. It should be ok to get a valid HTTP response and an error at the same time, either way, you get a valid HTTP response so the returningResponse should be set. Bad Apple!

RestKit: How to resubmit failed request after re-authenticating?

The API I'm developing against requires me to present an authentication token in a custom HTTP header. This token expires every few minutes, and could happen while the user is still within the app as long as they have been idle long enough. When the token has expired I receive a 403 response but I only find out after attempting a request.
What's the best way to get RestKit to automatically reauthenticate and retry the request so I don't have to put in this logic everywhere I make a request? Responses to similar questions have suggested using the RKRequestDelegate protocol or the RKObjectLoaderDelegate protocol but unfortunately these are no longer part of RestKit (as of 0.20).
Any idea what the "correct" approach should be now? Should I be subclassing RKObjectManager and tacking on a retry to each of the request operations or should I provide a custom HTTPOperation or HTTPClient class or is there some better approach altogether? Thanks!
Catch it in Failure block , and check for the status code and re-do the authentication
RKObjectRequestOperation *requestOp = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:#[getObjResp]];
[requestOp setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
....
}
} failure:^(RKObjectRequestOperation *operation, NSError *error){
// Here your status code check
// Here your retry-code
}

ASIHTTPRequest GET Request Issue

My request is
request_ = [[ASIFormDataRequest requestWithURL:requestUrl] retain];
[request_ setDelegate:self];
[request_ setRequestMethod:#"GET"];
[request_ setTimeOutSeconds:HTTP_TIME_OUT];
[request_ startAsynchronous];
But the response from the server is
HTTP Status 405 - Request method 'GET' not supported. The specified HTTP method is not allowed for the requested resource (Request method 'GET' not supported).
Please note that the url doesn't have any "GET" parameters along with it even though it is a get request. The thing is I am getting the proper response from the server when simply I take the request URL in a browser or when I call it using "HttpRequester"(a Firefox add-on to test http requests - well I'm sure you know that). What could have went wrong?
Thanks in advance.
Balu
For GET requests, use ASIHTTPRequest.
ASIFormDataRequest is for POST requests.
However, if all you need is a simple GET request, why bother with ASI? You can do this in a dispatch_async block:
dispatch_async(<some_queue>, ^{
NSError * error = nil;
NSString * response = [NSString stringWithContentsOfURL: stringWithContentsOfURL: requestUrl error: &error];
[self performSelectorOnMainThread: #selector(processResult:) withObject: response waitUntilDone: NO];
});
Solved it. It was because of the absence of the header parameter "Accept" in requests that have been made. Once it was added, everything worked like a charm.
Also replaced ASIFormDataRequest with ASIHTTPRequest(that one was a silly mistake).
Seems it is a server side issue. Please verify if all the header parameters as required by the server are there in request.
why you create a ASIFormDataRequest aka POSTRequest and set the RequestMethod to GET?
If you want to make a GET Request use ASIHTTPRequest instead.

Resources