Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Development: Why do I always get the "A connection failure occurred" on the 1st attempt, but success on the next?

I'm using the ASIHTTPRequest lib in my iOS app to make RESTful requests to my Rails 3 web app. I seeing a weird and somewhat consistent error the 1st time I try to make a POST request to my web app, but then the POST request works fine the on the second attempt. The exact error is...

Error Domain=ASIHTTPRequestErrorDomain Code=1 "A connection failure occurred" UserInfo=0xb513740 {NSUnderlyingError=0xb5135a0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1005.)", NSLocalizedDescription=A connection failure occurred}

And here's my ASIHTTPRequest code for making the POST request...

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://myrails3app.heroku.com/tournaments/%d/register.json", tid]];
    __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
    [request setRequestMethod:@"POST"];
    [request addPostValue:username forKey:@"username"];

    [request setCompletionBlock:^
    {
        NSData *responseData = [request responseData];     
        NSLog(@"Success!");
    }];

    // Set the code to be called when the request fails
    [request setFailedBlock:^
     {
         NSError *error = [request error];
         NSLog(@"Error: %@", [error localizedDescription]);
     }];

    // Start the request
    [request startAsynchronous];

It's worth mentioning that when it errors out, it errors out incredibly quickly! Also, for what it's worth, my Rail 3 app that I'm making the POST request to is hosted on Heroku. Your thoughts?

Thanks so much for your wisdom!

like image 695
BeachRunnerFred Avatar asked May 21 '11 14:05

BeachRunnerFred


2 Answers

This issue I had a lot of hard time to figure out why. The problem resides in ASIHTTPRequest itself (iOS), not the rails code.

To make a long story short, the problem is specific to the use of persistent connection for every request sent by ASIHTTPRequest.

While this is good for GET requests, most server implementation does not allow persistent connection to be used with POST request.

I didn't really have time to investigate it deeply on the server side of things but I think that the problem resides with the 100-Continue header that should be sent (and which isn't) with request that has body attached to it (hence PUT/POST). If you want to have a deeper look at what I'm talking about go have a read at the spec sheet: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html

So the persistent connection used by ASIHTTPRequest wait for a 100 response to be sent, which is never sent. so it ends up being timed out.

A fix is to set persistentConnection to NO with your post requests like the following:

ASIHTTPRequest *req                     = [ASIHTTPRequest requestWithURL:url];
req.shouldAttemptPersistentConnection   = NO;
like image 131
Pier-Olivier Thibault Avatar answered Nov 11 '22 12:11

Pier-Olivier Thibault


Secure Connection Failed

      An error occurred during a connection to login.yahoo.com.

SSL received a record with an incorrect Message Authentication Code.

(Error code: ssl_error_bad_mac_read)

The page you are trying to view can not be shown because the authenticity of the received data could not be verified. Please contact the web site owners to inform them of this problem. Alternatively, use the command found in the help menu to report this broken site.

like image 1
krishna Avatar answered Nov 11 '22 14:11

krishna