Ben Copsey

Remove duplication with calling the delegate for authentication details

@@ -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,6 +1403,7 @@ static NSError *ASITooMuchRedirectionError; @@ -1393,6 +1403,7 @@ 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
@@ -1400,6 +1411,7 @@ static NSError *ASITooMuchRedirectionError; @@ -1400,6 +1411,7 @@ static NSError *ASITooMuchRedirectionError;
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 }
@@ -1420,27 +1432,35 @@ static NSError *ASITooMuchRedirectionError; @@ -1420,27 +1432,35 @@ 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. 1436 + [self attemptToApplyProxyCredentialsAndResume];
  1437 + return;
  1438 + }
  1439 +
  1440 + // The delegate isn't interested, we'll have to give up
  1441 + [self failWithError:ASIAuthenticationError];
  1442 + return;
  1443 + }
  1444 +
  1445 +}
  1446 +
  1447 +- (BOOL)askDelegateForCredentials
  1448 +{
  1449 + // If we have a delegate, we'll see if it can handle proxyAuthorizationNeededForRequest:.
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 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
1426 id authorizationDelegate = [self delegate]; 1451 id authorizationDelegate = [self delegate];
1427 if (!authorizationDelegate) { 1452 if (!authorizationDelegate) {
1428 authorizationDelegate = [self queue]; 1453 authorizationDelegate = [self queue];
1429 } 1454 }
1430 1455
1431 - if ([authorizationDelegate respondsToSelector:@selector(proxyAuthorizationNeededForRequest:)]) { 1456 + if ([authorizationDelegate respondsToSelector:@selector(authorizationNeededForRequest:)]) {
1432 - [authorizationDelegate performSelectorOnMainThread:@selector(proxyAuthorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; 1457 + [authorizationDelegate performSelectorOnMainThread:@selector(authorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]];
1433 [[self authenticationLock] lockWhenCondition:2]; 1458 [[self authenticationLock] lockWhenCondition:2];
1434 [[self authenticationLock] unlockWithCondition:1]; 1459 [[self authenticationLock] unlockWithCondition:1];
1435 - [self attemptToApplyProxyCredentialsAndResume];  
1436 - return;  
1437 - }  
1438 1460
1439 - // The delegate isn't interested, we'll have to give up 1461 + return YES;
1440 - [self failWithError:ASIAuthenticationError];  
1441 - return;  
1442 } 1462 }
1443 - 1463 + return NO;
1444 } 1464 }
1445 1465
1446 - (void)attemptToApplyCredentialsAndResume 1466 - (void)attemptToApplyCredentialsAndResume
@@ -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 }