Ben Copsey

Fix delegate didFinish selector being called twice when using ASIReloadIfDifferentCachePolicy

(Reported by Philippe Jayet)
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 23
24 24
25 // Automatically set on build 25 // Automatically set on build
26 -NSString *ASIHTTPRequestVersion = @"v1.7-51 2010-08-18"; 26 +NSString *ASIHTTPRequestVersion = @"v1.7-52 2010-08-30";
27 27
28 NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; 28 NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain";
29 29
@@ -652,6 +652,7 @@ static NSOperationQueue *sharedQueue = nil; @@ -652,6 +652,7 @@ static NSOperationQueue *sharedQueue = nil;
652 } 652 }
653 653
654 [self setComplete:NO]; 654 [self setComplete:NO];
  655 + [self setDidUseCachedResponse:NO];
655 656
656 if (![self url]) { 657 if (![self url]) {
657 [self failWithError:ASIUnableToCreateRequestError]; 658 [self failWithError:ASIUnableToCreateRequestError];
@@ -2829,7 +2830,7 @@ static NSOperationQueue *sharedQueue = nil; @@ -2829,7 +2830,7 @@ static NSOperationQueue *sharedQueue = nil;
2829 } 2830 }
2830 2831
2831 // Save to the cache 2832 // Save to the cache
2832 - if ([self downloadCache]) { 2833 + if ([self downloadCache] && ![self didUseCachedResponse]) {
2833 [[self downloadCache] storeResponseForRequest:self maxAge:[self secondsToCache]]; 2834 [[self downloadCache] storeResponseForRequest:self maxAge:[self secondsToCache]];
2834 } 2835 }
2835 2836
@@ -2851,7 +2852,7 @@ static NSOperationQueue *sharedQueue = nil; @@ -2851,7 +2852,7 @@ static NSOperationQueue *sharedQueue = nil;
2851 [self destroyReadStream]; 2852 [self destroyReadStream];
2852 } 2853 }
2853 2854
2854 - if (![self needsRedirect] && ![self authenticationNeeded]) { 2855 + if (![self needsRedirect] && ![self authenticationNeeded] && ![self didUseCachedResponse]) {
2855 2856
2856 if (fileError) { 2857 if (fileError) {
2857 [self failWithError:fileError]; 2858 [self failWithError:fileError];
@@ -2923,10 +2924,10 @@ static NSOperationQueue *sharedQueue = nil; @@ -2923,10 +2924,10 @@ static NSOperationQueue *sharedQueue = nil;
2923 return NO; 2924 return NO;
2924 } 2925 }
2925 } 2926 }
2926 - 2927 +
2927 // only 200 responses are stored in the cache, so let the client know 2928 // only 200 responses are stored in the cache, so let the client know
2928 // this was a successful response 2929 // this was a successful response
2929 - self.responseStatusCode = 200; 2930 + [self setResponseStatusCode:200];
2930 2931
2931 [self setDidUseCachedResponse:YES]; 2932 [self setDidUseCachedResponse:YES];
2932 2933
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 10
11 11
12 @interface ASIDownloadCacheTests : ASITestCase { 12 @interface ASIDownloadCacheTests : ASITestCase {
13 - 13 + NSUInteger requestsFinishedCount;
14 } 14 }
15 15
16 @end 16 @end
@@ -291,4 +291,37 @@ @@ -291,4 +291,37 @@
291 [ASIHTTPRequest setDefaultCache:nil]; 291 [ASIHTTPRequest setDefaultCache:nil];
292 } 292 }
293 293
  294 +// Text fix for a bug where the didFinishSelector would be called twice for a cached response using ASIReloadIfDifferentCachePolicy
  295 +- (void)testCacheOnlyCallsRequestFinishedOnce
  296 +{
  297 + // Run this request on the main thread to force delegate calls to happen synchronously
  298 + [self performSelectorOnMainThread:@selector(runCacheOnlyCallsRequestFinishedOnceTest) withObject:nil waitUntilDone:YES];
  299 +}
  300 +
  301 +- (void)runCacheOnlyCallsRequestFinishedOnceTest
  302 +{
  303 + [[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:ASICacheForSessionDurationCacheStoragePolicy];
  304 + ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/i/logo.png"]];
  305 + [request setCachePolicy:ASIReloadIfDifferentCachePolicy];
  306 + [request setDownloadCache:[ASIDownloadCache sharedCache]];
  307 + [request setDelegate:self];
  308 + [request startSynchronous];
  309 +
  310 + requestsFinishedCount = 0;
  311 + request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/i/logo.png"]];
  312 + [request setCachePolicy:ASIReloadIfDifferentCachePolicy];
  313 + [request setDownloadCache:[ASIDownloadCache sharedCache]];
  314 + [request setDidFinishSelector:@selector(finishCached:)];
  315 + [request setDelegate:self];
  316 + [request startSynchronous];
  317 +
  318 + BOOL success = (requestsFinishedCount == 1);
  319 + GHAssertTrue(success,@"didFinishSelector called more than once");
  320 +}
  321 +
  322 +- (void)finishCached:(ASIHTTPRequest *)request
  323 +{
  324 + requestsFinishedCount++;
  325 +}
  326 +
294 @end 327 @end
@@ -1201,6 +1201,7 @@ IMPORTANT @@ -1201,6 +1201,7 @@ IMPORTANT
1201 complete = YES; 1201 complete = YES;
1202 } 1202 }
1203 1203
  1204 +
1204 @synthesize immediateCancelQueue; 1205 @synthesize immediateCancelQueue;
1205 @synthesize failedRequests; 1206 @synthesize failedRequests;
1206 @synthesize finishedRequests; 1207 @synthesize finishedRequests;