Ben Copsey

Notify request delegate, and don't bother attempting main request, when head req…

…uest created by ASINetworkQueue fails
Thanks to Hermes Pique for his bug report!
... ... @@ -21,7 +21,7 @@
#import "ASIInputStream.h"
// Automatically set on build
NSString *ASIHTTPRequestVersion = @"v1.2-20 2009-12-17";
NSString *ASIHTTPRequestVersion = @"v1.2-22 2009-12-18";
// We use our own custom run loop mode as CoreAnimation seems to want to hijack our threads otherwise
static CFStringRef ASIHTTPRequestRunMode = CFSTR("ASIHTTPRequest");
... ... @@ -465,6 +465,13 @@ static BOOL isiPhoneOS2;
@try {
// A HEAD request generated by an ASINetworkQueue may have set the error already. If so, we should not proceed.
if ([self error]) {
[self failWithError:nil];
[pool release];
return;
}
[self setComplete:NO];
if (![self url]) {
... ... @@ -1309,28 +1316,23 @@ static BOOL isiPhoneOS2;
return;
}
ASIHTTPRequest *failedRequest = self;
// If this is a HEAD request created by an ASINetworkQueue or compatible queue delegate, make the main request fail
if ([self mainRequest]) {
ASIHTTPRequest *mRequest = [self mainRequest];
[mRequest setError:theError];
// Let the queue know something went wrong
if ([[self queue] respondsToSelector:@selector(requestDidFail:)]) {
[[self queue] performSelectorOnMainThread:@selector(requestDidFail:) withObject:mRequest waitUntilDone:[NSThread isMainThread]];
}
failedRequest = [self mainRequest];
}
} else {
[self setError:theError];
// Let the queue know something went wrong
if ([[self queue] respondsToSelector:@selector(requestDidFail:)]) {
[[self queue] performSelectorOnMainThread:@selector(requestDidFail:) withObject:self waitUntilDone:[NSThread isMainThread]];
}
[failedRequest setError:theError];
// Let the queue know something went wrong
if ([[failedRequest queue] respondsToSelector:@selector(requestDidFail:)]) {
[[failedRequest queue] performSelectorOnMainThread:@selector(requestDidFail:) withObject:failedRequest waitUntilDone:[NSThread isMainThread]];
}
// Let the delegate know something went wrong
if ([self didFailSelector] && [[self delegate] respondsToSelector:[self didFailSelector]]) {
[[self delegate] performSelectorOnMainThread:[self didFailSelector] withObject:self waitUntilDone:[NSThread isMainThread]];
}
// Let the delegate know something went wrong
if ([failedRequest didFailSelector] && [[failedRequest delegate] respondsToSelector:[failedRequest didFailSelector]]) {
[[failedRequest delegate] performSelectorOnMainThread:[failedRequest didFailSelector] withObject:failedRequest waitUntilDone:[NSThread isMainThread]];
}
}
... ...
... ... @@ -45,6 +45,7 @@ IMPORTANT
BOOL started;
BOOL finished;
BOOL failed;
BOOL headFailed;
}
- (void)testFailure;
... ... @@ -70,7 +71,7 @@ IMPORTANT
- (void)testDelegateAuthenticationCredentialsReuse;
- (void)testPOSTWithAuthentication;
- (void)testHEADFailure;
@property (retain) NSOperationQueue *immediateCancelQueue;
@property (retain) NSMutableArray *failedRequests;
@property (retain) NSMutableArray *finishedRequests;
... ...
... ... @@ -1089,6 +1089,33 @@ IMPORTANT
GHAssertTrue(success,@"Failed to send credentials correctly? (Expected: '%@', got '%@')",expectedResponse,[[request responseString] lowercaseString]);
}
// Test for a bug where failing head requests would not notify the original request's delegate of the failure
- (void)testHEADFailure
{
headFailed = NO;
ASINetworkQueue *queue = [ASINetworkQueue queue];
[queue setShowAccurateProgress:YES];
[queue setDelegate:self];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://999.123"]];
[request setDelegate:self];
[request setDidFailSelector:@selector(HEADFail:)];
[queue addOperation:request];
[queue go];
[queue waitUntilAllOperationsAreFinished];
// Hope the request gets around to notifying the delegate in time
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
GHAssertTrue(headFailed,@"Failed to notify the request's delegate");
}
- (void)HEADFail:(ASIHTTPRequest *)request
{
headFailed = YES;
}
@synthesize immediateCancelQueue;
@synthesize failedRequests;
@synthesize finishedRequests;
... ...