Ben Copsey

Bug fixes

@@ -386,7 +386,7 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; @@ -386,7 +386,7 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount;
386 386
387 // Unlock (unpause) the request thread so it can resume the request 387 // Unlock (unpause) the request thread so it can resume the request
388 // Should be called by delegates when they have populated the authentication information after an authentication challenge 388 // Should be called by delegates when they have populated the authentication information after an authentication challenge
389 -- (void)retryWithAuthentication; 389 +- (void)retryUsingSuppliedCredentials;
390 390
391 // Should be called by delegates when they wish to cancel authentication and stop 391 // Should be called by delegates when they wish to cancel authentication and stop
392 - (void)cancelAuthentication; 392 - (void)cancelAuthentication;
@@ -77,8 +77,16 @@ BOOL isBandwidthThrottled = NO; @@ -77,8 +77,16 @@ BOOL isBandwidthThrottled = NO;
77 77
78 BOOL shouldThrottleBandwithForWWANOnly = NO; 78 BOOL shouldThrottleBandwithForWWANOnly = NO;
79 79
  80 +// Mediates access to the session cookies so requests can't modify them when they are in use
80 static NSLock *sessionCookiesLock = nil; 81 static NSLock *sessionCookiesLock = nil;
81 82
  83 +// This lock ensures delegates only receive one notification that authentication is required at once
  84 +// When using ASIAuthenticationDialogs, it also ensures only one dialog is shown at once
  85 +// If a request can't aquire the lock immediately, it means a dialog is being shown or a delegate is handling the authentication challenge
  86 +// Once it gets the lock, it will try to look for existing credentials again rather than showing the dialog / notifying the delegate
  87 +// This is so it can make use of any credentials supplied for the other request, if they are appropriate
  88 +static NSRecursiveLock *delegateAuthenticationLock = nil;
  89 +
82 // Private stuff 90 // Private stuff
83 @interface ASIHTTPRequest () 91 @interface ASIHTTPRequest ()
84 92
@@ -132,6 +140,7 @@ static NSLock *sessionCookiesLock = nil; @@ -132,6 +140,7 @@ static NSLock *sessionCookiesLock = nil;
132 progressLock = [[NSRecursiveLock alloc] init]; 140 progressLock = [[NSRecursiveLock alloc] init];
133 bandwidthThrottlingLock = [[NSLock alloc] init]; 141 bandwidthThrottlingLock = [[NSLock alloc] init];
134 sessionCookiesLock = [[NSLock alloc] init]; 142 sessionCookiesLock = [[NSLock alloc] init];
  143 + delegateAuthenticationLock = [[NSRecursiveLock alloc] init];
135 bandwidthUsageTracker = [[NSMutableArray alloc] initWithCapacity:5]; 144 bandwidthUsageTracker = [[NSMutableArray alloc] initWithCapacity:5];
136 ASIRequestTimedOutError = [[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIRequestTimedOutErrorType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"The request timed out",NSLocalizedDescriptionKey,nil]] retain]; 145 ASIRequestTimedOutError = [[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIRequestTimedOutErrorType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"The request timed out",NSLocalizedDescriptionKey,nil]] retain];
137 ASIAuthenticationError = [[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIAuthenticationErrorType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Authentication needed",NSLocalizedDescriptionKey,nil]] retain]; 146 ASIAuthenticationError = [[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIAuthenticationErrorType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Authentication needed",NSLocalizedDescriptionKey,nil]] retain];
@@ -1261,6 +1270,9 @@ static NSLock *sessionCookiesLock = nil; @@ -1261,6 +1270,9 @@ static NSLock *sessionCookiesLock = nil;
1261 } 1270 }
1262 [self setProxyCredentials:newCredentials]; 1271 [self setProxyCredentials:newCredentials];
1263 return YES; 1272 return YES;
  1273 + } else {
  1274 + [ASIHTTPRequest setSessionAuthentication:NULL];
  1275 + [ASIHTTPRequest setSessionCredentials:nil];
1264 } 1276 }
1265 } 1277 }
1266 return NO; 1278 return NO;
@@ -1279,7 +1291,6 @@ static NSLock *sessionCookiesLock = nil; @@ -1279,7 +1291,6 @@ static NSLock *sessionCookiesLock = nil;
1279 [self saveCredentialsToKeychain:newCredentials]; 1291 [self saveCredentialsToKeychain:newCredentials];
1280 } 1292 }
1281 if (useSessionPersistance) { 1293 if (useSessionPersistance) {
1282 -  
1283 [ASIHTTPRequest setSessionAuthentication:requestAuthentication]; 1294 [ASIHTTPRequest setSessionAuthentication:requestAuthentication];
1284 [ASIHTTPRequest setSessionCredentials:newCredentials]; 1295 [ASIHTTPRequest setSessionCredentials:newCredentials];
1285 } 1296 }
@@ -1404,7 +1415,7 @@ static NSLock *sessionCookiesLock = nil; @@ -1404,7 +1415,7 @@ static NSLock *sessionCookiesLock = nil;
1404 } 1415 }
1405 1416
1406 // Called by delegate or authentication dialog to resume loading once authentication info has been populated 1417 // Called by delegate or authentication dialog to resume loading once authentication info has been populated
1407 -- (void)retryWithAuthentication 1418 +- (void)retryUsingSuppliedCredentials
1408 { 1419 {
1409 [[self authenticationLock] lockWhenCondition:1]; 1420 [[self authenticationLock] lockWhenCondition:1];
1410 [[self authenticationLock] unlockWithCondition:2]; 1421 [[self authenticationLock] unlockWithCondition:2];
@@ -1426,6 +1437,9 @@ static NSLock *sessionCookiesLock = nil; @@ -1426,6 +1437,9 @@ static NSLock *sessionCookiesLock = nil;
1426 [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentProxyAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; 1437 [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentProxyAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]];
1427 [[self authenticationLock] lockWhenCondition:2]; 1438 [[self authenticationLock] lockWhenCondition:2];
1428 [[self authenticationLock] unlockWithCondition:1]; 1439 [[self authenticationLock] unlockWithCondition:1];
  1440 + if ([self error]) {
  1441 + return NO;
  1442 + }
1429 return YES; 1443 return YES;
1430 } 1444 }
1431 return NO; 1445 return NO;
@@ -1449,8 +1463,14 @@ static NSLock *sessionCookiesLock = nil; @@ -1449,8 +1463,14 @@ static NSLock *sessionCookiesLock = nil;
1449 [[self authenticationLock] lockWhenCondition:2]; 1463 [[self authenticationLock] lockWhenCondition:2];
1450 [[self authenticationLock] unlockWithCondition:1]; 1464 [[self authenticationLock] unlockWithCondition:1];
1451 1465
  1466 + // Was the request cancelled?
  1467 + if ([self error] || [[self mainRequest] error]) {
  1468 + return NO;
  1469 + }
  1470 +
1452 return YES; 1471 return YES;
1453 } 1472 }
  1473 + [delegateAuthenticationLock unlock];
1454 return NO; 1474 return NO;
1455 } 1475 }
1456 1476
@@ -1486,12 +1506,29 @@ static NSLock *sessionCookiesLock = nil; @@ -1486,12 +1506,29 @@ static NSLock *sessionCookiesLock = nil;
1486 // check for bad credentials, so we can give the delegate a chance to replace them 1506 // check for bad credentials, so we can give the delegate a chance to replace them
1487 if (err.domain == kCFStreamErrorDomainHTTP && (err.error == kCFStreamErrorHTTPAuthenticationBadUserName || err.error == kCFStreamErrorHTTPAuthenticationBadPassword)) { 1507 if (err.domain == kCFStreamErrorDomainHTTP && (err.error == kCFStreamErrorHTTPAuthenticationBadUserName || err.error == kCFStreamErrorHTTPAuthenticationBadPassword)) {
1488 1508
  1509 + // Prevent more than one request from asking for credentials at once
  1510 + [delegateAuthenticationLock lock];
  1511 +
  1512 + // Now we've aquirred the lock, it may be that the session contains credentials we can re-use for this request
  1513 + if ([self useSessionPersistance] && [self applyProxyCredentials:sessionProxyCredentials]) {
  1514 + [delegateAuthenticationLock unlock];
  1515 + [self startRequest];
  1516 + return;
  1517 + }
  1518 +
1489 [self setProxyCredentials:nil]; 1519 [self setProxyCredentials:nil];
1490 [self setLastActivityTime:nil]; 1520 [self setLastActivityTime:nil];
1491 if ([self askDelegateForProxyCredentials]) { 1521 if ([self askDelegateForProxyCredentials]) {
1492 [self attemptToApplyProxyCredentialsAndResume]; 1522 [self attemptToApplyProxyCredentialsAndResume];
  1523 + [delegateAuthenticationLock unlock];
1493 return; 1524 return;
1494 } 1525 }
  1526 + if ([self showProxyAuthenticationDialog]) {
  1527 + [self attemptToApplyProxyCredentialsAndResume];
  1528 + [delegateAuthenticationLock unlock];
  1529 + return;
  1530 + }
  1531 + [delegateAuthenticationLock unlock];
1495 } 1532 }
1496 [self cancelLoad]; 1533 [self cancelLoad];
1497 [self failWithError:ASIAuthenticationError]; 1534 [self failWithError:ASIAuthenticationError];
@@ -1518,6 +1555,16 @@ static NSLock *sessionCookiesLock = nil; @@ -1518,6 +1555,16 @@ static NSLock *sessionCookiesLock = nil;
1518 // Are a user name & password needed? 1555 // Are a user name & password needed?
1519 } else if (CFHTTPAuthenticationRequiresUserNameAndPassword(proxyAuthentication)) { 1556 } else if (CFHTTPAuthenticationRequiresUserNameAndPassword(proxyAuthentication)) {
1520 1557
  1558 + // Prevent more than one request from asking for credentials at once
  1559 + [delegateAuthenticationLock lock];
  1560 +
  1561 + // Now we've aquirred the lock, it may be that the session contains credentials we can re-use for this request
  1562 + if ([self useSessionPersistance] && [self applyProxyCredentials:sessionProxyCredentials]) {
  1563 + [delegateAuthenticationLock unlock];
  1564 + [self startRequest];
  1565 + return;
  1566 + }
  1567 +
1521 NSMutableDictionary *newCredentials = [self findProxyCredentials]; 1568 NSMutableDictionary *newCredentials = [self findProxyCredentials];
1522 1569
1523 //If we have some credentials to use let's apply them to the request and continue 1570 //If we have some credentials to use let's apply them to the request and continue
@@ -1528,17 +1575,22 @@ static NSLock *sessionCookiesLock = nil; @@ -1528,17 +1575,22 @@ static NSLock *sessionCookiesLock = nil;
1528 } else { 1575 } else {
1529 [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileApplyingCredentialsType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Failed to apply proxy credentials to request",NSLocalizedDescriptionKey,nil]]]; 1576 [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileApplyingCredentialsType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Failed to apply proxy credentials to request",NSLocalizedDescriptionKey,nil]]];
1530 } 1577 }
  1578 +
1531 return; 1579 return;
1532 } 1580 }
1533 1581
1534 if ([self askDelegateForProxyCredentials]) { 1582 if ([self askDelegateForProxyCredentials]) {
1535 [self attemptToApplyProxyCredentialsAndResume]; 1583 [self attemptToApplyProxyCredentialsAndResume];
  1584 + [delegateAuthenticationLock unlock];
1536 return; 1585 return;
1537 } 1586 }
1538 1587
1539 if ([self showProxyAuthenticationDialog]) { 1588 if ([self showProxyAuthenticationDialog]) {
1540 [self attemptToApplyProxyCredentialsAndResume]; 1589 [self attemptToApplyProxyCredentialsAndResume];
  1590 + [delegateAuthenticationLock unlock];
  1591 + return;
1541 } 1592 }
  1593 + [delegateAuthenticationLock unlock];
1542 1594
1543 // The delegate isn't interested and we aren't showing the authentication dialog, we'll have to give up 1595 // The delegate isn't interested and we aren't showing the authentication dialog, we'll have to give up
1544 [self failWithError:ASIAuthenticationError]; 1596 [self failWithError:ASIAuthenticationError];
@@ -1555,6 +1607,9 @@ static NSLock *sessionCookiesLock = nil; @@ -1555,6 +1607,9 @@ static NSLock *sessionCookiesLock = nil;
1555 [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; 1607 [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]];
1556 [[self authenticationLock] lockWhenCondition:2]; 1608 [[self authenticationLock] lockWhenCondition:2];
1557 [[self authenticationLock] unlockWithCondition:1]; 1609 [[self authenticationLock] unlockWithCondition:1];
  1610 + if ([self error]) {
  1611 + return NO;
  1612 + }
1558 return YES; 1613 return YES;
1559 } 1614 }
1560 return NO; 1615 return NO;
@@ -1577,6 +1632,10 @@ static NSLock *sessionCookiesLock = nil; @@ -1577,6 +1632,10 @@ static NSLock *sessionCookiesLock = nil;
1577 [[self authenticationLock] lockWhenCondition:2]; 1632 [[self authenticationLock] lockWhenCondition:2];
1578 [[self authenticationLock] unlockWithCondition:1]; 1633 [[self authenticationLock] unlockWithCondition:1];
1579 1634
  1635 + // Was the request cancelled?
  1636 + if ([self error] || [[self mainRequest] error]) {
  1637 + return NO;
  1638 + }
1580 return YES; 1639 return YES;
1581 } 1640 }
1582 return NO; 1641 return NO;
@@ -1617,17 +1676,31 @@ static NSLock *sessionCookiesLock = nil; @@ -1617,17 +1676,31 @@ static NSLock *sessionCookiesLock = nil;
1617 // check for bad credentials, so we can give the delegate a chance to replace them 1676 // check for bad credentials, so we can give the delegate a chance to replace them
1618 if (err.domain == kCFStreamErrorDomainHTTP && (err.error == kCFStreamErrorHTTPAuthenticationBadUserName || err.error == kCFStreamErrorHTTPAuthenticationBadPassword)) { 1677 if (err.domain == kCFStreamErrorDomainHTTP && (err.error == kCFStreamErrorHTTPAuthenticationBadUserName || err.error == kCFStreamErrorHTTPAuthenticationBadPassword)) {
1619 1678
  1679 + // Prevent more than one request from asking for credentials at once
  1680 + [delegateAuthenticationLock lock];
  1681 +
  1682 + // Now we've aquirred the lock, it may be that the session contains credentials we can re-use for this request
  1683 + if ([self useSessionPersistance] && [self applyCredentials:sessionCredentials]) {
  1684 + [delegateAuthenticationLock unlock];
  1685 + [self startRequest];
  1686 + return;
  1687 + }
  1688 +
1620 [self setRequestCredentials:nil]; 1689 [self setRequestCredentials:nil];
1621 1690
1622 [self setLastActivityTime:nil]; 1691 [self setLastActivityTime:nil];
1623 1692
1624 if ([self askDelegateForCredentials]) { 1693 if ([self askDelegateForCredentials]) {
1625 [self attemptToApplyCredentialsAndResume]; 1694 [self attemptToApplyCredentialsAndResume];
  1695 + [delegateAuthenticationLock unlock];
1626 return; 1696 return;
1627 } 1697 }
1628 if ([self showAuthenticationDialog]) { 1698 if ([self showAuthenticationDialog]) {
1629 [self attemptToApplyCredentialsAndResume]; 1699 [self attemptToApplyCredentialsAndResume];
  1700 + [delegateAuthenticationLock unlock];
  1701 + return;
1630 } 1702 }
  1703 + [delegateAuthenticationLock unlock];
1631 } 1704 }
1632 [self cancelLoad]; 1705 [self cancelLoad];
1633 [self failWithError:ASIAuthenticationError]; 1706 [self failWithError:ASIAuthenticationError];
@@ -1652,27 +1725,46 @@ static NSLock *sessionCookiesLock = nil; @@ -1652,27 +1725,46 @@ static NSLock *sessionCookiesLock = nil;
1652 // Are a user name & password needed? 1725 // Are a user name & password needed?
1653 } else if (CFHTTPAuthenticationRequiresUserNameAndPassword(requestAuthentication)) { 1726 } else if (CFHTTPAuthenticationRequiresUserNameAndPassword(requestAuthentication)) {
1654 1727
  1728 + // Prevent more than one request from asking for credentials at once
  1729 + [delegateAuthenticationLock lock];
  1730 +
  1731 + // Now we've aquirred the lock, it may be that the session contains credentials we can re-use for this request
  1732 + if ([self useSessionPersistance] && [self applyCredentials:sessionCredentials]) {
  1733 + [delegateAuthenticationLock unlock];
  1734 + [self startRequest];
  1735 + return;
  1736 + }
  1737 +
  1738 +
1655 NSMutableDictionary *newCredentials = [self findCredentials]; 1739 NSMutableDictionary *newCredentials = [self findCredentials];
1656 1740
1657 //If we have some credentials to use let's apply them to the request and continue 1741 //If we have some credentials to use let's apply them to the request and continue
1658 if (newCredentials) { 1742 if (newCredentials) {
1659 1743
1660 if ([self applyCredentials:newCredentials]) { 1744 if ([self applyCredentials:newCredentials]) {
  1745 + [delegateAuthenticationLock unlock];
1661 [self startRequest]; 1746 [self startRequest];
1662 } else { 1747 } else {
  1748 + [delegateAuthenticationLock unlock];
1663 [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileApplyingCredentialsType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Failed to apply credentials to request",NSLocalizedDescriptionKey,nil]]]; 1749 [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileApplyingCredentialsType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Failed to apply credentials to request",NSLocalizedDescriptionKey,nil]]];
1664 } 1750 }
1665 return; 1751 return;
1666 } 1752 }
1667 -  
1668 if ([self askDelegateForCredentials]) { 1753 if ([self askDelegateForCredentials]) {
1669 [self attemptToApplyCredentialsAndResume]; 1754 [self attemptToApplyCredentialsAndResume];
  1755 + [delegateAuthenticationLock unlock];
1670 return; 1756 return;
1671 } 1757 }
1672 1758
1673 if ([self showAuthenticationDialog]) { 1759 if ([self showAuthenticationDialog]) {
1674 [self attemptToApplyCredentialsAndResume]; 1760 [self attemptToApplyCredentialsAndResume];
  1761 + [delegateAuthenticationLock unlock];
  1762 + return;
1675 } 1763 }
  1764 + [delegateAuthenticationLock unlock];
  1765 +
  1766 + [self failWithError:ASIAuthenticationError];
  1767 +
1676 return; 1768 return;
1677 } 1769 }
1678 1770
@@ -32,6 +32,8 @@ IMPORTANT @@ -32,6 +32,8 @@ IMPORTANT
32 32
33 ASINetworkQueue *releaseTestQueue; 33 ASINetworkQueue *releaseTestQueue;
34 ASINetworkQueue *cancelQueue; 34 ASINetworkQueue *cancelQueue;
  35 +
  36 + int authenticationPromptCount;
35 } 37 }
36 38
37 - (void)testFailure; 39 - (void)testFailure;
@@ -55,6 +57,8 @@ IMPORTANT @@ -55,6 +57,8 @@ IMPORTANT
55 - (void)testCancelStressTest; 57 - (void)testCancelStressTest;
56 */ 58 */
57 59
  60 +- (void)testDelegateAuthenticationCredentialsReuse;
  61 +
58 @property (retain) NSOperationQueue *immediateCancelQueue; 62 @property (retain) NSOperationQueue *immediateCancelQueue;
59 @property (retain) NSMutableArray *failedRequests; 63 @property (retain) NSMutableArray *failedRequests;
60 @property (retain) NSMutableArray *finishedRequests; 64 @property (retain) NSMutableArray *finishedRequests;
@@ -27,6 +27,32 @@ IMPORTANT @@ -27,6 +27,32 @@ IMPORTANT
27 27
28 @implementation ASINetworkQueueTests 28 @implementation ASINetworkQueueTests
29 29
  30 +- (void)testDelegateAuthenticationCredentialsReuse
  31 +{
  32 + complete = NO;
  33 + authenticationPromptCount = 0;
  34 +
  35 + ASINetworkQueue *networkQueue = [ASINetworkQueue queue];
  36 + [networkQueue setDelegate:self];
  37 + [networkQueue setQueueDidFinishSelector:@selector(queueFinished:)];
  38 +
  39 + NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"reuse" forKey:@"test"];
  40 +
  41 + int i;
  42 + for (i=0; i<5; i++) {
  43 + ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/basic-authentication"]];
  44 + [request setUserInfo:userInfo];
  45 + [networkQueue addOperation:request];
  46 + }
  47 + [networkQueue go];
  48 +
  49 + while (!complete) {
  50 + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
  51 + }
  52 +}
  53 +
  54 +
  55 +
30 - (void)testProgress 56 - (void)testProgress
31 { 57 {
32 complete = NO; 58 complete = NO;
@@ -281,11 +307,15 @@ IMPORTANT @@ -281,11 +307,15 @@ IMPORTANT
281 307
282 308
283 309
  310 +
284 - (void)testProgressWithAuthentication 311 - (void)testProgressWithAuthentication
285 { 312 {
286 complete = NO; 313 complete = NO;
287 progress = 0; 314 progress = 0;
288 315
  316 + // Make sure we don't re-use credentials from previous tests
  317 + [ASIHTTPRequest clearSession];
  318 +
289 ASINetworkQueue *networkQueue = [ASINetworkQueue queue]; 319 ASINetworkQueue *networkQueue = [ASINetworkQueue queue];
290 [networkQueue setDownloadProgressDelegate:self]; 320 [networkQueue setDownloadProgressDelegate:self];
291 [networkQueue setDelegate:self]; 321 [networkQueue setDelegate:self];
@@ -316,6 +346,7 @@ IMPORTANT @@ -316,6 +346,7 @@ IMPORTANT
316 [networkQueue setDelegate:self]; 346 [networkQueue setDelegate:self];
317 [networkQueue setShowAccurateProgress:YES]; 347 [networkQueue setShowAccurateProgress:YES];
318 [networkQueue setQueueDidFinishSelector:@selector(queueFinished:)]; 348 [networkQueue setQueueDidFinishSelector:@selector(queueFinished:)];
  349 + [networkQueue setRequestDidFailSelector:@selector(requestFailed:)];
319 350
320 request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; 351 request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
321 [request setUserInfo:[NSDictionary dictionaryWithObject:@"Don't bother" forKey:@"Shall I return any credentials?"]]; 352 [request setUserInfo:[NSDictionary dictionaryWithObject:@"Don't bother" forKey:@"Shall I return any credentials?"]];
@@ -357,14 +388,24 @@ IMPORTANT @@ -357,14 +388,24 @@ IMPORTANT
357 388
358 - (void)authenticationNeededForRequest:(ASIHTTPRequest *)request 389 - (void)authenticationNeededForRequest:(ASIHTTPRequest *)request
359 { 390 {
360 - // We're using this method in multiple tests: 391 + // We're using this method in multiple tests, so the code here is to act appropriatly for each one
  392 + if ([[[request userInfo] objectForKey:@"test"] isEqualToString:@"reuse"]) {
  393 + authenticationPromptCount++;
  394 + BOOL success = (authenticationPromptCount == 1);
  395 + GHAssertTrue(success,@"Delegate was asked for credentials more than once");
  396 +
  397 + [request setUsername:@"secret_username"];
  398 + [request setPassword:@"secret_password"];
  399 + [request retryUsingSuppliedCredentials];
  400 +
  401 +
361 // testProgressWithAuthentication will set a userInfo dictionary on the main request, to tell us not to supply credentials 402 // testProgressWithAuthentication will set a userInfo dictionary on the main request, to tell us not to supply credentials
362 - if (![request mainRequest] || ![[request mainRequest] userInfo]) { 403 + } else if (![request mainRequest] || ![[request mainRequest] userInfo]) {
363 [request setUsername:@"secret_username"]; 404 [request setUsername:@"secret_username"];
364 [request setPassword:@"secret_password"]; 405 [request setPassword:@"secret_password"];
365 - [request retryWithAuthentication]; 406 + [request retryUsingSuppliedCredentials];
366 } else { 407 } else {
367 - [request cancel]; 408 + [request cancelAuthentication];
368 } 409 }
369 } 410 }
370 411
@@ -133,11 +133,11 @@ static NSString *proxyPassword = @""; @@ -133,11 +133,11 @@ static NSString *proxyPassword = @"";
133 GHAssertTrue(0,@"Request failed when it shouldn't have done so"); 133 GHAssertTrue(0,@"Request failed when it shouldn't have done so");
134 } 134 }
135 135
136 -- (void)proxyAuthorizationNeededForRequest:(ASIHTTPRequest *)request 136 +- (void)proxyAuthenticationNeededForRequest:(ASIHTTPRequest *)request
137 { 137 {
138 [request setProxyUsername:proxyUsername]; 138 [request setProxyUsername:proxyUsername];
139 [request setProxyPassword:proxyPassword]; 139 [request setProxyPassword:proxyPassword];
140 - [request retryWithAuthentication]; 140 + [request retryUsingSuppliedCredentials];
141 } 141 }
142 142
143 143
@@ -168,11 +168,11 @@ static NSString *proxyPassword = @""; @@ -168,11 +168,11 @@ static NSString *proxyPassword = @"";
168 [self setComplete:YES]; 168 [self setComplete:YES];
169 } 169 }
170 170
171 -- (void)authorizationNeededForRequest:(ASIHTTPRequest *)request 171 +- (void)authenticationNeededForRequest:(ASIHTTPRequest *)request
172 { 172 {
173 [request setUsername:@"secret_username"]; 173 [request setUsername:@"secret_username"];
174 [request setPassword:@"secret_password"]; 174 [request setPassword:@"secret_password"];
175 - [request retryWithAuthentication]; 175 + [request retryUsingSuppliedCredentials];
176 } 176 }
177 177
178 178
@@ -46,7 +46,7 @@ @@ -46,7 +46,7 @@
46 46
47 - (IBAction)fetchThreeImages:(id)sender; 47 - (IBAction)fetchThreeImages:(id)sender;
48 48
49 -- (void)authorizationNeededForRequest:(ASIHTTPRequest *)request; 49 +- (void)authenticationNeededForRequest:(ASIHTTPRequest *)request;
50 - (IBAction)dismissAuthSheet:(id)sender; 50 - (IBAction)dismissAuthSheet:(id)sender;
51 - (IBAction)fetchTopSecretInformation:(id)sender; 51 - (IBAction)fetchTopSecretInformation:(id)sender;
52 52
@@ -200,7 +200,7 @@ @@ -200,7 +200,7 @@
200 } 200 }
201 } 201 }
202 202
203 -- (void)authorizationNeededForRequest:(ASIHTTPRequest *)request 203 +- (void)authenticationNeededForRequest:(ASIHTTPRequest *)request
204 { 204 {
205 [realm setStringValue:[request authenticationRealm]]; 205 [realm setStringValue:[request authenticationRealm]];
206 [host setStringValue:[[request url] host]]; 206 [host setStringValue:[[request url] host]];
@@ -212,7 +212,7 @@ @@ -212,7 +212,7 @@
212 contextInfo: request]; 212 contextInfo: request];
213 } 213 }
214 214
215 -- (void)proxyAuthorizationNeededForRequest:(ASIHTTPRequest *)request 215 +- (void)proxyAuthenticationNeededForRequest:(ASIHTTPRequest *)request
216 { 216 {
217 [realm setStringValue:[request proxyAuthenticationRealm]]; 217 [realm setStringValue:[request proxyAuthenticationRealm]];
218 [host setStringValue:[request proxyHost]]; 218 [host setStringValue:[request proxyHost]];
@@ -239,9 +239,9 @@ @@ -239,9 +239,9 @@
239 [request setUsername:[[[username stringValue] copy] autorelease]]; 239 [request setUsername:[[[username stringValue] copy] autorelease]];
240 [request setPassword:[[[password stringValue] copy] autorelease]]; 240 [request setPassword:[[[password stringValue] copy] autorelease]];
241 } 241 }
242 - [request retryWithAuthentication]; 242 + [request retryUsingSuppliedCredentials];
243 } else { 243 } else {
244 - [request cancelLoad]; 244 + [request cancelAuthentication];
245 } 245 }
246 [loginWindow orderOut: self]; 246 [loginWindow orderOut: self];
247 } 247 }