Showing
3 changed files
with
50 additions
and
20 deletions
| @@ -366,6 +366,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -366,6 +366,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
| 366 | // When set to YES, 301 and 302 automatic redirects will use the original method and and body, according to the HTTP 1.1 standard | 366 | // When set to YES, 301 and 302 automatic redirects will use the original method and and body, according to the HTTP 1.1 standard |
| 367 | // Default is NO (to follow the behaviour of most browsers) | 367 | // Default is NO (to follow the behaviour of most browsers) |
| 368 | BOOL shouldUseRFC2616RedirectBehaviour; | 368 | BOOL shouldUseRFC2616RedirectBehaviour; |
| 369 | + | ||
| 370 | + // Used internally to record when a request has finished downloading data | ||
| 371 | + BOOL downloadComplete; | ||
| 369 | } | 372 | } |
| 370 | 373 | ||
| 371 | #pragma mark init / dealloc | 374 | #pragma mark init / dealloc |
| @@ -21,7 +21,7 @@ | @@ -21,7 +21,7 @@ | ||
| 21 | #import "ASIInputStream.h" | 21 | #import "ASIInputStream.h" |
| 22 | 22 | ||
| 23 | // Automatically set on build | 23 | // Automatically set on build |
| 24 | -NSString *ASIHTTPRequestVersion = @"v1.5-44 2010-02-04"; | 24 | +NSString *ASIHTTPRequestVersion = @"v1.5-45 2010-02-10"; |
| 25 | 25 | ||
| 26 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; | 26 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; |
| 27 | 27 | ||
| @@ -181,6 +181,7 @@ static BOOL isiPhoneOS2; | @@ -181,6 +181,7 @@ static BOOL isiPhoneOS2; | ||
| 181 | @property (assign) ASIAuthenticationState authenticationNeeded; | 181 | @property (assign) ASIAuthenticationState authenticationNeeded; |
| 182 | @property (assign, nonatomic) BOOL readStreamIsScheduled; | 182 | @property (assign, nonatomic) BOOL readStreamIsScheduled; |
| 183 | @property (retain, nonatomic) NSTimer *statusTimer; | 183 | @property (retain, nonatomic) NSTimer *statusTimer; |
| 184 | +@property (assign, nonatomic) BOOL downloadComplete; | ||
| 184 | @end | 185 | @end |
| 185 | 186 | ||
| 186 | 187 | ||
| @@ -768,6 +769,7 @@ static BOOL isiPhoneOS2; | @@ -768,6 +769,7 @@ static BOOL isiPhoneOS2; | ||
| 768 | 769 | ||
| 769 | [self requestStarted]; | 770 | [self requestStarted]; |
| 770 | 771 | ||
| 772 | + [self setDownloadComplete:NO]; | ||
| 771 | [self setComplete:NO]; | 773 | [self setComplete:NO]; |
| 772 | [self setTotalBytesRead:0]; | 774 | [self setTotalBytesRead:0]; |
| 773 | [self setLastBytesRead:0]; | 775 | [self setLastBytesRead:0]; |
| @@ -2403,7 +2405,15 @@ static BOOL isiPhoneOS2; | @@ -2403,7 +2405,15 @@ static BOOL isiPhoneOS2; | ||
| 2403 | 2405 | ||
| 2404 | [[self cancelledLock] unlock]; | 2406 | [[self cancelledLock] unlock]; |
| 2405 | 2407 | ||
| 2406 | - if (![self inProgress]) { | 2408 | + if ([self downloadComplete] && [self needsRedirect]) { |
| 2409 | + CFRunLoopStop(CFRunLoopGetCurrent()); | ||
| 2410 | + [self performRedirect]; | ||
| 2411 | + return; | ||
| 2412 | + } else if ([self downloadComplete] && [self authenticationNeeded]) { | ||
| 2413 | + CFRunLoopStop(CFRunLoopGetCurrent()); | ||
| 2414 | + [self attemptToApplyCredentialsAndResume]; | ||
| 2415 | + return; | ||
| 2416 | + } else if (![self inProgress]) { | ||
| 2407 | [self setStatusTimer:nil]; | 2417 | [self setStatusTimer:nil]; |
| 2408 | } | 2418 | } |
| 2409 | 2419 | ||
| @@ -2497,6 +2507,8 @@ static BOOL isiPhoneOS2; | @@ -2497,6 +2507,8 @@ static BOOL isiPhoneOS2; | ||
| 2497 | NSLog(@"Request %@ finished downloading data",self); | 2507 | NSLog(@"Request %@ finished downloading data",self); |
| 2498 | #endif | 2508 | #endif |
| 2499 | 2509 | ||
| 2510 | + [self setDownloadComplete:YES]; | ||
| 2511 | + | ||
| 2500 | if (![self responseHeaders]) { | 2512 | if (![self responseHeaders]) { |
| 2501 | [self readResponseHeaders]; | 2513 | [self readResponseHeaders]; |
| 2502 | } | 2514 | } |
| @@ -2528,7 +2540,6 @@ static BOOL isiPhoneOS2; | @@ -2528,7 +2540,6 @@ static BOOL isiPhoneOS2; | ||
| 2528 | if (decompressionStatus != Z_OK) { | 2540 | if (decompressionStatus != Z_OK) { |
| 2529 | fileError = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASIFileManagementError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of %@ failed with code %hi",[self temporaryFileDownloadPath],decompressionStatus],NSLocalizedDescriptionKey,nil]]; | 2541 | fileError = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASIFileManagementError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of %@ failed with code %hi",[self temporaryFileDownloadPath],decompressionStatus],NSLocalizedDescriptionKey,nil]]; |
| 2530 | } | 2542 | } |
| 2531 | - | ||
| 2532 | [self removeTemporaryDownloadFile]; | 2543 | [self removeTemporaryDownloadFile]; |
| 2533 | } else { | 2544 | } else { |
| 2534 | 2545 | ||
| @@ -2549,6 +2560,7 @@ static BOOL isiPhoneOS2; | @@ -2549,6 +2560,7 @@ static BOOL isiPhoneOS2; | ||
| 2549 | } | 2560 | } |
| 2550 | [self setTemporaryFileDownloadPath:nil]; | 2561 | [self setTemporaryFileDownloadPath:nil]; |
| 2551 | } | 2562 | } |
| 2563 | + | ||
| 2552 | } | 2564 | } |
| 2553 | } | 2565 | } |
| 2554 | [progressLock unlock]; | 2566 | [progressLock unlock]; |
| @@ -2565,27 +2577,20 @@ static BOOL isiPhoneOS2; | @@ -2565,27 +2577,20 @@ static BOOL isiPhoneOS2; | ||
| 2565 | [[self connectionInfo] setObject:[NSDate dateWithTimeIntervalSinceNow:closeStreamTime] forKey:@"expires"]; | 2577 | [[self connectionInfo] setObject:[NSDate dateWithTimeIntervalSinceNow:closeStreamTime] forKey:@"expires"]; |
| 2566 | [connectionsLock unlock]; | 2578 | [connectionsLock unlock]; |
| 2567 | 2579 | ||
| 2568 | - if ([self needsRedirect]) { | ||
| 2569 | - CFRunLoopStop(CFRunLoopGetCurrent()); | ||
| 2570 | - [self performRedirect]; | ||
| 2571 | - return; | ||
| 2572 | - } else if ([self authenticationNeeded]) { | ||
| 2573 | - CFRunLoopStop(CFRunLoopGetCurrent()); | ||
| 2574 | - [self attemptToApplyCredentialsAndResume]; | ||
| 2575 | - return; | ||
| 2576 | - } | ||
| 2577 | - | ||
| 2578 | - if (fileError) { | ||
| 2579 | - [self failWithError:fileError]; | ||
| 2580 | - } else { | ||
| 2581 | - [self requestFinished]; | ||
| 2582 | - } | ||
| 2583 | - | ||
| 2584 | if (![self authenticationNeeded]) { | 2580 | if (![self authenticationNeeded]) { |
| 2585 | [self destroyReadStream]; | 2581 | [self destroyReadStream]; |
| 2586 | } | 2582 | } |
| 2587 | 2583 | ||
| 2588 | - [self markAsFinished]; | 2584 | + if (![self needsRedirect] && ![self authenticationNeeded]) { |
| 2585 | + | ||
| 2586 | + if (fileError) { | ||
| 2587 | + [self failWithError:fileError]; | ||
| 2588 | + } else { | ||
| 2589 | + [self requestFinished]; | ||
| 2590 | + } | ||
| 2591 | + | ||
| 2592 | + [self markAsFinished]; | ||
| 2593 | + } | ||
| 2589 | } | 2594 | } |
| 2590 | 2595 | ||
| 2591 | - (void)markAsFinished | 2596 | - (void)markAsFinished |
| @@ -3720,4 +3725,5 @@ static BOOL isiPhoneOS2; | @@ -3720,4 +3725,5 @@ static BOOL isiPhoneOS2; | ||
| 3720 | @synthesize readStreamIsScheduled; | 3725 | @synthesize readStreamIsScheduled; |
| 3721 | @synthesize statusTimer; | 3726 | @synthesize statusTimer; |
| 3722 | @synthesize shouldUseRFC2616RedirectBehaviour; | 3727 | @synthesize shouldUseRFC2616RedirectBehaviour; |
| 3728 | +@synthesize downloadComplete; | ||
| 3723 | @end | 3729 | @end |
| @@ -78,8 +78,29 @@ | @@ -78,8 +78,29 @@ | ||
| 78 | [request startAsynchronous]; | 78 | [request startAsynchronous]; |
| 79 | [request cancel]; | 79 | [request cancel]; |
| 80 | GHAssertNotNil([request error],@"Failed to cancel the request"); | 80 | GHAssertNotNil([request error],@"Failed to cancel the request"); |
| 81 | + | ||
| 82 | + // Test cancelling a redirected request works | ||
| 83 | + // This test is probably unreliable on very slow or very fast connections, as it depends on being able to complete the first request (but not the second) in under 2 seconds | ||
| 84 | + request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/cancel_redirect"]]; | ||
| 85 | + [request startAsynchronous]; | ||
| 86 | + | ||
| 87 | + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]]; | ||
| 88 | + [request cancel]; | ||
| 89 | + | ||
| 90 | + BOOL success = ([[[request url] absoluteString] isEqualToString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel.txt"]); | ||
| 91 | + | ||
| 92 | + GHAssertTrue(success, @"Request did not redirect quickly enough, cannot proceed with test"); | ||
| 93 | + | ||
| 94 | + GHAssertNotNil([request error],@"Failed to cancel the request"); | ||
| 95 | + | ||
| 96 | + success = [request totalBytesRead] < 7900198; | ||
| 97 | + GHAssertTrue(success, @"Downloaded the whole of the response even though we should have cancelled by now"); | ||
| 98 | + | ||
| 99 | + | ||
| 81 | } | 100 | } |
| 82 | 101 | ||
| 102 | + | ||
| 103 | + | ||
| 83 | - (void)testDelegateMethods | 104 | - (void)testDelegateMethods |
| 84 | { | 105 | { |
| 85 | // We run this test on the main thread because otherwise we can't depend on the delegate being notified before we need to test it's working | 106 | // We run this test on the main thread because otherwise we can't depend on the delegate being notified before we need to test it's working |
-
Please register or login to post a comment