Fix a race condition in PINURLSessionManager

The callback queue cannot be concurrent because there's no way to guarantee the
operations happen FIFO.

Also fixed an issue where authentication wouldn't happen if the PINURLSessionManager
delegate didn't respond to didReceiveChallenge:
This commit is contained in:
Garrett Moon
2015-10-23 11:36:58 -07:00
parent 999b5305ec
commit 65d9c582fb

View File

@@ -26,7 +26,9 @@
self.sessionManagerLock = [[NSLock alloc] init];
self.sessionManagerLock.name = @"PINURLSessionManager";
self.operationQueue = [[NSOperationQueue alloc] init];
[self.operationQueue setMaxConcurrentOperationCount:NSOperationQueueDefaultMaxConcurrentOperationCount];
//queue must be serial to ensure proper ordering
[self.operationQueue setMaxConcurrentOperationCount:1];
self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:self.operationQueue];
self.completions = [[NSMutableDictionary alloc] init];
self.delegateQueues = [[NSMutableDictionary alloc] init];
@@ -69,14 +71,16 @@
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
[self lock];
dispatch_queue_t delegateQueue = self.delegateQueues[@(task.taskIdentifier)];
dispatch_queue_t delegateQueue = self.delegateQueues[@(task.taskIdentifier)];
[self unlock];
__weak typeof(self) weakSelf = self;
dispatch_async(delegateQueue, ^{
if ([weakSelf.delegate respondsToSelector:@selector(didReceiveAuthenticationChallenge:forTask:completionHandler:)]) {
[weakSelf.delegate didReceiveAuthenticationChallenge:challenge forTask:task completionHandler:completionHandler];
}
} else {
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}
});
}