Showing
7 changed files
with
154 additions
and
17 deletions
@@ -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 | } |
-
Please register or login to post a comment