Ben Copsey

Make resume work when redirecting

... ... @@ -21,7 +21,7 @@
#import "ASIInputStream.h"
// Automatically set on build
NSString *ASIHTTPRequestVersion = @"v1.5-51 2010-03-02";
NSString *ASIHTTPRequestVersion = @"v1.5-52 2010-03-02";
NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain";
... ... @@ -2498,6 +2498,11 @@ static BOOL isiPhoneOS2;
// For bandwidth measurement / throttling
[ASIHTTPRequest incrementBandwidthUsedInLastSecond:bytesRead];
// If we need to redirect, and have automatic redirect on, and might be resuming a download, let's do nothing with the content
if ([self needsRedirect] && [self shouldRedirect] && [self allowResumeForFileDownloads]) {
return;
}
// Are we downloading to a file?
if ([self downloadDestinationPath]) {
if (![self fileDownloadOutputStream]) {
... ... @@ -2554,15 +2559,19 @@ static BOOL isiPhoneOS2;
[[self fileDownloadOutputStream] close];
[self setFileDownloadOutputStream:nil];
// If we are going to redirect and we are resuming, let's ignore this download
if ([self shouldRedirect] && [self needsRedirect] && [self allowResumeForFileDownloads]) {
// Decompress the file (if necessary) directly to the destination path
if ([self isResponseCompressed]) {
} else if ([self isResponseCompressed]) {
int decompressionStatus = [ASIHTTPRequest uncompressZippedDataFromFile:[self temporaryFileDownloadPath] toFile:[self downloadDestinationPath]];
if (decompressionStatus != Z_OK) {
fileError = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASIFileManagementError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of %@ failed with code %hi",[self temporaryFileDownloadPath],decompressionStatus],NSLocalizedDescriptionKey,nil]];
}
[self removeTemporaryDownloadFile];
} else {
//Remove any file at the destination path
NSError *moveError = nil;
if ([[NSFileManager defaultManager] fileExistsAtPath:[self downloadDestinationPath]]) {
... ...
... ... @@ -449,6 +449,60 @@
}
}
- (void)testRedirectedResume
{
[self performSelectorOnMainThread:@selector(runRedirectedResume) withObject:nil waitUntilDone:YES];
}
- (void)runRedirectedResume
{
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect_resume"];
NSString *temporaryPath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"foo.temp"];
[@"" writeToFile:temporaryPath atomically:NO encoding:NSUTF8StringEncoding error:NULL];
NSString *downloadPath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"foo.txt"];
// Download part of a large file that is returned after a redirect
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setTemporaryFileDownloadPath:temporaryPath];
[request setDownloadDestinationPath:downloadPath];
[request setAllowResumeForFileDownloads:YES];
[request setAllowCompressedResponse:NO];
[request startAsynchronous];
// Cancel the request as soon as it has downloaded 64KB
while (1) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
if ([request totalBytesRead] > 32*1024) {
[request cancel];
break;
}
}
NSNumber *fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:temporaryPath error:NULL] objectForKey:NSFileSize];
unsigned long long partialFileSize = [fileSize unsignedLongLongValue];
BOOL success = (partialFileSize < 1036935);
GHAssertTrue(success,@"Downloaded whole file too quickly, cannot proceed with this test");
// Resume the download synchronously
request = [ASIHTTPRequest requestWithURL:url];
[request setTemporaryFileDownloadPath:temporaryPath];
[request setDownloadDestinationPath:downloadPath];
[request setAllowResumeForFileDownloads:YES];
[request setAllowCompressedResponse:NO];
[request startSynchronous];
fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:downloadPath error:NULL] objectForKey:NSFileSize];
success = ([fileSize intValue] == 1036935);
GHAssertTrue(success,@"Downloaded file has wrong length");
success = [[[request requestHeaders] objectForKey:@"Range"] isEqualToString:[NSString stringWithFormat:@"bytes=%llu-",partialFileSize]];
GHAssertTrue(success,@"Restarted download when we should have resumed, or asked for the wrong segment of the file");
}
- (void)testUploadContentLength
{
//This url will return the contents of the Content-Length request header
... ...