My server provide several authentication methods: NTLM and digest.
My iOS client won't handle the NTLM authentication, so I implement the connection:willSendRequestForAuthenticationChallenge:
delegate to reject the NTLM, then use correct credential only for the digest authentication challenge.
Everything works fine on iOS 7 so far.
But on iOS 8, I found a weird behavior:
the connection:willSendRequestForAuthenticationChallenge:
delegate won't be called at most time (95%)!!
I got this error instead:
Error: Error Domain=NSPOSIXErrorDomain Code=54 "The operation couldn’t be completed. Connection reset by peer"
UserInfo=0x16520fb0 {_kCFStreamErrorCodeKey=54,
NSErrorPeerAddressKey=<CFData 0x16682e40 [0x2f752440]>{length = 16, capacity = 16, bytes = 0x10020d7eac12780b0000000000000000},
NSErrorFailingURLKey=http://SERVER_IP:SERVER_PORT/Tunnel/Message.aspx,
NSErrorFailingURLStringKey=http://SERVER_IP:SERVER_PORT/Tunnel/Message.aspx,
_kCFStreamErrorDomainKey=1}
Only 5% time the delegate is correctly called and work as usual.
Below shows how I send my request to server and handle the authentication challenge:
- (void)postRequest
{
NSString *IP = SERVER_IP;
int port = SERVER_PORT;
NSString *url = [NSString stringWithFormat:@"http://%@:%d/Tunnel/Message.aspx", IP, port];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
NSString *xml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?><GetServerInfo></GetServerInfo>"];
[request setHTTPBody: [xml dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSLog(@"%@", challenge.protectionSpace);
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPDigest])
{
if ([challenge previousFailureCount] == 0)
{
[[challenge sender] useCredential:[NSURLCredential credentialWithUser:USERNAME
password:PASSWORD
persistence:NSURLCredentialPersistenceNone]
forAuthenticationChallenge:challenge];
}
else
{
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
}
}
else
{
[[challenge sender] rejectProtectionSpaceAndContinueWithChallenge:challenge];
}
}
Those code work on iOS 7, willSendRequestForAuthenticationChallenge
get called several times during the authentication challenge, but not even called any once on iOS 8!
Could this be a bug of iOS 8 or something changed since iOS 8?