Remove duplication with calling the delegate for authentication details
Showing
1 changed file
with
82 additions
and
88 deletions
| @@ -51,36 +51,41 @@ static NSError *ASITooMuchRedirectionError; | @@ -51,36 +51,41 @@ static NSError *ASITooMuchRedirectionError; | ||
| 51 | 51 | ||
| 52 | // Private stuff | 52 | // Private stuff |
| 53 | @interface ASIHTTPRequest () | 53 | @interface ASIHTTPRequest () |
| 54 | - @property (assign) BOOL complete; | 54 | + |
| 55 | - @property (retain) NSDictionary *responseHeaders; | 55 | +- (BOOL)askDelegateForCredentials; |
| 56 | - @property (retain) NSArray *responseCookies; | 56 | +- (BOOL)askDelegateForProxyCredentials; |
| 57 | - @property (assign) int responseStatusCode; | 57 | + |
| 58 | - @property (retain) NSMutableData *rawResponseData; | 58 | +@property (assign) BOOL complete; |
| 59 | - @property (retain, nonatomic) NSDate *lastActivityTime; | 59 | +@property (retain) NSDictionary *responseHeaders; |
| 60 | - @property (assign) unsigned long long contentLength; | 60 | +@property (retain) NSArray *responseCookies; |
| 61 | - @property (assign) unsigned long long partialDownloadSize; | 61 | +@property (assign) int responseStatusCode; |
| 62 | - @property (assign, nonatomic) unsigned long long uploadBufferSize; | 62 | +@property (retain) NSMutableData *rawResponseData; |
| 63 | - @property (assign) NSStringEncoding responseEncoding; | 63 | +@property (retain, nonatomic) NSDate *lastActivityTime; |
| 64 | - @property (retain, nonatomic) NSOutputStream *postBodyWriteStream; | 64 | +@property (assign) unsigned long long contentLength; |
| 65 | - @property (retain, nonatomic) NSInputStream *postBodyReadStream; | 65 | +@property (assign) unsigned long long partialDownloadSize; |
| 66 | - @property (assign) unsigned long long totalBytesRead; | 66 | +@property (assign, nonatomic) unsigned long long uploadBufferSize; |
| 67 | - @property (assign) unsigned long long totalBytesSent; | 67 | +@property (assign) NSStringEncoding responseEncoding; |
| 68 | - @property (assign, nonatomic) unsigned long long lastBytesRead; | 68 | +@property (retain, nonatomic) NSOutputStream *postBodyWriteStream; |
| 69 | - @property (assign, nonatomic) unsigned long long lastBytesSent; | 69 | +@property (retain, nonatomic) NSInputStream *postBodyReadStream; |
| 70 | - @property (retain) NSLock *cancelledLock; | 70 | +@property (assign) unsigned long long totalBytesRead; |
| 71 | - @property (assign, nonatomic) BOOL haveBuiltPostBody; | 71 | +@property (assign) unsigned long long totalBytesSent; |
| 72 | - @property (retain, nonatomic) NSOutputStream *fileDownloadOutputStream; | 72 | +@property (assign, nonatomic) unsigned long long lastBytesRead; |
| 73 | - @property (assign, nonatomic) int authenticationRetryCount; | 73 | +@property (assign, nonatomic) unsigned long long lastBytesSent; |
| 74 | - @property (assign, nonatomic) int proxyAuthenticationRetryCount; | 74 | +@property (retain) NSLock *cancelledLock; |
| 75 | - @property (assign, nonatomic) BOOL needsProxyAuthentication; | 75 | +@property (assign, nonatomic) BOOL haveBuiltPostBody; |
| 76 | - @property (assign, nonatomic) BOOL updatedProgress; | 76 | +@property (retain, nonatomic) NSOutputStream *fileDownloadOutputStream; |
| 77 | - @property (assign, nonatomic) BOOL needsRedirect; | 77 | +@property (assign, nonatomic) int authenticationRetryCount; |
| 78 | - @property (assign, nonatomic) int redirectCount; | 78 | +@property (assign, nonatomic) int proxyAuthenticationRetryCount; |
| 79 | - @property (retain, nonatomic) NSData *compressedPostBody; | 79 | +@property (assign, nonatomic) BOOL needsProxyAuthentication; |
| 80 | - @property (retain, nonatomic) NSString *compressedPostBodyFilePath; | 80 | +@property (assign, nonatomic) BOOL updatedProgress; |
| 81 | - @property (retain) NSConditionLock *authenticationLock; | 81 | +@property (assign, nonatomic) BOOL needsRedirect; |
| 82 | - @property (retain) NSString *authenticationRealm; | 82 | +@property (assign, nonatomic) int redirectCount; |
| 83 | - @property (retain) NSString *proxyAuthenticationRealm; | 83 | +@property (retain, nonatomic) NSData *compressedPostBody; |
| 84 | +@property (retain, nonatomic) NSString *compressedPostBodyFilePath; | ||
| 85 | +@property (retain) NSConditionLock *authenticationLock; | ||
| 86 | +@property (retain) NSString *authenticationRealm; | ||
| 87 | +@property (retain) NSString *proxyAuthenticationRealm; | ||
| 88 | + | ||
| 84 | @end | 89 | @end |
| 85 | 90 | ||
| 86 | @implementation ASIHTTPRequest | 91 | @implementation ASIHTTPRequest |
| @@ -1335,6 +1340,25 @@ static NSError *ASITooMuchRedirectionError; | @@ -1335,6 +1340,25 @@ static NSError *ASITooMuchRedirectionError; | ||
| 1335 | [[self authenticationLock] unlockWithCondition:2]; | 1340 | [[self authenticationLock] unlockWithCondition:2]; |
| 1336 | } | 1341 | } |
| 1337 | 1342 | ||
| 1343 | +- (BOOL)askDelegateForProxyCredentials | ||
| 1344 | +{ | ||
| 1345 | + // If we have a delegate, we'll see if it can handle proxyAuthorizationNeededForRequest:. | ||
| 1346 | + // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate | ||
| 1347 | + id authorizationDelegate = [self delegate]; | ||
| 1348 | + if (!authorizationDelegate) { | ||
| 1349 | + authorizationDelegate = [self queue]; | ||
| 1350 | + } | ||
| 1351 | + | ||
| 1352 | + if ([authorizationDelegate respondsToSelector:@selector(proxyAuthorizationNeededForRequest:)]) { | ||
| 1353 | + [authorizationDelegate performSelectorOnMainThread:@selector(proxyAuthorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | ||
| 1354 | + [[self authenticationLock] lockWhenCondition:2]; | ||
| 1355 | + [[self authenticationLock] unlockWithCondition:1]; | ||
| 1356 | + | ||
| 1357 | + return YES; | ||
| 1358 | + } | ||
| 1359 | + return NO; | ||
| 1360 | +} | ||
| 1361 | + | ||
| 1338 | - (void)attemptToApplyProxyCredentialsAndResume | 1362 | - (void)attemptToApplyProxyCredentialsAndResume |
| 1339 | { | 1363 | { |
| 1340 | 1364 | ||
| @@ -1346,7 +1370,7 @@ static NSError *ASITooMuchRedirectionError; | @@ -1346,7 +1370,7 @@ static NSError *ASITooMuchRedirectionError; | ||
| 1346 | proxyAuthenticationMethod = (NSString *)CFHTTPAuthenticationCopyMethod(proxyAuthentication); | 1370 | proxyAuthenticationMethod = (NSString *)CFHTTPAuthenticationCopyMethod(proxyAuthentication); |
| 1347 | } | 1371 | } |
| 1348 | 1372 | ||
| 1349 | - | 1373 | + // If we haven't got a CFHTTPAuthenticationRef by now, something is badly wrong, so we'll have to give up |
| 1350 | if (!proxyAuthentication) { | 1374 | if (!proxyAuthentication) { |
| 1351 | [self cancelLoad]; | 1375 | [self cancelLoad]; |
| 1352 | [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileApplyingCredentialsType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Failed to get authentication object from response headers",NSLocalizedDescriptionKey,nil]]]; | 1376 | [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileApplyingCredentialsType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Failed to get authentication object from response headers",NSLocalizedDescriptionKey,nil]]]; |
| @@ -1364,22 +1388,8 @@ static NSError *ASITooMuchRedirectionError; | @@ -1364,22 +1388,8 @@ static NSError *ASITooMuchRedirectionError; | ||
| 1364 | if (err.domain == kCFStreamErrorDomainHTTP && (err.error == kCFStreamErrorHTTPAuthenticationBadUserName || err.error == kCFStreamErrorHTTPAuthenticationBadPassword)) { | 1388 | if (err.domain == kCFStreamErrorDomainHTTP && (err.error == kCFStreamErrorHTTPAuthenticationBadUserName || err.error == kCFStreamErrorHTTPAuthenticationBadPassword)) { |
| 1365 | 1389 | ||
| 1366 | [self setProxyCredentials:nil]; | 1390 | [self setProxyCredentials:nil]; |
| 1367 | - | ||
| 1368 | [self setLastActivityTime:nil]; | 1391 | [self setLastActivityTime:nil]; |
| 1369 | - | 1392 | + if ([self askDelegateForProxyCredentials]) { |
| 1370 | - // If we have a delegate, we'll see if it can handle authorizationNeededForRequest. | ||
| 1371 | - // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate | ||
| 1372 | - id authorizationDelegate = [self delegate]; | ||
| 1373 | - if (!authorizationDelegate) { | ||
| 1374 | - authorizationDelegate = [self queue]; | ||
| 1375 | - } | ||
| 1376 | - | ||
| 1377 | - if ([authorizationDelegate respondsToSelector:@selector(proxyAuthorizationNeededForRequest:)]) { | ||
| 1378 | - [authorizationDelegate performSelectorOnMainThread:@selector(proxyAuthorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | ||
| 1379 | - [[self authenticationLock] lockWhenCondition:2]; | ||
| 1380 | - [[self authenticationLock] unlockWithCondition:1]; | ||
| 1381 | - | ||
| 1382 | - // Hopefully, the delegate gave us some credentials, let's apply them and reload | ||
| 1383 | [self attemptToApplyProxyCredentialsAndResume]; | 1393 | [self attemptToApplyProxyCredentialsAndResume]; |
| 1384 | return; | 1394 | return; |
| 1385 | } | 1395 | } |
| @@ -1393,18 +1403,20 @@ static NSError *ASITooMuchRedirectionError; | @@ -1393,18 +1403,20 @@ static NSError *ASITooMuchRedirectionError; | ||
| 1393 | 1403 | ||
| 1394 | if (proxyCredentials) { | 1404 | if (proxyCredentials) { |
| 1395 | 1405 | ||
| 1406 | + // We use startRequest rather than starting all over again in load request because NTLM requires we reuse the request | ||
| 1396 | if (((proxyAuthenticationMethod != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || proxyAuthenticationRetryCount < 2) && [self applyCredentials:proxyCredentials]) { | 1407 | if (((proxyAuthenticationMethod != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || proxyAuthenticationRetryCount < 2) && [self applyCredentials:proxyCredentials]) { |
| 1397 | [self startRequest]; | 1408 | [self startRequest]; |
| 1398 | 1409 | ||
| 1399 | - // We've failed NTLM authentication twice, we should assume our credentials are wrong | 1410 | + // We've failed NTLM authentication twice, we should assume our credentials are wrong |
| 1400 | } else if (proxyAuthenticationMethod == (NSString *)kCFHTTPAuthenticationSchemeNTLM && proxyAuthenticationRetryCount == 2) { | 1411 | } else if (proxyAuthenticationMethod == (NSString *)kCFHTTPAuthenticationSchemeNTLM && proxyAuthenticationRetryCount == 2) { |
| 1401 | [self failWithError:ASIAuthenticationError]; | 1412 | [self failWithError:ASIAuthenticationError]; |
| 1402 | 1413 | ||
| 1414 | + // Something went wrong, we'll have to give up | ||
| 1403 | } else { | 1415 | } else { |
| 1404 | [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileApplyingCredentialsType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Failed to apply proxy credentials to request",NSLocalizedDescriptionKey,nil]]]; | 1416 | [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileApplyingCredentialsType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Failed to apply proxy credentials to request",NSLocalizedDescriptionKey,nil]]]; |
| 1405 | } | 1417 | } |
| 1406 | 1418 | ||
| 1407 | - // Are a user name & password needed? | 1419 | + // Are a user name & password needed? |
| 1408 | } else if (CFHTTPAuthenticationRequiresUserNameAndPassword(proxyAuthentication)) { | 1420 | } else if (CFHTTPAuthenticationRequiresUserNameAndPassword(proxyAuthentication)) { |
| 1409 | 1421 | ||
| 1410 | NSMutableDictionary *newCredentials = [self findProxyCredentials]; | 1422 | NSMutableDictionary *newCredentials = [self findProxyCredentials]; |
| @@ -1420,18 +1432,7 @@ static NSError *ASITooMuchRedirectionError; | @@ -1420,18 +1432,7 @@ static NSError *ASITooMuchRedirectionError; | ||
| 1420 | return; | 1432 | return; |
| 1421 | } | 1433 | } |
| 1422 | 1434 | ||
| 1423 | - // We've got no credentials, let's ask the delegate to sort this out | 1435 | + if ([self askDelegateForProxyCredentials]) { |
| 1424 | - // If we have a delegate, we'll see if it can handle authorizationNeededForRequest. | ||
| 1425 | - // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate | ||
| 1426 | - id authorizationDelegate = [self delegate]; | ||
| 1427 | - if (!authorizationDelegate) { | ||
| 1428 | - authorizationDelegate = [self queue]; | ||
| 1429 | - } | ||
| 1430 | - | ||
| 1431 | - if ([authorizationDelegate respondsToSelector:@selector(proxyAuthorizationNeededForRequest:)]) { | ||
| 1432 | - [authorizationDelegate performSelectorOnMainThread:@selector(proxyAuthorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | ||
| 1433 | - [[self authenticationLock] lockWhenCondition:2]; | ||
| 1434 | - [[self authenticationLock] unlockWithCondition:1]; | ||
| 1435 | [self attemptToApplyProxyCredentialsAndResume]; | 1436 | [self attemptToApplyProxyCredentialsAndResume]; |
| 1436 | return; | 1437 | return; |
| 1437 | } | 1438 | } |
| @@ -1443,6 +1444,25 @@ static NSError *ASITooMuchRedirectionError; | @@ -1443,6 +1444,25 @@ static NSError *ASITooMuchRedirectionError; | ||
| 1443 | 1444 | ||
| 1444 | } | 1445 | } |
| 1445 | 1446 | ||
| 1447 | +- (BOOL)askDelegateForCredentials | ||
| 1448 | +{ | ||
| 1449 | + // If we have a delegate, we'll see if it can handle proxyAuthorizationNeededForRequest:. | ||
| 1450 | + // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate | ||
| 1451 | + id authorizationDelegate = [self delegate]; | ||
| 1452 | + if (!authorizationDelegate) { | ||
| 1453 | + authorizationDelegate = [self queue]; | ||
| 1454 | + } | ||
| 1455 | + | ||
| 1456 | + if ([authorizationDelegate respondsToSelector:@selector(authorizationNeededForRequest:)]) { | ||
| 1457 | + [authorizationDelegate performSelectorOnMainThread:@selector(authorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | ||
| 1458 | + [[self authenticationLock] lockWhenCondition:2]; | ||
| 1459 | + [[self authenticationLock] unlockWithCondition:1]; | ||
| 1460 | + | ||
| 1461 | + return YES; | ||
| 1462 | + } | ||
| 1463 | + return NO; | ||
| 1464 | +} | ||
| 1465 | + | ||
| 1446 | - (void)attemptToApplyCredentialsAndResume | 1466 | - (void)attemptToApplyCredentialsAndResume |
| 1447 | { | 1467 | { |
| 1448 | if ([self needsProxyAuthentication]) { | 1468 | if ([self needsProxyAuthentication]) { |
| @@ -1458,7 +1478,6 @@ static NSError *ASITooMuchRedirectionError; | @@ -1458,7 +1478,6 @@ static NSError *ASITooMuchRedirectionError; | ||
| 1458 | authenticationMethod = (NSString *)CFHTTPAuthenticationCopyMethod(requestAuthentication); | 1478 | authenticationMethod = (NSString *)CFHTTPAuthenticationCopyMethod(requestAuthentication); |
| 1459 | } | 1479 | } |
| 1460 | 1480 | ||
| 1461 | - | ||
| 1462 | if (!requestAuthentication) { | 1481 | if (!requestAuthentication) { |
| 1463 | [self cancelLoad]; | 1482 | [self cancelLoad]; |
| 1464 | [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileApplyingCredentialsType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Failed to get authentication object from response headers",NSLocalizedDescriptionKey,nil]]]; | 1483 | [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileApplyingCredentialsType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Failed to get authentication object from response headers",NSLocalizedDescriptionKey,nil]]]; |
| @@ -1479,24 +1498,11 @@ static NSError *ASITooMuchRedirectionError; | @@ -1479,24 +1498,11 @@ static NSError *ASITooMuchRedirectionError; | ||
| 1479 | 1498 | ||
| 1480 | [self setLastActivityTime:nil]; | 1499 | [self setLastActivityTime:nil]; |
| 1481 | 1500 | ||
| 1482 | - // If we have a delegate, we'll see if it can handle authorizationNeededForRequest. | 1501 | + if ([self askDelegateForCredentials]) { |
| 1483 | - // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate | ||
| 1484 | - id authorizationDelegate = [self delegate]; | ||
| 1485 | - if (!authorizationDelegate) { | ||
| 1486 | - authorizationDelegate = [self queue]; | ||
| 1487 | - } | ||
| 1488 | - | ||
| 1489 | - if ([authorizationDelegate respondsToSelector:@selector(authorizationNeededForRequest:)]) { | ||
| 1490 | - [authorizationDelegate performSelectorOnMainThread:@selector(authorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | ||
| 1491 | - [[self authenticationLock] lockWhenCondition:2]; | ||
| 1492 | - [[self authenticationLock] unlockWithCondition:1]; | ||
| 1493 | - | ||
| 1494 | - // Hopefully, the delegate gave us some credentials, let's apply them and reload | ||
| 1495 | [self attemptToApplyCredentialsAndResume]; | 1502 | [self attemptToApplyCredentialsAndResume]; |
| 1496 | return; | 1503 | return; |
| 1497 | } | 1504 | } |
| 1498 | } | 1505 | } |
| 1499 | - // The delegate isn't interested, we'll have to give up | ||
| 1500 | [self cancelLoad]; | 1506 | [self cancelLoad]; |
| 1501 | [self failWithError:ASIAuthenticationError]; | 1507 | [self failWithError:ASIAuthenticationError]; |
| 1502 | return; | 1508 | return; |
| @@ -1533,19 +1539,7 @@ static NSError *ASITooMuchRedirectionError; | @@ -1533,19 +1539,7 @@ static NSError *ASITooMuchRedirectionError; | ||
| 1533 | return; | 1539 | return; |
| 1534 | } | 1540 | } |
| 1535 | 1541 | ||
| 1536 | - // We've got no credentials, let's ask the delegate to sort this out | 1542 | + if ([self askDelegateForCredentials]) { |
| 1537 | - // If we have a delegate, we'll see if it can handle authorizationNeededForRequest. | ||
| 1538 | - // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate | ||
| 1539 | - id authorizationDelegate = [self delegate]; | ||
| 1540 | - if (!authorizationDelegate) { | ||
| 1541 | - authorizationDelegate = [self queue]; | ||
| 1542 | - } | ||
| 1543 | - | ||
| 1544 | - if ([authorizationDelegate respondsToSelector:@selector(authorizationNeededForRequest:)]) { | ||
| 1545 | - [authorizationDelegate performSelectorOnMainThread:@selector(authorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | ||
| 1546 | - | ||
| 1547 | - [[self authenticationLock] lockWhenCondition:2]; | ||
| 1548 | - [[self authenticationLock] unlockWithCondition:1]; | ||
| 1549 | [self attemptToApplyCredentialsAndResume]; | 1543 | [self attemptToApplyCredentialsAndResume]; |
| 1550 | return; | 1544 | return; |
| 1551 | } | 1545 | } |
-
Please register or login to post a comment