in Source/TNLError.m [125:182]
BOOL TNLErrorIsNetworkSecurityError(NSError * __nullable error)
{
NSString * const domain = error.domain;
NSInteger code = error.code;
if ([domain isEqualToString:TNLErrorDomain] && TNLErrorCodeRequestOperationAuthenticationChallengeCancelled == code) {
// auth challenge failed
return YES;
}
if (![domain isEqualToString:NSURLErrorDomain] && ![domain isEqualToString:(NSString *)kCFErrorDomainCFNetwork]) {
// not an internet failure
return NO;
}
// Conveniently, NSURL errors and CFNetwork errors share the same error code values
if (-1022 == code) {
// Insecure request violates ATS
return YES;
} else if (-1200 == code) {
// skip! - this is SSL connection failure
// which is a network failure, not a security failure
} else if (code <= -1201 && code >= -1206) {
// SSL error
return YES;
} else if (-2000 == code) {
#if !TARGET_OS_WATCH
// cannot load from network - is it due to SSL?
if (nil != error.userInfo[(NSString *)kCFStreamPropertySSLPeerTrust]) {
// short cut - we have a "trust" which implicates network security
return YES;
}
// Some network errors can be underpinned by CFStream errors,
// which are not wrapped in an `NSError`,
// so we can look at the userInfo for specific keys
// (namely _kCFStreamErrorDomainKey and _kCFStreamErrorDomainCode)
id domainNumber = error.userInfo[@"_kCFStreamErrorDomainKey"];
if ([domainNumber respondsToSelector:@selector(intValue)]) {
if (kCFStreamErrorDomainSSL == [domainNumber intValue]) {
// It is an SSL error, treat as security error
// NOTE: there is a more specific subset of error codes which we are ignoring (see Security/SecureTransport.h)
return YES;
}
}
#endif // !WATCH
}
NSError * const underlyingError = error.userInfo[NSUnderlyingErrorKey];
if (underlyingError) {
// recurse to see if the underlying error is network security related
return TNLErrorIsNetworkSecurityError(underlyingError);
}
return NO;
}