Ben Copsey

Retry automatically on 'connection lost'

... ... @@ -23,7 +23,7 @@
// Automatically set on build
NSString *ASIHTTPRequestVersion = @"v1.6-15 2010-03-18";
NSString *ASIHTTPRequestVersion = @"v1.6-16 2010-03-19";
NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain";
... ... @@ -1647,13 +1647,18 @@ static BOOL isiPhoneOS2;
if (!message) {
return;
}
if (CFHTTPMessageIsHeaderComplete(message)) {
#if DEBUG_REQUEST_STATUS
// Make sure we've received all the headers
if (!CFHTTPMessageIsHeaderComplete(message)) {
CFRelease(message);
return;
}
#if DEBUG_REQUEST_STATUS
if ([self totalBytesSent] == [self postLength]) {
NSLog(@"Request %@ received response headers",self);
}
#endif
#endif
CFDictionaryRef headerFields = CFHTTPMessageCopyAllHeaderFields(message);
[self setResponseHeaders:(NSDictionary *)headerFields];
... ... @@ -1686,7 +1691,7 @@ static BOOL isiPhoneOS2;
[sessionCredentials setObject:(NSString *)kCFHTTPAuthenticationSchemeBasic forKey:@"AuthenticationScheme"];
[[self class] storeAuthenticationCredentialsInSessionStore:sessionCredentials];
}
}
// See if we got a Content-length header
NSString *cLength = [responseHeaders valueForKey:@"Content-Length"];
... ... @@ -1754,6 +1759,7 @@ static BOOL isiPhoneOS2;
[ASIHTTPRequest addSessionCookie:cookie];
}
}
// Do we need to redirect?
// Note that ASIHTTPRequest does not currently support 305 Use Proxy
if ([self shouldRedirect] && [responseHeaders valueForKey:@"Location"]) {
... ... @@ -1793,9 +1799,6 @@ static BOOL isiPhoneOS2;
}
}
}
// Handle connection persistence
if ([self shouldAttemptPersistentConnection]) {
... ... @@ -1838,7 +1841,6 @@ static BOOL isiPhoneOS2;
}
}
}
}
... ... @@ -2687,17 +2689,15 @@ static BOOL isiPhoneOS2;
if (![self error]) { // We may already have handled this error
// First, check for a socket not connected error
// First, check for a 'socket not connected' or 'connection lost' error
// This may occur when we've attempted to reuse a connection that should have been closed
// If we get this, we need to retry the request
// We'll only do this once - if it happens again on retry, we'll give up
if ([[underlyingError domain] isEqualToString:NSPOSIXErrorDomain]) {
if ([underlyingError code] == ENOTCONN) {
if (([[underlyingError domain] isEqualToString:NSPOSIXErrorDomain] && [underlyingError code] == ENOTCONN) || ([[underlyingError domain] isEqualToString:(NSString *)kCFErrorDomainCFNetwork] && [underlyingError code] == kCFURLErrorNetworkConnectionLost)) {
if ([self retryUsingNewConnection]) {
return;
}
}
}
NSString *reason = @"A connection failure occurred";
... ... @@ -2706,7 +2706,7 @@ static BOOL isiPhoneOS2;
// Also, iPhone seems to handle errors differently from Mac OS X - a self-signed certificate returns a different error code on each platform, so we'll just provide a general error
if ([[underlyingError domain] isEqualToString:NSOSStatusErrorDomain]) {
if ([underlyingError code] <= -9800 && [underlyingError code] >= -9818) {
reason = [NSString stringWithFormat:@"%@: SSL problem (possibily a bad/expired/self-signed certificate)",reason];
reason = [NSString stringWithFormat:@"%@: SSL problem (possibly a bad/expired/self-signed certificate)",reason];
}
}
... ...
... ... @@ -1464,6 +1464,13 @@
BOOL success = ![request connectionCanBeReused];
GHAssertTrue(success,@"Should not be able to re-use a request sent with Connection:close");
// Ensure we close the connection when authentication is needed
request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://asi/ASIHTTPRequest/tests/close-connection-auth-needed"]];
[request startSynchronous];
success = ![request connectionCanBeReused];
GHAssertTrue(success,@"Should not be able to re-use a request sent with Connection:close");
}
- (void)testPersistentConnectionTimeout
... ...