Permalink
Browse files

Added timeout support

  • Loading branch information...
1 parent c020411 commit 076dc89e9b618e7fb0ed9a90a621da3a064dbee0 @pokeb pokeb committed Sep 13, 2008
Showing with 1,525 additions and 629 deletions.
  1. +5 −1 ASIHTTPRequest.h
  2. +23 −2 ASIHTTPRequest.m
  3. +1 −0 ASIHTTPRequestTests.h
  4. +14 −0 ASIHTTPRequestTests.m
  5. +1 −0 AppDelegate.h
  6. +77 −138 asi-http-request.xcodeproj/ben.mode1v3
  7. +1,404 −488 asi-http-request.xcodeproj/ben.pbxuser
View
@@ -122,7 +122,10 @@
//Called on the delegate when the request fails
SEL didFailSelector;
+ //Used for recording when something last happened during the request, we will compare this value with the current date to time out requests when appropriate
+ NSDate *lastActivityTime;
+ NSTimeInterval timeOutSeconds;
}
#pragma mark init / dealloc
@@ -254,5 +257,6 @@
@property (retain) NSDictionary *requestCredentials;
@property (assign) int responseStatusCode;
@property (retain) NSMutableData *receivedData;
-
+@property (retain) NSDate *lastActivityTime;
+@property (assign) NSTimeInterval timeOutSeconds;
@end
View
@@ -51,6 +51,7 @@ - (id)initWithURL:(NSURL *)newURL
//credentials = NULL;
request = NULL;
responseHeaders = nil;
+ [self setTimeOutSeconds:30];
[self setUseKeychainPersistance:NO];
[self setUseSessionPersistance:YES];
[self setUseCookiePersistance:YES];
@@ -83,6 +84,7 @@ - (void)dealloc
[authenticationRealm release];
[url release];
[authenticationLock release];
+ [lastActivityTime release];
[super dealloc];
}
@@ -304,11 +306,23 @@ - (void)loadRequest
[self performSelectorOnMainThread:@selector(resetUploadProgress:) withObject:[NSNumber numberWithDouble:postLength] waitUntilDone:YES];
}
+ //Record when the request started, so we can timeout if nothing happens
+ [self setLastActivityTime:[[NSDate new] autorelease]];
// Wait for the request to finish
NSDate* endDate = [NSDate distantFuture];
while (!complete) {
+ //See if we need to timeout
+ if (lastActivityTime && timeOutSeconds > 0) {
+ if ([[[NSDate new] autorelease] timeIntervalSinceDate:lastActivityTime] > timeOutSeconds) {
+ [self failWithProblem:@"Request timed out"];
+ [self cancelLoad];
+ complete = YES;
+ break;
+ }
+ }
+
// See if our NSOperationQueue told us to cancel
if ([self isCancelled]) {
[self failWithProblem:@"The request was cancelled"];
@@ -366,6 +380,8 @@ - (void)resetUploadProgress:(NSNumber *)max
- (void)updateUploadProgress
{
+ [self setLastActivityTime:[[NSDate new] autorelease]];
+
double byteCount = [[(NSNumber *)CFReadStreamCopyProperty (readStream, kCFStreamPropertyHTTPRequestBytesWrittenCount) autorelease] doubleValue];
if (uploadProgressDelegate) {
[uploadProgressDelegate incrementBy:byteCount-lastBytesSent];
@@ -385,6 +401,8 @@ - (void)resetDownloadProgress:(NSNumber *)max
- (void)updateDownloadProgress
{
+ [self setLastActivityTime:[[NSDate new] autorelease]];
+
//We won't update downlaod progress until we've examined the headers, since we might need to authenticate
if (downloadProgressDelegate && responseHeaders) {
[downloadProgressDelegate incrementBy:totalBytesRead-lastBytesRead];
@@ -586,6 +604,7 @@ - (void)attemptToApplyCredentialsAndResume
// check for bad credentials, so we can give the delegate a chance to replace them
if (err.domain == kCFStreamErrorDomainHTTP && (err.error == kCFStreamErrorHTTPAuthenticationBadUserName || err.error == kCFStreamErrorHTTPAuthenticationBadPassword)) {
ignoreError = YES;
+ [self setLastActivityTime:nil];
if ([delegate respondsToSelector:@selector(authorizationNeededForRequest:)]) {
[delegate performSelectorOnMainThread:@selector(authorizationNeededForRequest:) withObject:self waitUntilDone:YES];
[authenticationLock lockWhenCondition:2];
@@ -682,14 +701,14 @@ - (void)handleNetworkEvent:(CFStreamEventType)type
- (void)handleBytesAvailable
{
-
+
if (!responseHeaders) {
if ([self readResponseHeadersReturningAuthenticationFailure]) {
[self attemptToApplyCredentialsAndResume];
return;
}
}
-
+
UInt8 buffer[2048];
CFIndex bytesRead = CFReadStreamRead(readStream, buffer, sizeof(buffer));
@@ -863,4 +882,6 @@ + (void)clearSession
@synthesize requestCredentials;
@synthesize responseStatusCode;
@synthesize receivedData;
+@synthesize lastActivityTime;
+@synthesize timeOutSeconds;
@end
@@ -13,6 +13,7 @@
}
- (void)testBasicDownload;
+- (void)testTimeOut;
- (void)testOperationQueue;
- (void)testCookies;
@end
View
@@ -58,6 +58,20 @@ - (void)testBasicDownload
STAssertNotNil(error,@"Failed to generate an error for a bad host - this test may fail when your DNS server redirects you to another page when it can't find a domain name (eg OpenDNS)");
}
+- (void)testTimeOut
+{
+ //Grab data
+ NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
+ ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
+ [request setTimeOutSeconds:0.0001]; //It's pretty unlikely we will be able to grab the data this quickly, so the request should timeout
+ [request start];
+ NSError *error = [request error];
+ STAssertNotNil(error,@"Request didn't timeout");
+ BOOL success = [[[error userInfo] valueForKey:@"Description"] isEqualToString:@"Request timed out"];
+ STAssertTrue(success,@"Timeout didn't generate the correct error");
+
+}
+
- (void)testOperationQueue
{
NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
View
@@ -40,4 +40,5 @@
- (IBAction)fetchTopSecretInformation:(id)sender;
- (IBAction)postWithProgress:(id)sender;
+
@end
Oops, something went wrong.

0 comments on commit 076dc89

Please sign in to comment.