Showing
7 changed files
with
65 additions
and
37 deletions
| @@ -50,6 +50,11 @@ | @@ -50,6 +50,11 @@ | ||
| 50 | 50 | ||
| 51 | - (void)buildPostBody | 51 | - (void)buildPostBody |
| 52 | { | 52 | { |
| 53 | + if (!postData && ! fileData) { | ||
| 54 | + [super buildPostBody]; | ||
| 55 | + return; | ||
| 56 | + } | ||
| 57 | + | ||
| 53 | NSMutableData *body = [[[NSMutableData alloc] init] autorelease]; | 58 | NSMutableData *body = [[[NSMutableData alloc] init] autorelease]; |
| 54 | 59 | ||
| 55 | // 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. | 60 | // 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. |
| @@ -10,6 +10,7 @@ | @@ -10,6 +10,7 @@ | ||
| 10 | // Portions are based on the ImageClient example from Apple: | 10 | // Portions are based on the ImageClient example from Apple: |
| 11 | // See: http://developer.apple.com/samplecode/ImageClient/listing37.html | 11 | // See: http://developer.apple.com/samplecode/ImageClient/listing37.html |
| 12 | 12 | ||
| 13 | +#import <Cocoa/Cocoa.h> | ||
| 13 | 14 | ||
| 14 | @interface ASIHTTPRequest : NSOperation { | 15 | @interface ASIHTTPRequest : NSOperation { |
| 15 | 16 | ||
| @@ -93,18 +94,18 @@ | @@ -93,18 +94,18 @@ | ||
| 93 | int responseStatusCode; | 94 | int responseStatusCode; |
| 94 | 95 | ||
| 95 | //Size of the response | 96 | //Size of the response |
| 96 | - unsigned int contentLength; | 97 | + unsigned long long contentLength; |
| 97 | 98 | ||
| 98 | //Size of the POST payload | 99 | //Size of the POST payload |
| 99 | - unsigned int postLength; | 100 | + unsigned long long postLength; |
| 100 | 101 | ||
| 101 | //The total amount of downloaded data | 102 | //The total amount of downloaded data |
| 102 | - unsigned int totalBytesRead; | 103 | + unsigned long long totalBytesRead; |
| 103 | 104 | ||
| 104 | //Last amount of data read (used for incrementing progress) | 105 | //Last amount of data read (used for incrementing progress) |
| 105 | - unsigned int lastBytesRead; | 106 | + unsigned long long lastBytesRead; |
| 106 | //Last amount of data sent (used for incrementing progress) | 107 | //Last amount of data sent (used for incrementing progress) |
| 107 | - unsigned int lastBytesSent; | 108 | + unsigned long long lastBytesSent; |
| 108 | 109 | ||
| 109 | //Realm for authentication when credentials are required | 110 | //Realm for authentication when credentials are required |
| 110 | NSString *authenticationRealm; | 111 | NSString *authenticationRealm; |
| @@ -112,6 +113,9 @@ | @@ -112,6 +113,9 @@ | ||
| 112 | //This lock will block the request until the delegate supplies authentication info | 113 | //This lock will block the request until the delegate supplies authentication info |
| 113 | NSConditionLock *authenticationLock; | 114 | NSConditionLock *authenticationLock; |
| 114 | 115 | ||
| 116 | + //This lock prevents the operation from being cancelled at an inopportune moment | ||
| 117 | + NSLock *cancelledLock; | ||
| 118 | + | ||
| 115 | //Called on the delegate when the request completes successfully | 119 | //Called on the delegate when the request completes successfully |
| 116 | SEL didFinishSelector; | 120 | SEL didFinishSelector; |
| 117 | 121 | ||
| @@ -128,7 +132,7 @@ | @@ -128,7 +132,7 @@ | ||
| 128 | NSAutoreleasePool *pool; | 132 | NSAutoreleasePool *pool; |
| 129 | 133 | ||
| 130 | // Will be YES when a HEAD request will handle the content-length before this request starts | 134 | // Will be YES when a HEAD request will handle the content-length before this request starts |
| 131 | - BOOL useCachedContentLength; | 135 | + BOOL shouldResetProgressIndicators; |
| 132 | 136 | ||
| 133 | // Used by HEAD requests when showAccurateProgress is YES to preset the content-length for this request | 137 | // Used by HEAD requests when showAccurateProgress is YES to preset the content-length for this request |
| 134 | ASIHTTPRequest *mainRequest; | 138 | ASIHTTPRequest *mainRequest; |
| @@ -177,9 +181,9 @@ | @@ -177,9 +181,9 @@ | ||
| 177 | 181 | ||
| 178 | // Called on main thread to update progress delegates | 182 | // Called on main thread to update progress delegates |
| 179 | - (void)updateProgressIndicators; | 183 | - (void)updateProgressIndicators; |
| 180 | -- (void)resetUploadProgress:(NSNumber *)max; | 184 | +- (void)resetUploadProgress:(unsigned long long)value; |
| 181 | - (void)updateUploadProgress; | 185 | - (void)updateUploadProgress; |
| 182 | -- (void)resetDownloadProgress:(NSNumber *)max; | 186 | +- (void)resetDownloadProgress:(unsigned long long)value; |
| 183 | - (void)updateDownloadProgress; | 187 | - (void)updateDownloadProgress; |
| 184 | 188 | ||
| 185 | // Called when authorisation is needed, as we only find out we don't have permission to something when the upload is complete | 189 | // Called when authorisation is needed, as we only find out we don't have permission to something when the upload is complete |
| @@ -279,10 +283,10 @@ | @@ -279,10 +283,10 @@ | ||
| 279 | @property (assign) NSTimeInterval timeOutSeconds; | 283 | @property (assign) NSTimeInterval timeOutSeconds; |
| 280 | @property (retain) NSString *requestMethod; | 284 | @property (retain) NSString *requestMethod; |
| 281 | @property (retain,setter=setPostBody:) NSData *postBody; | 285 | @property (retain,setter=setPostBody:) NSData *postBody; |
| 282 | -@property (assign) unsigned int contentLength; | 286 | +@property (assign) unsigned long long contentLength; |
| 283 | -@property (assign) unsigned int postLength; | 287 | +@property (assign) unsigned long long postLength; |
| 284 | -@property (assign) BOOL useCachedContentLength; | 288 | +@property (assign) BOOL shouldResetProgressIndicators; |
| 285 | @property (retain) ASIHTTPRequest *mainRequest; | 289 | @property (retain) ASIHTTPRequest *mainRequest; |
| 286 | @property (assign) BOOL showAccurateProgress; | 290 | @property (assign) BOOL showAccurateProgress; |
| 287 | -@property (assign,readonly) unsigned int totalBytesRead; | 291 | +@property (assign,readonly) unsigned long long totalBytesRead; |
| 288 | @end | 292 | @end |
This diff is collapsed. Click to expand it.
| @@ -109,8 +109,9 @@ | @@ -109,8 +109,9 @@ | ||
| 109 | ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | 109 | ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; |
| 110 | [request setDownloadProgressDelegate:self]; | 110 | [request setDownloadProgressDelegate:self]; |
| 111 | [request start]; | 111 | [request start]; |
| 112 | + | ||
| 112 | BOOL success = (progress == 1); | 113 | BOOL success = (progress == 1); |
| 113 | - STAssertTrue(success,@"Failed to properly increment download progress"); | 114 | + STAssertTrue(success,@"Failed to properly increment download progress %f != 1.0",progress); |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | 117 | ||
| @@ -121,8 +122,9 @@ | @@ -121,8 +122,9 @@ | ||
| 121 | [request setPostBody:[NSMutableData dataWithLength:1024*32]]; | 122 | [request setPostBody:[NSMutableData dataWithLength:1024*32]]; |
| 122 | [request setUploadProgressDelegate:self]; | 123 | [request setUploadProgressDelegate:self]; |
| 123 | [request start]; | 124 | [request start]; |
| 125 | + | ||
| 124 | BOOL success = (progress == 1); | 126 | BOOL success = (progress == 1); |
| 125 | - STAssertTrue(success,@"Failed to properly increment upload progress"); | 127 | + STAssertTrue(success,@"Failed to properly increment upload progress %f != 1.0",progress); |
| 126 | } | 128 | } |
| 127 | 129 | ||
| 128 | 130 |
| @@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
| 6 | // Copyright 2008 All-Seeing Interactive. All rights reserved. | 6 | // Copyright 2008 All-Seeing Interactive. All rights reserved. |
| 7 | // | 7 | // |
| 8 | 8 | ||
| 9 | - | 9 | +#import <Cocoa/Cocoa.h> |
| 10 | 10 | ||
| 11 | @interface ASINetworkQueue : NSOperationQueue { | 11 | @interface ASINetworkQueue : NSOperationQueue { |
| 12 | 12 | ||
| @@ -26,19 +26,19 @@ | @@ -26,19 +26,19 @@ | ||
| 26 | id uploadProgressDelegate; | 26 | id uploadProgressDelegate; |
| 27 | 27 | ||
| 28 | // Total amount uploaded so far for all requests in this queue | 28 | // Total amount uploaded so far for all requests in this queue |
| 29 | - unsigned int uploadProgressBytes; | 29 | + unsigned long long uploadProgressBytes; |
| 30 | 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 | 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 |
| 32 | - unsigned int uploadProgressTotalBytes; | 32 | + unsigned long long uploadProgressTotalBytes; |
| 33 | 33 | ||
| 34 | // Download progress indicator, probably an NSProgressIndicator or UIProgressView | 34 | // Download progress indicator, probably an NSProgressIndicator or UIProgressView |
| 35 | id downloadProgressDelegate; | 35 | id downloadProgressDelegate; |
| 36 | 36 | ||
| 37 | // Total amount downloaded so far for all requests in this queue | 37 | // Total amount downloaded so far for all requests in this queue |
| 38 | - unsigned int downloadProgressBytes; | 38 | + unsigned long long downloadProgressBytes; |
| 39 | 39 | ||
| 40 | // Total amount to be downloaded for all requests in this queue - requests add to this figure as they receive Content-Length headers | 40 | // Total amount to be downloaded for all requests in this queue - requests add to this figure as they receive Content-Length headers |
| 41 | - unsigned int downloadProgressTotalBytes; | 41 | + unsigned long long downloadProgressTotalBytes; |
| 42 | 42 | ||
| 43 | // When YES, the queue will cancel all requests when a request fails. Default is YES | 43 | // When YES, the queue will cancel all requests when a request fails. Default is YES |
| 44 | BOOL shouldCancelAllRequestsOnFailure; | 44 | BOOL shouldCancelAllRequestsOnFailure; |
| @@ -61,16 +61,19 @@ | @@ -61,16 +61,19 @@ | ||
| 61 | - (void)addHEADOperation:(NSOperation *)operation; | 61 | - (void)addHEADOperation:(NSOperation *)operation; |
| 62 | 62 | ||
| 63 | // Called at the start of a request to add on the size of this upload to the total | 63 | // Called at the start of a request to add on the size of this upload to the total |
| 64 | -- (void)incrementUploadSizeBy:(int)bytes; | 64 | +- (void)incrementUploadSizeBy:(unsigned long long)bytes; |
| 65 | 65 | ||
| 66 | // Called during a request when data is written to the upload stream to increment the progress indicator | 66 | // Called during a request when data is written to the upload stream to increment the progress indicator |
| 67 | -- (void)incrementUploadProgressBy:(int)bytes; | 67 | +- (void)incrementUploadProgressBy:(unsigned long long)bytes; |
| 68 | 68 | ||
| 69 | // Called at the start of a request to add on the size of this download to the total | 69 | // Called at the start of a request to add on the size of this download to the total |
| 70 | -- (void)incrementDownloadSizeBy:(int)bytes; | 70 | +- (void)incrementDownloadSizeBy:(unsigned long long)bytes; |
| 71 | 71 | ||
| 72 | // Called during a request when data is received to increment the progress indicator | 72 | // Called during a request when data is received to increment the progress indicator |
| 73 | -- (void)incrementDownloadProgressBy:(int)bytes; | 73 | +- (void)incrementDownloadProgressBy:(unsigned long long)bytes; |
| 74 | + | ||
| 75 | +// Called during a request when authorisation fails to cancel any progress so far | ||
| 76 | +- (void)decrementUploadProgressBy:(unsigned long long)bytes; | ||
| 74 | 77 | ||
| 75 | // All ASINetworkQueues are paused when created so that total size can be calculated before the queue starts | 78 | // All ASINetworkQueues are paused when created so that total size can be calculated before the queue starts |
| 76 | // This method will start the queue | 79 | // This method will start the queue |
| @@ -34,6 +34,7 @@ | @@ -34,6 +34,7 @@ | ||
| 34 | 34 | ||
| 35 | showAccurateProgress = NO; | 35 | showAccurateProgress = NO; |
| 36 | 36 | ||
| 37 | + [self setMaxConcurrentOperationCount:4]; | ||
| 37 | [self setSuspended:YES]; | 38 | [self setSuspended:YES]; |
| 38 | 39 | ||
| 39 | return self; | 40 | return self; |
| @@ -59,9 +60,6 @@ | @@ -59,9 +60,6 @@ | ||
| 59 | uploadProgressTotalBytes = 0; | 60 | uploadProgressTotalBytes = 0; |
| 60 | downloadProgressBytes = 0; | 61 | downloadProgressBytes = 0; |
| 61 | downloadProgressTotalBytes = 0; | 62 | downloadProgressTotalBytes = 0; |
| 62 | - [self setUploadProgressDelegate:nil]; | ||
| 63 | - [self setDownloadProgressDelegate:nil]; | ||
| 64 | - [self setDelegate:nil]; | ||
| 65 | [super cancelAllOperations]; | 63 | [super cancelAllOperations]; |
| 66 | } | 64 | } |
| 67 | 65 | ||
| @@ -103,6 +101,8 @@ | @@ -103,6 +101,8 @@ | ||
| 103 | if ([operation isKindOfClass:[ASIHTTPRequest class]]) { | 101 | if ([operation isKindOfClass:[ASIHTTPRequest class]]) { |
| 104 | 102 | ||
| 105 | ASIHTTPRequest *request = (ASIHTTPRequest *)operation; | 103 | ASIHTTPRequest *request = (ASIHTTPRequest *)operation; |
| 104 | + [request setRequestMethod:@"HEAD"]; | ||
| 105 | + [request setQueuePriority:10]; | ||
| 106 | [request setShowAccurateProgress:YES]; | 106 | [request setShowAccurateProgress:YES]; |
| 107 | if (uploadProgressDelegate) { | 107 | if (uploadProgressDelegate) { |
| 108 | [request setUploadProgressDelegate:self]; | 108 | [request setUploadProgressDelegate:self]; |
| @@ -133,12 +133,11 @@ | @@ -133,12 +133,11 @@ | ||
| 133 | //If this is a GET request and we want accurate progress, perform a HEAD request first to get the content-length | 133 | //If this is a GET request and we want accurate progress, perform a HEAD request first to get the content-length |
| 134 | if ([[request requestMethod] isEqualToString:@"GET"]) { | 134 | if ([[request requestMethod] isEqualToString:@"GET"]) { |
| 135 | ASIHTTPRequest *HEADRequest = [[[ASIHTTPRequest alloc] initWithURL:[request url]] autorelease]; | 135 | ASIHTTPRequest *HEADRequest = [[[ASIHTTPRequest alloc] initWithURL:[request url]] autorelease]; |
| 136 | - [HEADRequest setRequestMethod:@"HEAD"]; | ||
| 137 | - [HEADRequest setQueuePriority:10]; | ||
| 138 | [HEADRequest setMainRequest:request]; | 136 | [HEADRequest setMainRequest:request]; |
| 139 | [self addHEADOperation:HEADRequest]; | 137 | [self addHEADOperation:HEADRequest]; |
| 140 | 138 | ||
| 141 | - [request setUseCachedContentLength:YES]; | 139 | + //Tell the request not to reset the progress indicator when it gets a content-length, as we will get the length from the HEAD request |
| 140 | + [request setShouldResetProgressIndicators:NO]; | ||
| 142 | [request addDependency:HEADRequest]; | 141 | [request addDependency:HEADRequest]; |
| 143 | 142 | ||
| 144 | //If we want to track uploading for this request accurately, we need to add the size of the post content to the total | 143 | //If we want to track uploading for this request accurately, we need to add the size of the post content to the total |
| @@ -150,6 +149,9 @@ | @@ -150,6 +149,9 @@ | ||
| 150 | [request setShowAccurateProgress:showAccurateProgress]; | 149 | [request setShowAccurateProgress:showAccurateProgress]; |
| 151 | 150 | ||
| 152 | if (uploadProgressDelegate) { | 151 | if (uploadProgressDelegate) { |
| 152 | + | ||
| 153 | + //For uploads requests, we always work out the total upload size before the queue starts, so we tell the request not to reset the progress indicator when starting each request | ||
| 154 | + [request setShouldResetProgressIndicators:NO]; | ||
| 153 | [request setUploadProgressDelegate:self]; | 155 | [request setUploadProgressDelegate:self]; |
| 154 | } else { | 156 | } else { |
| 155 | [request setUploadProgressDelegate:NULL]; | 157 | [request setUploadProgressDelegate:NULL]; |
| @@ -173,7 +175,7 @@ | @@ -173,7 +175,7 @@ | ||
| 173 | if (requestDidFailSelector) { | 175 | if (requestDidFailSelector) { |
| 174 | [delegate performSelector:requestDidFailSelector withObject:request]; | 176 | [delegate performSelector:requestDidFailSelector withObject:request]; |
| 175 | } | 177 | } |
| 176 | - if (shouldCancelAllRequestsOnFailure) { | 178 | + if (shouldCancelAllRequestsOnFailure && requestsCount > 0) { |
| 177 | [self cancelAllOperations]; | 179 | [self cancelAllOperations]; |
| 178 | } | 180 | } |
| 179 | } | 181 | } |
| @@ -191,7 +193,7 @@ | @@ -191,7 +193,7 @@ | ||
| 191 | } | 193 | } |
| 192 | } | 194 | } |
| 193 | 195 | ||
| 194 | -- (void)incrementUploadSizeBy:(int)bytes | 196 | +- (void)incrementUploadSizeBy:(unsigned long long)bytes |
| 195 | { | 197 | { |
| 196 | if (!uploadProgressDelegate) { | 198 | if (!uploadProgressDelegate) { |
| 197 | return; | 199 | return; |
| @@ -200,7 +202,19 @@ | @@ -200,7 +202,19 @@ | ||
| 200 | [self incrementUploadProgressBy:0]; | 202 | [self incrementUploadProgressBy:0]; |
| 201 | } | 203 | } |
| 202 | 204 | ||
| 203 | -- (void)incrementUploadProgressBy:(int)bytes | 205 | +- (void)decrementUploadProgressBy:(unsigned long long)bytes |
| 206 | +{ | ||
| 207 | + if (!uploadProgressDelegate || uploadProgressTotalBytes == 0) { | ||
| 208 | + return; | ||
| 209 | + } | ||
| 210 | + uploadProgressBytes -= bytes; | ||
| 211 | + | ||
| 212 | + double progress = (uploadProgressBytes*1.0)/(uploadProgressTotalBytes*1.0); | ||
| 213 | + [ASIHTTPRequest setProgress:progress forProgressIndicator:uploadProgressDelegate]; | ||
| 214 | +} | ||
| 215 | + | ||
| 216 | + | ||
| 217 | +- (void)incrementUploadProgressBy:(unsigned long long)bytes | ||
| 204 | { | 218 | { |
| 205 | if (!uploadProgressDelegate || uploadProgressTotalBytes == 0) { | 219 | if (!uploadProgressDelegate || uploadProgressTotalBytes == 0) { |
| 206 | return; | 220 | return; |
| @@ -209,24 +223,26 @@ | @@ -209,24 +223,26 @@ | ||
| 209 | 223 | ||
| 210 | double progress = (uploadProgressBytes*1.0)/(uploadProgressTotalBytes*1.0); | 224 | double progress = (uploadProgressBytes*1.0)/(uploadProgressTotalBytes*1.0); |
| 211 | [ASIHTTPRequest setProgress:progress forProgressIndicator:uploadProgressDelegate]; | 225 | [ASIHTTPRequest setProgress:progress forProgressIndicator:uploadProgressDelegate]; |
| 226 | + | ||
| 212 | } | 227 | } |
| 213 | 228 | ||
| 214 | -- (void)incrementDownloadSizeBy:(int)bytes | 229 | +- (void)incrementDownloadSizeBy:(unsigned long long)bytes |
| 215 | { | 230 | { |
| 216 | if (!downloadProgressDelegate) { | 231 | if (!downloadProgressDelegate) { |
| 217 | return; | 232 | return; |
| 218 | } | 233 | } |
| 219 | downloadProgressTotalBytes += bytes; | 234 | downloadProgressTotalBytes += bytes; |
| 220 | [self incrementDownloadProgressBy:0]; | 235 | [self incrementDownloadProgressBy:0]; |
| 236 | + NSLog(@"download size is now: %qu",downloadProgressTotalBytes); | ||
| 221 | } | 237 | } |
| 222 | 238 | ||
| 223 | -- (void)incrementDownloadProgressBy:(int)bytes | 239 | +- (void)incrementDownloadProgressBy:(unsigned long long)bytes |
| 224 | { | 240 | { |
| 225 | if (!downloadProgressDelegate || downloadProgressTotalBytes == 0) { | 241 | if (!downloadProgressDelegate || downloadProgressTotalBytes == 0) { |
| 226 | return; | 242 | return; |
| 227 | } | 243 | } |
| 228 | downloadProgressBytes += bytes; | 244 | downloadProgressBytes += bytes; |
| 229 | - //NSLog(@"%hu/%hu",downloadProgressBytes,downloadProgressTotalBytes); | 245 | + //NSLog(@"%qu/%qu",downloadProgressBytes,downloadProgressTotalBytes); |
| 230 | double progress = (downloadProgressBytes*1.0)/(downloadProgressTotalBytes*1.0); | 246 | double progress = (downloadProgressBytes*1.0)/(downloadProgressTotalBytes*1.0); |
| 231 | [ASIHTTPRequest setProgress:progress forProgressIndicator:downloadProgressDelegate]; | 247 | [ASIHTTPRequest setProgress:progress forProgressIndicator:downloadProgressDelegate]; |
| 232 | } | 248 | } |
| @@ -201,8 +201,6 @@ | @@ -201,8 +201,6 @@ | ||
| 201 | 201 | ||
| 202 | - (void)requestFailedCancellingOthers:(ASIHTTPRequest *)request | 202 | - (void)requestFailedCancellingOthers:(ASIHTTPRequest *)request |
| 203 | { | 203 | { |
| 204 | - BOOL success = (request == requestThatShouldFail); | ||
| 205 | - STAssertTrue(success,@"Wrong request failed"); | ||
| 206 | complete = YES; | 204 | complete = YES; |
| 207 | } | 205 | } |
| 208 | 206 |
-
Please register or login to post a comment