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