I got an app which use ASIHTTPRequest.
I recompiled my app with iOS 5 (sdk : 5.0 / xcode: 4.2 Build 4D199 ) and the https connections fail with error message (the same call with https disabled works fine):
Error Domain=ASIHTTPRequestErrorDomain Code=1 "A connection failure occurred" UserInfo=0xa8e66e0 {NSUnderlyingError=0xa8ac6c0 "The operation couldn’t be completed. (OSStatus error -9844.)", NSLocalizedDescription=A connection failure occurred}
With debug log enabled:
[STATUS] Starting asynchronous request <ASIFormDataRequest: 0xd96fc00>
[CONNECTION] Request <ASIFormDataRequest: 0xd96fc00> will not use a persistent connection
[STATUS] Request <ASIFormDataRequest: 0xd96fc00>: Failed
[CONNECTION] Request #(null) failed and will invalidate connection #(null)
I found this related post:
https://devforums.apple.com/message/537440#537440
which could explain my problem.
based on the idea that iOS 5 prefer TLS 1.2, I try changing the setting kCFStreamSocketSecurityLevelTLSv1 in AIHTTPRequest.m
NSDictionary *sslProperties = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool:YES],
kCFStreamSSLAllowsExpiredCertificates,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
kCFNull,kCFStreamSSLPeerName,
kCFStreamSocketSecurityLevelTLSv1, kCFStreamSSLLevel,// my modif
nil];
with no success. Maybe my modification is incorrect?
Details:
- I got the ARC disabled
- I use libz.1.2.5.dylib
- I updated the ASIHTTPRequest a week ago.
I do not know if the issue is a certificate story (like TLS version) or something else.
any help/idea is welcome !
Here is the final solution:
https://developer.apple.com/library/ios/#technotes/tn2287/_index.html#//apple_ref/doc/uid/DTS40011309
NSDictionary *sslProperties = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
kCFNull,kCFStreamSSLPeerName,
@"kCFStreamSocketSecurityLevelTLSv1_0SSLv3", kCFStreamSSLLevel,
nil];
Adding this param:
@"kCFStreamSocketSecurityLevelTLSv1_0SSLv3", kCFStreamSSLLevel,
On our setup the problem was fixed by inserting
[sslProperties setObject:(NSString *)kCFStreamSocketSecurityLevelSSLv3 forKey:(NSString *)kCFStreamSSLLevel];
just above
CFReadStreamSetProperty((CFReadStreamRef)[self readStream], kCFStreamPropertySSLSettings, sslProperties);
in the Handle SSL certificate settings section.
EDIT:
According to http://developer.apple.com/library/ios/#technotes/tn2287/_index.html#//apple_ref/doc/uid/DTS40011309 the following should be more robust
[sslProperties setObject:@"kCFStreamSocketSecurityLevelTLSv1_0SSLv3" forKey:(NSString *)kCFStreamSSLLevel];
looks like the ASIHTTPRequest is being abandoned.
and the current version got issue with iOS 5.
http://groups.google.com/group/asihttprequest/browse_thread/thread/7731197dbe71c260
they recommend moving to NSURLConnection.
These are the things I would try:
- Download a fresh copy of asihttprequest, put it into a newly created very simple app that just makes single http and see if it behaves the same
- Try against other https servers see if you get the same behaviour (try with some of the big name ones, eg https://twitter.com - linkedin, google, etc, all have https versions too)
- Try the same server in Safari (still on the iOS device)
For what it's worth, I have ASIHTTPRequest on iOS5 working fine with my customer's https servers - I didn't have to make any changes for iOS5.
Try using kCFStreamSocketSecurityLevelSSLv3 instead of TLSv1. That worked for me when I ran into a similar situation. I'm not sure why the auto-negotiation isn't falling back to the right protocol, but at least on some servers it seems to fail under ASIHttpRequest where it would work with NSURLConnection.