Ben Copsey

Stop stopping the runloop in markAsFinished, otherwise the timer doesn't get inv…

…alidated and it leaks the whole request
Stop reading request headers in handleBytesAvailable - they are now read only in handleStreamComplete.
This change prevents a neverending loop of ASIAuthenticationDialogs caused by the new lockless delegate authentication system.
(It also means the request body will always get downloaded, which may be useful sometimes when failing authentication)
... ... @@ -21,7 +21,7 @@
#import "ASIInputStream.h"
// Automatically set on build
NSString *ASIHTTPRequestVersion = @"v1.2-66 2010-01-05";
NSString *ASIHTTPRequestVersion = @"v1.2-67 2010-01-05";
NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain";
... ... @@ -1036,7 +1036,7 @@ static BOOL isiPhoneOS2;
{
// We must invalidate the old timer here, not before we've created and scheduled a new timer
// This is because the timer may be the only thing retaining an asynchronous request
if (timer != [self statusTimer]) {
if ([self statusTimer] && timer != [self statusTimer]) {
[[self statusTimer] invalidate];
[[self statusTimer] release];
}
... ... @@ -2323,7 +2323,6 @@ static BOOL isiPhoneOS2;
#pragma mark stream status handlers
- (void)handleNetworkEvent:(CFStreamEventType)type
{
[[self cancelledLock] lock];
... ... @@ -2365,9 +2364,6 @@ static BOOL isiPhoneOS2;
if (!CFReadStreamHasBytesAvailable((CFReadStreamRef)[self readStream])) {
return;
}
if (![self responseHeaders]) {
[self readResponseHeaders];
}
long long bufferSize = 16384;
if (contentLength > 262144) {
... ... @@ -2439,7 +2435,6 @@ static BOOL isiPhoneOS2;
- (void)handleStreamComplete
{
//Try to read the headers (if this is a HEAD request handleBytesAvailable may not be called)
if (![self responseHeaders]) {
[self readResponseHeaders];
}
... ... @@ -2536,7 +2531,7 @@ static BOOL isiPhoneOS2;
[self willChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isFinished"];
[self setInProgress:NO];
CFRunLoopStop(CFRunLoopGetCurrent());
// We leave stopping the runloop to the timer, since it needs to clean itself up first or we'll leak
}
... ...
... ... @@ -182,11 +182,12 @@ IMPORTANT
BOOL success = (progress == 1.0);
GHAssertTrue(success,@"Failed to increment progress properly");
[networkQueue cancelAllOperations];
// This test will request gzipped content, but the content-length header we get on the HEAD request will be wrong, ASIHTTPRequest should fall back to simple progress
// This is to workaround an issue Apache has with HEAD requests for dynamically generated content when accepting gzip - it returns the content-length of a gzipped empty body
complete = NO;
progress = 0;
[networkQueue cancelAllOperations];
[networkQueue setShowAccurateProgress:YES];
for (i=0; i<5; i++) {
... ...