Ben Copsey

Added lots of comments

Added missing setDownloadProgressDelegate to ASIHTTPRequest
@@ -10,20 +10,20 @@ @@ -10,20 +10,20 @@
10 10
11 @interface ASIFormDataRequest : ASIHTTPRequest { 11 @interface ASIFormDataRequest : ASIHTTPRequest {
12 12
13 - //Parameters that will be POSTed to the url 13 + // Parameters that will be POSTed to the url
14 NSMutableDictionary *postData; 14 NSMutableDictionary *postData;
15 15
16 - //Files that will be POSTed to the url 16 + // Files that will be POSTed to the url
17 NSMutableDictionary *fileData; 17 NSMutableDictionary *fileData;
18 18
19 } 19 }
20 20
21 #pragma mark setup request 21 #pragma mark setup request
22 22
23 -//Add a POST variable to the request 23 +// Add a POST variable to the request
24 - (void)setPostValue:(id)value forKey:(NSString *)key; 24 - (void)setPostValue:(id)value forKey:(NSString *)key;
25 25
26 -//Add the contents of a local file as a POST variable to the request 26 +// Add the contents of a local file as a POST variable to the request
27 - (void)setFile:(NSString *)filePath forKey:(NSString *)key; 27 - (void)setFile:(NSString *)filePath forKey:(NSString *)key;
28 28
29 @end 29 @end
@@ -61,11 +61,11 @@ @@ -61,11 +61,11 @@
61 61
62 NSMutableData *body = [[[NSMutableData alloc] init] autorelease]; 62 NSMutableData *body = [[[NSMutableData alloc] init] autorelease];
63 63
64 - //Set your own boundary string only if really obsessive. We don't bother to check if post data contains the boundary, since it's pretty unlikely that it does. 64 + // Set your own boundary string only if really obsessive. We don't bother to check if post data contains the boundary, since it's pretty unlikely that it does.
65 NSString *stringBoundary = @"0xKhTmLbOuNdArY"; 65 NSString *stringBoundary = @"0xKhTmLbOuNdArY";
66 66
67 if ([fileData count] > 0) { 67 if ([fileData count] > 0) {
68 - //We need to use multipart/form-data when using file upload 68 + // We need to use multipart/form-data when using file upload
69 [self addRequestHeader:@"Content-Type" value:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary]]; 69 [self addRequestHeader:@"Content-Type" value:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary]];
70 } 70 }
71 71
@@ -73,7 +73,7 @@ @@ -73,7 +73,7 @@
73 73
74 [body appendData:[[NSString stringWithFormat:@"--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; 74 [body appendData:[[NSString stringWithFormat:@"--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
75 75
76 - //Adds post data 76 + // Adds post data
77 NSData *endItemBoundary = [[NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]; 77 NSData *endItemBoundary = [[NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding];
78 NSEnumerator *e = [postData keyEnumerator]; 78 NSEnumerator *e = [postData keyEnumerator];
79 NSString *key; 79 NSString *key;
@@ -87,7 +87,7 @@ @@ -87,7 +87,7 @@
87 } 87 }
88 } 88 }
89 89
90 - //Adds files to upload 90 + // Adds files to upload
91 NSData *contentTypeHeader = [[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]; 91 NSData *contentTypeHeader = [[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding];
92 e = [fileData keyEnumerator]; 92 e = [fileData keyEnumerator];
93 i=0; 93 i=0;
@@ -97,14 +97,14 @@ @@ -97,14 +97,14 @@
97 [body appendData:contentTypeHeader]; 97 [body appendData:contentTypeHeader];
98 [body appendData:[NSData dataWithContentsOfMappedFile:filePath]]; 98 [body appendData:[NSData dataWithContentsOfMappedFile:filePath]];
99 i++; 99 i++;
100 - if (i != [fileData count]) { //Only add the boundary if this is not the last item in the post body 100 + // Only add the boundary if this is not the last item in the post body
  101 + if (i != [fileData count]) {
101 [body appendData:endItemBoundary]; 102 [body appendData:endItemBoundary];
102 } 103 }
103 } 104 }
104 105
105 [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; 106 [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
106 107
107 - //Since we've got post data, let's set the post body to an empty NSMutableData object  
108 [self setPostBody:body]; 108 [self setPostBody:body];
109 109
110 //Now we've created our post data, construct the request 110 //Now we've created our post data, construct the request
@@ -163,8 +163,13 @@ @@ -163,8 +163,13 @@
163 - (void)updateUploadProgress; 163 - (void)updateUploadProgress;
164 - (void)resetDownloadProgress:(NSNumber *)max; 164 - (void)resetDownloadProgress:(NSNumber *)max;
165 - (void)updateDownloadProgress; 165 - (void)updateDownloadProgress;
  166 +
  167 +// Called when authorisation is needed, as we only find out we don't have permission to something when the upload is complete
166 - (void)removeUploadProgressSoFar; 168 - (void)removeUploadProgressSoFar;
167 169
  170 +// Helper method for interacting with progress indicators to abstract the details of different APIS (NSProgressIndicator and UIProgressView)
  171 ++ (void)setProgress:(double)progress forProgressIndicator:(id)indicator;
  172 +
168 #pragma mark handling request complete / failure 173 #pragma mark handling request complete / failure
169 174
170 // Called when a request completes successfully - defaults to: @selector(requestFinished:) 175 // Called when a request completes successfully - defaults to: @selector(requestFinished:)
@@ -228,8 +233,6 @@ @@ -228,8 +233,6 @@
228 // Dump all session data (authentication and cookies) 233 // Dump all session data (authentication and cookies)
229 + (void)clearSession; 234 + (void)clearSession;
230 235
231 -//Helper method for interacting with progress indicators to abstract the details of different APIS for cocoa and cocoa touch  
232 -+ (void)setProgress:(double)progress forProgressIndicator:(id)indicator;  
233 236
234 @property (retain) NSString *username; 237 @property (retain) NSString *username;
235 @property (retain) NSString *password; 238 @property (retain) NSString *password;
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 #import "ASIHTTPRequest.h" 13 #import "ASIHTTPRequest.h"
14 #import "NSHTTPCookieAdditions.h" 14 #import "NSHTTPCookieAdditions.h"
15 15
  16 +// We use our own custom run loop mode as CoreAnimation seems to want to hijack our threads otherwise
16 static CFStringRef ASIHTTPRequestRunMode = CFSTR("ASIHTTPRequest"); 17 static CFStringRef ASIHTTPRequestRunMode = CFSTR("ASIHTTPRequest");
17 18
18 static NSString *NetworkRequestErrorDomain = @"com.Your-Company.Your-Product.NetworkError."; 19 static NSString *NetworkRequestErrorDomain = @"com.Your-Company.Your-Product.NetworkError.";
@@ -31,8 +32,7 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -31,8 +32,7 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
31 [((ASIHTTPRequest*)clientCallBackInfo) handleNetworkEvent: type]; 32 [((ASIHTTPRequest*)clientCallBackInfo) handleNetworkEvent: type];
32 } 33 }
33 34
34 -//This lock prevents the operation from being cancelled while it is trying to update the progress, and vice versa 35 +// This lock prevents the operation from being cancelled while it is trying to update the progress, and vice versa
35 -  
36 static NSLock *progressLock; 36 static NSLock *progressLock;
37 37
38 @implementation ASIHTTPRequest 38 @implementation ASIHTTPRequest
@@ -166,7 +166,7 @@ static NSLock *progressLock; @@ -166,7 +166,7 @@ static NSLock *progressLock;
166 return; 166 return;
167 } 167 }
168 168
169 - //If we've already talked to this server and have valid credentials, let's apply them to the request 169 + // If we've already talked to this server and have valid credentials, let's apply them to the request
170 if (useSessionPersistance && sessionCredentials && sessionAuthentication) { 170 if (useSessionPersistance && sessionCredentials && sessionAuthentication) {
171 if (!CFHTTPMessageApplyCredentialDictionary(request, sessionAuthentication, (CFMutableDictionaryRef)sessionCredentials, NULL)) { 171 if (!CFHTTPMessageApplyCredentialDictionary(request, sessionAuthentication, (CFMutableDictionaryRef)sessionCredentials, NULL)) {
172 [ASIHTTPRequest setSessionAuthentication:NULL]; 172 [ASIHTTPRequest setSessionAuthentication:NULL];
@@ -174,7 +174,7 @@ static NSLock *progressLock; @@ -174,7 +174,7 @@ static NSLock *progressLock;
174 } 174 }
175 } 175 }
176 176
177 - //Add cookies from the persistant (mac os global) store 177 + // Add cookies from the persistant (mac os global) store
178 if (useCookiePersistance) { 178 if (useCookiePersistance) {
179 NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:url]; 179 NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:url];
180 if (cookies) { 180 if (cookies) {
@@ -182,7 +182,7 @@ static NSLock *progressLock; @@ -182,7 +182,7 @@ static NSLock *progressLock;
182 } 182 }
183 } 183 }
184 184
185 - //Apply request cookies 185 + // Apply request cookies
186 if ([requestCookies count] > 0) { 186 if ([requestCookies count] > 0) {
187 NSHTTPCookie *cookie; 187 NSHTTPCookie *cookie;
188 NSString *cookieHeader = nil; 188 NSString *cookieHeader = nil;
@@ -199,14 +199,14 @@ static NSLock *progressLock; @@ -199,14 +199,14 @@ static NSLock *progressLock;
199 } 199 }
200 200
201 201
202 - //Add custom headers 202 + // Add custom headers
203 NSString *header; 203 NSString *header;
204 for (header in requestHeaders) { 204 for (header in requestHeaders) {
205 CFHTTPMessageSetHeaderFieldValue(request, (CFStringRef)header, (CFStringRef)[requestHeaders objectForKey:header]); 205 CFHTTPMessageSetHeaderFieldValue(request, (CFStringRef)header, (CFStringRef)[requestHeaders objectForKey:header]);
206 } 206 }
207 207
208 208
209 - //If this is a post request and we have data to send, add it to the request 209 + // If this is a post request and we have data to send, add it to the request
210 if ([self postBody]) { 210 if ([self postBody]) {
211 CFHTTPMessageSetBody(request, (CFDataRef)postBody); 211 CFHTTPMessageSetBody(request, (CFDataRef)postBody);
212 postLength = [postBody length]; 212 postLength = [postBody length];
@@ -229,7 +229,7 @@ static NSLock *progressLock; @@ -229,7 +229,7 @@ static NSLock *progressLock;
229 totalBytesRead = 0; 229 totalBytesRead = 0;
230 lastBytesRead = 0; 230 lastBytesRead = 0;
231 231
232 - //If we're retrying a request after an authentication failure, let's remove any progress we made 232 + // If we're retrying a request after an authentication failure, let's remove any progress we made
233 if (lastBytesSent > 0 && uploadProgressDelegate) { 233 if (lastBytesSent > 0 && uploadProgressDelegate) {
234 [self removeUploadProgressSoFar]; 234 [self removeUploadProgressSoFar];
235 } 235 }
@@ -273,17 +273,17 @@ static NSLock *progressLock; @@ -273,17 +273,17 @@ static NSLock *progressLock;
273 [self performSelectorOnMainThread:@selector(resetUploadProgress:) withObject:[NSNumber numberWithDouble:postLength] waitUntilDone:YES]; 273 [self performSelectorOnMainThread:@selector(resetUploadProgress:) withObject:[NSNumber numberWithDouble:postLength] waitUntilDone:YES];
274 } 274 }
275 275
276 - //Record when the request started, so we can timeout if nothing happens 276 + // Record when the request started, so we can timeout if nothing happens
277 [self setLastActivityTime:[NSDate date]]; 277 [self setLastActivityTime:[NSDate date]];
278 278
279 // Wait for the request to finish 279 // Wait for the request to finish
280 while (!complete) { 280 while (!complete) {
281 281
282 - //This may take a while, so we'll release the pool each cycle to stop a giant backlog building up 282 + // This may take a while, so we'll release the pool each cycle to stop a giant backlog of autoreleased objects building up
283 [pool release]; 283 [pool release];
284 pool = [[NSAutoreleasePool alloc] init]; 284 pool = [[NSAutoreleasePool alloc] init];
285 285
286 - //See if we need to timeout 286 + // See if we need to timeout
287 if (lastActivityTime && timeOutSeconds > 0) { 287 if (lastActivityTime && timeOutSeconds > 0) {
288 if ([[NSDate date] timeIntervalSinceDate:lastActivityTime] > timeOutSeconds) { 288 if ([[NSDate date] timeIntervalSinceDate:lastActivityTime] > timeOutSeconds) {
289 [self failWithProblem:@"Request timed out"]; 289 [self failWithProblem:@"Request timed out"];
@@ -324,7 +324,7 @@ static NSLock *progressLock; @@ -324,7 +324,7 @@ static NSLock *progressLock;
324 if (receivedData) { 324 if (receivedData) {
325 [self setReceivedData:nil]; 325 [self setReceivedData:nil];
326 326
327 - //If we were downloading to a file, let's remove it 327 + //If we were downloading to a file, let's remove it
328 } else if (downloadDestinationPath) { 328 } else if (downloadDestinationPath) {
329 [outputStream close]; 329 [outputStream close];
330 [[NSFileManager defaultManager] removeFileAtPath:downloadDestinationPath handler:nil]; 330 [[NSFileManager defaultManager] removeFileAtPath:downloadDestinationPath handler:nil];
@@ -347,40 +347,11 @@ static NSLock *progressLock; @@ -347,40 +347,11 @@ static NSLock *progressLock;
347 } 347 }
348 348
349 349
350 -+ (void)setProgress:(double)progress forProgressIndicator:(id)indicator  
351 -{  
352 -  
353 - SEL selector;  
354 -  
355 - //Cocoa Touch: UIProgressView  
356 - if ([indicator respondsToSelector:@selector(setProgress:)]) {  
357 - selector = @selector(setProgress:);  
358 - NSMethodSignature *signature = [[indicator class] instanceMethodSignatureForSelector:selector];  
359 - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];  
360 - [invocation setSelector:selector];  
361 - float progressFloat = (float)progress; //UIProgressView wants a float for the progress parameter  
362 - [invocation setArgument:&progressFloat atIndex:2];  
363 - [invocation invokeWithTarget:indicator];  
364 -  
365 -  
366 - //Cocoa: NSProgressIndicator  
367 - } else if ([indicator respondsToSelector:@selector(setDoubleValue:)]) {  
368 - selector = @selector(setDoubleValue:);  
369 - NSMethodSignature *signature = [[indicator class] instanceMethodSignatureForSelector:selector];  
370 - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];  
371 - [invocation setSelector:selector];  
372 - [invocation setArgument:&progress atIndex:2];  
373 - [invocation invokeWithTarget:indicator];  
374 -  
375 - //Progress indicator is some other thing that we can't handle  
376 - } else {  
377 - return;  
378 - }  
379 -}  
380 -  
381 - (void)setUploadProgressDelegate:(id)newDelegate 350 - (void)setUploadProgressDelegate:(id)newDelegate
382 { 351 {
383 uploadProgressDelegate = newDelegate; 352 uploadProgressDelegate = newDelegate;
  353 +
  354 + // If the uploadProgressDelegate is an NSProgressIndicator, we set it's MaxValue to 1.0 so we can treat it similarly to UIProgressViews
384 SEL selector = @selector(setMaxValue:); 355 SEL selector = @selector(setMaxValue:);
385 if ([uploadProgressDelegate respondsToSelector:selector]) { 356 if ([uploadProgressDelegate respondsToSelector:selector]) {
386 double max = 1.0; 357 double max = 1.0;
@@ -394,31 +365,20 @@ static NSLock *progressLock; @@ -394,31 +365,20 @@ static NSLock *progressLock;
394 } 365 }
395 } 366 }
396 367
397 - 368 +- (void)setDownloadProgressDelegate:(id)newDelegate
398 --(void)removeUploadProgressSoFar  
399 { 369 {
400 - [progressLock lock]; 370 + downloadProgressDelegate = newDelegate;
401 - if ([self isCancelled]) {  
402 - [progressLock unlock];  
403 - return;  
404 - }  
405 371
406 - //We're using a progress queue or compatible controller to handle progress 372 + // If the downloadProgressDelegate is an NSProgressIndicator, we set it's MaxValue to 1.0 so we can treat it similarly to UIProgressViews
407 - if ([uploadProgressDelegate respondsToSelector:@selector(incrementUploadProgressBy:)]) { 373 + SEL selector = @selector(setMaxValue:);
408 - int value = 0-lastBytesSent; 374 + if ([downloadProgressDelegate respondsToSelector:selector]) {
409 - SEL selector = @selector(incrementUploadProgressBy:); 375 + double max = 1.0;
410 - NSMethodSignature *signature = [[uploadProgressDelegate class] instanceMethodSignatureForSelector:selector]; 376 + NSMethodSignature *signature = [[downloadProgressDelegate class] instanceMethodSignatureForSelector:selector];
411 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 377 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
412 - [invocation setTarget:uploadProgressDelegate]; 378 + [invocation setSelector:@selector(setMaxValue:)];
413 - [invocation setSelector:selector]; 379 + [invocation setArgument:&max atIndex:2];
414 - [invocation setArgument:&value atIndex:2]; 380 + [invocation invokeWithTarget:downloadProgressDelegate];
415 - [invocation invoke]; 381 + }
416 -  
417 - //We aren't using a queue, we should just set progress of the indicator to 0  
418 - } else {  
419 - [ASIHTTPRequest setProgress:0 forProgressIndicator:uploadProgressDelegate];  
420 - }  
421 - [progressLock unlock];  
422 } 382 }
423 383
424 384
@@ -546,6 +506,65 @@ static NSLock *progressLock; @@ -546,6 +506,65 @@ static NSLock *progressLock;
546 [progressLock unlock]; 506 [progressLock unlock];
547 } 507 }
548 508
  509 +-(void)removeUploadProgressSoFar
  510 +{
  511 + [progressLock lock];
  512 + if ([self isCancelled]) {
  513 + [progressLock unlock];
  514 + return;
  515 + }
  516 +
  517 + //We're using a progress queue or compatible controller to handle progress
  518 + if ([uploadProgressDelegate respondsToSelector:@selector(incrementUploadProgressBy:)]) {
  519 + int value = 0-lastBytesSent;
  520 + SEL selector = @selector(incrementUploadProgressBy:);
  521 + NSMethodSignature *signature = [[uploadProgressDelegate class] instanceMethodSignatureForSelector:selector];
  522 + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
  523 + [invocation setTarget:uploadProgressDelegate];
  524 + [invocation setSelector:selector];
  525 + [invocation setArgument:&value atIndex:2];
  526 + [invocation invoke];
  527 +
  528 + //We aren't using a queue, we should just set progress of the indicator to 0
  529 + } else {
  530 + [ASIHTTPRequest setProgress:0 forProgressIndicator:uploadProgressDelegate];
  531 + }
  532 + [progressLock unlock];
  533 +}
  534 +
  535 +
  536 ++ (void)setProgress:(double)progress forProgressIndicator:(id)indicator
  537 +{
  538 +
  539 + SEL selector;
  540 +
  541 + //Cocoa Touch: UIProgressView
  542 + if ([indicator respondsToSelector:@selector(setProgress:)]) {
  543 + selector = @selector(setProgress:);
  544 + NSMethodSignature *signature = [[indicator class] instanceMethodSignatureForSelector:selector];
  545 + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
  546 + [invocation setSelector:selector];
  547 + float progressFloat = (float)progress; //UIProgressView wants a float for the progress parameter
  548 + [invocation setArgument:&progressFloat atIndex:2];
  549 + [invocation invokeWithTarget:indicator];
  550 +
  551 +
  552 + //Cocoa: NSProgressIndicator
  553 + } else if ([indicator respondsToSelector:@selector(setDoubleValue:)]) {
  554 + selector = @selector(setDoubleValue:);
  555 + NSMethodSignature *signature = [[indicator class] instanceMethodSignatureForSelector:selector];
  556 + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
  557 + [invocation setSelector:selector];
  558 + [invocation setArgument:&progress atIndex:2];
  559 + [invocation invokeWithTarget:indicator];
  560 +
  561 + //Progress indicator is some other thing that we can't handle
  562 + } else {
  563 + return;
  564 + }
  565 +}
  566 +
  567 +
549 #pragma mark handling request complete / failure 568 #pragma mark handling request complete / failure
550 569
551 570
@@ -718,7 +737,7 @@ static NSLock *progressLock; @@ -718,7 +737,7 @@ static NSLock *progressLock;
718 - (void)attemptToApplyCredentialsAndResume 737 - (void)attemptToApplyCredentialsAndResume
719 { 738 {
720 739
721 - //Read authentication data 740 + // Read authentication data
722 if (!requestAuthentication) { 741 if (!requestAuthentication) {
723 CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader); 742 CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader);
724 requestAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader); 743 requestAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader);
@@ -730,7 +749,7 @@ static NSLock *progressLock; @@ -730,7 +749,7 @@ static NSLock *progressLock;
730 return; 749 return;
731 } 750 }
732 751
733 - //See if authentication is valid 752 + // See if authentication is valid
734 CFStreamError err; 753 CFStreamError err;
735 if (!CFHTTPAuthenticationIsValid(requestAuthentication, &err)) { 754 if (!CFHTTPAuthenticationIsValid(requestAuthentication, &err)) {
736 755
@@ -749,7 +768,7 @@ static NSLock *progressLock; @@ -749,7 +768,7 @@ static NSLock *progressLock;
749 [authenticationLock lockWhenCondition:2]; 768 [authenticationLock lockWhenCondition:2];
750 [authenticationLock unlock]; 769 [authenticationLock unlock];
751 770
752 - //Hopefully, the delegate gave us some credentials, let's apply them and reload 771 + // Hopefully, the delegate gave us some credentials, let's apply them and reload
753 [self attemptToApplyCredentialsAndResume]; 772 [self attemptToApplyCredentialsAndResume];
754 return; 773 return;
755 } 774 }
@@ -768,7 +787,7 @@ static NSLock *progressLock; @@ -768,7 +787,7 @@ static NSLock *progressLock;
768 [self failWithProblem:@"Failed to apply credentials to request"]; 787 [self failWithProblem:@"Failed to apply credentials to request"];
769 } 788 }
770 789
771 - // are a user name & password needed? 790 + // Are a user name & password needed?
772 } else if (CFHTTPAuthenticationRequiresUserNameAndPassword(requestAuthentication)) { 791 } else if (CFHTTPAuthenticationRequiresUserNameAndPassword(requestAuthentication)) {
773 792
774 NSMutableDictionary *newCredentials = [self findCredentials]; 793 NSMutableDictionary *newCredentials = [self findCredentials];
@@ -784,7 +803,7 @@ static NSLock *progressLock; @@ -784,7 +803,7 @@ static NSLock *progressLock;
784 return; 803 return;
785 } 804 }
786 805
787 - //We've got no credentials, let's ask the delegate to sort this out 806 + // We've got no credentials, let's ask the delegate to sort this out
788 ignoreError = YES; 807 ignoreError = YES;
789 if ([delegate respondsToSelector:@selector(authorizationNeededForRequest:)]) { 808 if ([delegate respondsToSelector:@selector(authorizationNeededForRequest:)]) {
790 [delegate performSelectorOnMainThread:@selector(authorizationNeededForRequest:) withObject:self waitUntilDone:YES]; 809 [delegate performSelectorOnMainThread:@selector(authorizationNeededForRequest:) withObject:self waitUntilDone:YES];
@@ -794,7 +813,7 @@ static NSLock *progressLock; @@ -794,7 +813,7 @@ static NSLock *progressLock;
794 return; 813 return;
795 } 814 }
796 815
797 - //The delegate isn't interested, we'll have to give up 816 + // The delegate isn't interested, we'll have to give up
798 [self setError:[self authenticationError]]; 817 [self setError:[self authenticationError]];
799 complete = YES; 818 complete = YES;
800 return; 819 return;
@@ -890,7 +909,7 @@ static NSLock *progressLock; @@ -890,7 +909,7 @@ static NSLock *progressLock;
890 readStream = NULL; 909 readStream = NULL;
891 } 910 }
892 911
893 - //close the output stream as we're done writing to the file 912 + // Close the output stream as we're done writing to the file
894 if (downloadDestinationPath) { 913 if (downloadDestinationPath) {
895 [outputStream close]; 914 [outputStream close];
896 } 915 }
@@ -906,7 +925,7 @@ static NSLock *progressLock; @@ -906,7 +925,7 @@ static NSLock *progressLock;
906 925
907 [self cancelLoad]; 926 [self cancelLoad];
908 927
909 - if (!error) { //We may already have handled this error 928 + if (!error) { // We may already have handled this error
910 [self failWithProblem:[NSString stringWithFormat: @"An error occurred: %@",[err localizedDescription]]]; 929 [self failWithProblem:[NSString stringWithFormat: @"An error occurred: %@",[err localizedDescription]]];
911 } 930 }
912 } 931 }
@@ -980,7 +999,7 @@ static NSLock *progressLock; @@ -980,7 +999,7 @@ static NSLock *progressLock;
980 999
981 + (void)setSessionCookies:(NSMutableArray *)newSessionCookies 1000 + (void)setSessionCookies:(NSMutableArray *)newSessionCookies
982 { 1001 {
983 - //Remove existing cookies from the persistent store 1002 + // Remove existing cookies from the persistent store
984 NSHTTPCookie *cookie; 1003 NSHTTPCookie *cookie;
985 for (cookie in newSessionCookies) { 1004 for (cookie in newSessionCookies) {
986 [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie]; 1005 [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
@@ -20,7 +20,6 @@ @@ -20,7 +20,6 @@
20 - (void)testFileDownload; 20 - (void)testFileDownload;
21 - (void)testDownloadProgress; 21 - (void)testDownloadProgress;
22 - (void)testUploadProgress; 22 - (void)testUploadProgress;
23 -- (void)testOperationQueue;  
24 - (void)testCookies; 23 - (void)testCookies;
25 24
26 @end 25 @end
@@ -138,66 +138,6 @@ More tests needed for: @@ -138,66 +138,6 @@ More tests needed for:
138 { 138 {
139 progress = newProgress; 139 progress = newProgress;
140 } 140 }
141 -  
142 -  
143 -  
144 -- (void)testOperationQueue  
145 -{  
146 - NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];  
147 -  
148 - NSURL *url;  
149 - url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/asi-http-request/tests/first"] autorelease];  
150 - ASIHTTPRequest *request1 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];  
151 - [queue addOperation:request1];  
152 -  
153 - url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/asi-http-request/tests/second"] autorelease];  
154 - ASIHTTPRequest *request2 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];  
155 - [queue addOperation:request2];  
156 -  
157 - url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/asi-http-request/tests/third"] autorelease];  
158 - ASIHTTPRequest *request3 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];  
159 - [queue addOperation:request3];  
160 -  
161 - url = [[[NSURL alloc] initWithString:@""] autorelease];  
162 - ASIHTTPRequest *request4 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];  
163 - [queue addOperation:request4];  
164 -  
165 - url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/asi-http-request/tests/broken"] autorelease];  
166 - ASIHTTPRequest *request5 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];  
167 - [queue addOperation:request5];  
168 -  
169 - [queue waitUntilAllOperationsAreFinished];  
170 -  
171 - BOOL success;  
172 -  
173 - success = ([request1 error] == nil);  
174 - STAssertTrue(success,@"Request 1 failed");  
175 -  
176 - success = [[request1 dataString] isEqualToString:@"This is the expected content for the first string"];  
177 - STAssertTrue(success,@"Failed to download the correct data for request 1");  
178 -  
179 - success = ([request2 error] == nil);  
180 - STAssertTrue(success,@"Request 2 failed");  
181 -  
182 - success = [[request2 dataString] isEqualToString:@"This is the expected content for the second string"];  
183 - STAssertTrue(success,@"Failed to download the correct data for request 2");  
184 -  
185 - success = ([request3 error] == nil);  
186 - STAssertTrue(success,@"Request 3 failed");  
187 -  
188 - success = [[request3 dataString] isEqualToString:@"This is the expected content for the third string"];  
189 - STAssertTrue(success,@"Failed to download the correct data for request 3");  
190 -  
191 - success = ([request4 error] != nil);  
192 - STAssertTrue(success,@"Request 4 succeed when it should have failed");  
193 -  
194 - success = ([request5 error] == nil);  
195 - STAssertTrue(success,@"Request 5 failed");  
196 -  
197 - success = ([request5 responseStatusCode] == 404);  
198 - STAssertTrue(success,@"Failed to obtain the correct status code for request 5");  
199 -  
200 -}  
201 141
202 142
203 143
@@ -9,27 +9,44 @@ @@ -9,27 +9,44 @@
9 9
10 10
11 @interface ASINetworkQueue : NSOperationQueue { 11 @interface ASINetworkQueue : NSOperationQueue {
  12 +
  13 + // Delegate will get didFail + didFinish messages (if set), as well as authorizationNeededForRequest messages
12 id delegate; 14 id delegate;
  15 +
  16 + // Will be called when a request completes with the request as the argument
  17 + SEL requestDidFinishSelector;
  18 +
  19 + // Will be called when a request fails with the request as the argument
  20 + SEL requestDidFailSelector;
  21 +
  22 + // Will be called when the queue finishes with the queue as the argument
  23 + SEL queueDidFinishSelector;
13 24
  25 + // Upload progress indicator, probably an NSProgressIndicator or UIProgressView
14 id uploadProgressDelegate; 26 id uploadProgressDelegate;
  27 +
  28 + // Total amount uploaded so far for all requests in this queue
15 int uploadProgressBytes; 29 int uploadProgressBytes;
  30 +
  31 + // Total amount to be uploaded for all requests in this queue - requests add to this figure as they work out how much data they have to transmit
16 int uploadProgressTotalBytes; 32 int uploadProgressTotalBytes;
17 33
  34 + // Download progress indicator, probably an NSProgressIndicator or UIProgressView
18 id downloadProgressDelegate; 35 id downloadProgressDelegate;
  36 +
  37 + // Total amount downloaded so far for all requests in this queue
19 int downloadProgressBytes; 38 int downloadProgressBytes;
20 - int downloadProgressTotalBytes;  
21 39
22 - SEL requestDidFinishSelector; 40 + // Total amount to be downloaded for all requests in this queue - requests add to this figure as they receive Content-Length headers
23 - SEL requestDidFailSelector; 41 + int downloadProgressTotalBytes;
24 - SEL queueDidFinishSelector;  
25 42
  43 + // When YES, the queue will cancel all requests when a request fails. Default is YES
26 BOOL shouldCancelAllRequestsOnFailure; 44 BOOL shouldCancelAllRequestsOnFailure;
27 45
28 int requestsCount; 46 int requestsCount;
29 int requestsCompleteCount; 47 int requestsCompleteCount;
30 } 48 }
31 49
32 -//  
33 50
34 // Called at the start of a request to add on the size of this upload to the total 51 // Called at the start of a request to add on the size of this upload to the total
35 - (void)incrementUploadSizeBy:(int)bytes; 52 - (void)incrementUploadSizeBy:(int)bytes;
@@ -48,6 +48,8 @@ @@ -48,6 +48,8 @@
48 - (void)setUploadProgressDelegate:(id)newDelegate 48 - (void)setUploadProgressDelegate:(id)newDelegate
49 { 49 {
50 uploadProgressDelegate = newDelegate; 50 uploadProgressDelegate = newDelegate;
  51 +
  52 + // If the uploadProgressDelegate is an NSProgressIndicator, we set it's MaxValue to 1.0 so we can treat it similarly to UIProgressViews
51 SEL selector = @selector(setMaxValue:); 53 SEL selector = @selector(setMaxValue:);
52 if ([uploadProgressDelegate respondsToSelector:selector]) { 54 if ([uploadProgressDelegate respondsToSelector:selector]) {
53 double max = 1.0; 55 double max = 1.0;
@@ -64,6 +66,8 @@ @@ -64,6 +66,8 @@
64 - (void)setDownloadProgressDelegate:(id)newDelegate 66 - (void)setDownloadProgressDelegate:(id)newDelegate
65 { 67 {
66 downloadProgressDelegate = newDelegate; 68 downloadProgressDelegate = newDelegate;
  69 +
  70 + // If the downloadProgressDelegate is an NSProgressIndicator, we set it's MaxValue to 1.0 so we can treat it similarly to UIProgressViews
67 SEL selector = @selector(setMaxValue:); 71 SEL selector = @selector(setMaxValue:);
68 if ([downloadProgressDelegate respondsToSelector:selector]) { 72 if ([downloadProgressDelegate respondsToSelector:selector]) {
69 double max = 1.0; 73 double max = 1.0;
@@ -75,7 +79,7 @@ @@ -75,7 +79,7 @@
75 } 79 }
76 } 80 }
77 81
78 -//Only add ASIHTTPRequests to this queue 82 +// Only add ASIHTTPRequests to this queue!!
79 - (void)addOperation:(NSOperation *)operation 83 - (void)addOperation:(NSOperation *)operation
80 { 84 {
81 if ([operation isKindOfClass:[ASIHTTPRequest class]]) { 85 if ([operation isKindOfClass:[ASIHTTPRequest class]]) {
@@ -160,6 +164,7 @@ @@ -160,6 +164,7 @@
160 [ASIHTTPRequest setProgress:progress forProgressIndicator:downloadProgressDelegate]; 164 [ASIHTTPRequest setProgress:progress forProgressIndicator:downloadProgressDelegate];
161 } 165 }
162 166
  167 +// Since this queue takes over as the delegate for all requests it contains, it should forward authorisation requests to its own delegate
163 - (void)authorizationNeededForRequest:(ASIHTTPRequest *)request 168 - (void)authorizationNeededForRequest:(ASIHTTPRequest *)request
164 { 169 {
165 if ([delegate respondsToSelector:@selector(authorizationNeededForRequest:)]) { 170 if ([delegate respondsToSelector:@selector(authorizationNeededForRequest:)]) {
@@ -82,12 +82,48 @@ @@ -82,12 +82,48 @@
82 url = [[[NSURL alloc] initWithString:@""] autorelease]; 82 url = [[[NSURL alloc] initWithString:@""] autorelease];
83 requestThatShouldFail = [[ASIHTTPRequest alloc] initWithURL:url]; 83 requestThatShouldFail = [[ASIHTTPRequest alloc] initWithURL:url];
84 [networkQueue addOperation:requestThatShouldFail]; 84 [networkQueue addOperation:requestThatShouldFail];
  85 +
  86 + url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/asi-http-request/tests/broken"] autorelease];
  87 + ASIHTTPRequest *request5 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
  88 + [networkQueue addOperation:request5];
  89 +
85 90
86 NSDate* endDate = [NSDate distantFuture]; 91 NSDate* endDate = [NSDate distantFuture];
87 while (!complete) { 92 while (!complete) {
88 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:endDate]; 93 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:endDate];
89 } 94 }
90 95
  96 +
  97 + BOOL success;
  98 + success = ([request1 error] == nil);
  99 + STAssertTrue(success,@"Request 1 failed");
  100 +
  101 + success = [[request1 dataString] isEqualToString:@"This is the expected content for the first string"];
  102 + STAssertTrue(success,@"Failed to download the correct data for request 1");
  103 +
  104 + success = ([request2 error] == nil);
  105 + STAssertTrue(success,@"Request 2 failed");
  106 +
  107 + success = [[request2 dataString] isEqualToString:@"This is the expected content for the second string"];
  108 + STAssertTrue(success,@"Failed to download the correct data for request 2");
  109 +
  110 + success = ([request3 error] == nil);
  111 + STAssertTrue(success,@"Request 3 failed");
  112 +
  113 + success = [[request3 dataString] isEqualToString:@"This is the expected content for the third string"];
  114 + STAssertTrue(success,@"Failed to download the correct data for request 3");
  115 +
  116 + success = ([requestThatShouldFail error] != nil);
  117 + STAssertTrue(success,@"Request 4 succeed when it should have failed");
  118 +
  119 + success = ([request5 error] == nil);
  120 + STAssertTrue(success,@"Request 5 failed");
  121 +
  122 + success = ([request5 responseStatusCode] == 404);
  123 + STAssertTrue(success,@"Failed to obtain the correct status code for request 5");
  124 +
  125 +
  126 +
91 [requestThatShouldFail release]; 127 [requestThatShouldFail release];
92 128
93 } 129 }
@@ -118,14 +154,14 @@ @@ -118,14 +154,14 @@
118 url = [[[NSURL alloc] initWithString:@""] autorelease]; 154 url = [[[NSURL alloc] initWithString:@""] autorelease];
119 requestThatShouldFail = [[ASIHTTPRequest alloc] initWithURL:url]; 155 requestThatShouldFail = [[ASIHTTPRequest alloc] initWithURL:url];
120 [networkQueue addOperation:requestThatShouldFail]; 156 [networkQueue addOperation:requestThatShouldFail];
121 - 157 +
122 NSDate* endDate = [NSDate distantFuture]; 158 NSDate* endDate = [NSDate distantFuture];
123 while (!complete) { 159 while (!complete) {
124 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:endDate]; 160 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:endDate];
125 } 161 }
126 162
127 - [requestThatShouldFail release];  
128 163
  164 + [requestThatShouldFail release];
129 } 165 }
130 166
131 - (void)requestFailedCancellingOthers:(ASIHTTPRequest *)request 167 - (void)requestFailedCancellingOthers:(ASIHTTPRequest *)request
@@ -144,7 +180,6 @@ @@ -144,7 +180,6 @@
144 - (void)queueFinished:(ASINetworkQueue *)queue 180 - (void)queueFinished:(ASINetworkQueue *)queue
145 { 181 {
146 complete = YES; 182 complete = YES;
147 -  
148 } 183 }
149 184
150 185