diff --git a/AFNetworking/AFURLConnectionOperation.h b/AFNetworking/AFURLConnectionOperation.h index 600981c..abd2495 100644 --- a/AFNetworking/AFURLConnectionOperation.h +++ b/AFNetworking/AFURLConnectionOperation.h @@ -185,4 +185,10 @@ extern NSString * const AFNetworkingOperationDidFinishNotification; */ - (void)setDownloadProgressBlock:(void (^)(NSInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead))block; +///------------------------------------------------- +/// @name Setting Authentication Challenge Callbacks +///------------------------------------------------- + +- (void)setAuthenticationChallengeBlock:(void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block; + @end diff --git a/AFNetworking/AFURLConnectionOperation.m b/AFNetworking/AFURLConnectionOperation.m index bc8a71e..114cec2 100644 --- a/AFNetworking/AFURLConnectionOperation.m +++ b/AFNetworking/AFURLConnectionOperation.m @@ -37,6 +37,7 @@ NSString * const AFNetworkingOperationDidStartNotification = @"com.alamofire.net NSString * const AFNetworkingOperationDidFinishNotification = @"com.alamofire.networking.operation.finish"; typedef void (^AFURLConnectionOperationProgressBlock)(NSInteger bytes, NSInteger totalBytes, NSInteger totalBytesExpected); +typedef void (^AFURLConnectionOperationAuthenticationChallengeBlock)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge); static inline NSString * AFKeyPathFromOperationState(AFOperationState state) { switch (state) { @@ -64,6 +65,7 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) { @property (readwrite, nonatomic, retain) NSMutableData *dataAccumulator; @property (readwrite, nonatomic, copy) AFURLConnectionOperationProgressBlock uploadProgress; @property (readwrite, nonatomic, copy) AFURLConnectionOperationProgressBlock downloadProgress; +@property (readwrite, nonatomic, copy) AFURLConnectionOperationAuthenticationChallengeBlock authenticationBlock; - (BOOL)shouldTransitionToState:(AFOperationState)state; - (void)operationDidStart; @@ -86,6 +88,7 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) { @synthesize outputStream = _outputStream; @synthesize uploadProgress = _uploadProgress; @synthesize downloadProgress = _downloadProgress; +@synthesize authenticationBlock = _authenticationBlock; + (void)networkRequestThreadEntryPoint:(id)__unused object { do { @@ -136,6 +139,7 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) { [_uploadProgress release]; [_downloadProgress release]; + [_authenticationBlock release]; [super dealloc]; } @@ -170,6 +174,10 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) { self.downloadProgress = block; } +- (void)setAuthenticationChallengeBlock:(void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block { + self.authenticationBlock = block; +} + - (void)setState:(AFOperationState)state { if (![self shouldTransitionToState:state]) { return; @@ -305,6 +313,37 @@ static inline NSString * AFKeyPathFromOperationState(AFOperationState state) { #pragma mark - NSURLConnectionDelegate +- (void)connection:(NSURLConnection *)connection +didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge +{ + if (self.authenticationBlock) { + self.authenticationBlock(connection, challenge); + } else { + if ([challenge previousFailureCount] == 0) { + NSURLCredential *credential = nil; + + NSString *username = [(NSString *)CFURLCopyUserName((CFURLRef)[self.request URL]) autorelease]; + NSString *password = [(NSString *)CFURLCopyPassword((CFURLRef)[self.request URL]) autorelease]; + + if (username && password) { + credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceNone]; + } else if (username) { + credential = [[[NSURLCredentialStorage sharedCredentialStorage] credentialsForProtectionSpace:[challenge protectionSpace]] objectForKey:username]; + } else { + credential = [[NSURLCredentialStorage sharedCredentialStorage] defaultCredentialForProtectionSpace:[challenge protectionSpace]]; + } + + if (credential) { + [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; + } else { + [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; + } + } else { + [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; + } + } +} + - (void)connection:(NSURLConnection *)__unused connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten