Start work on test for file-streamed request body
Improve comments
Showing
7 changed files
with
130 additions
and
31 deletions
| @@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
| 3 | // asi-http-request | 3 | // asi-http-request |
| 4 | // | 4 | // |
| 5 | // Created by Ben Copsey on 07/11/2008. | 5 | // Created by Ben Copsey on 07/11/2008. |
| 6 | -// Copyright 2008 All-Seeing Interactive. All rights reserved. | 6 | +// Copyright 2008-2009 All-Seeing Interactive. All rights reserved. |
| 7 | // | 7 | // |
| 8 | 8 | ||
| 9 | #import "ASIHTTPRequest.h" | 9 | #import "ASIHTTPRequest.h" |
| @@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
| 3 | // asi-http-request | 3 | // asi-http-request |
| 4 | // | 4 | // |
| 5 | // Created by Ben Copsey on 07/11/2008. | 5 | // Created by Ben Copsey on 07/11/2008. |
| 6 | -// Copyright 2008 All-Seeing Interactive. All rights reserved. | 6 | +// Copyright 2008-2009 All-Seeing Interactive. All rights reserved. |
| 7 | // | 7 | // |
| 8 | 8 | ||
| 9 | #import "ASIFormDataRequest.h" | 9 | #import "ASIFormDataRequest.h" |
| @@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
| 2 | // ASIHTTPRequest.h | 2 | // ASIHTTPRequest.h |
| 3 | // | 3 | // |
| 4 | // Created by Ben Copsey on 04/10/2007. | 4 | // Created by Ben Copsey on 04/10/2007. |
| 5 | -// Copyright 2007-2008 All-Seeing Interactive. All rights reserved. | 5 | +// Copyright 2007-2009 All-Seeing Interactive. All rights reserved. |
| 6 | // | 6 | // |
| 7 | // A guide to the main features is available at: | 7 | // A guide to the main features is available at: |
| 8 | // http://allseeing-i.com/ASIHTTPRequest | 8 | // http://allseeing-i.com/ASIHTTPRequest |
| @@ -40,9 +40,26 @@ typedef enum _ASINetworkErrorType { | @@ -40,9 +40,26 @@ typedef enum _ASINetworkErrorType { | ||
| 40 | // HTTP method to use (GET / POST / PUT / DELETE). Defaults to GET | 40 | // HTTP method to use (GET / POST / PUT / DELETE). Defaults to GET |
| 41 | NSString *requestMethod; | 41 | NSString *requestMethod; |
| 42 | 42 | ||
| 43 | - // Request body | 43 | + // Request body - only used when the whole body is stored in memory (shouldStreamPostDataFromDisk is false) |
| 44 | NSMutableData *postBody; | 44 | NSMutableData *postBody; |
| 45 | 45 | ||
| 46 | + // When true, post body will be streamed from a file on disk, rather than loaded into memory at once (useful for large uploads) | ||
| 47 | + // Automatically set to true in ASIFormDataRequests when using setFile:forKey: | ||
| 48 | + BOOL shouldStreamPostDataFromDisk; | ||
| 49 | + | ||
| 50 | + // Path to file used to store post body (when shouldStreamPostDataFromDisk is true) | ||
| 51 | + // You can set this yourself - useful if you want to PUT a file from local disk | ||
| 52 | + NSString *postBodyFilePath; | ||
| 53 | + | ||
| 54 | + // Set to true when ASIHTTPRequest automatically created a temporary file containing the request body (when true, the file at postBodyFilePath will be deleted at the end of the request) | ||
| 55 | + BOOL didCreateTemporaryPostDataFile; | ||
| 56 | + | ||
| 57 | + // Used when writing to the post body when shouldStreamPostDataFromDisk is true (via appendPostData: or appendPostDataFromFile:) | ||
| 58 | + NSOutputStream *postBodyWriteStream; | ||
| 59 | + | ||
| 60 | + // Used for reading from the post body when sending the request | ||
| 61 | + NSInputStream *postBodyReadStream; | ||
| 62 | + | ||
| 46 | // Dictionary for custom HTTP request headers | 63 | // Dictionary for custom HTTP request headers |
| 47 | NSMutableDictionary *requestHeaders; | 64 | NSMutableDictionary *requestHeaders; |
| 48 | 65 | ||
| @@ -192,10 +209,7 @@ typedef enum _ASINetworkErrorType { | @@ -192,10 +209,7 @@ typedef enum _ASINetworkErrorType { | ||
| 192 | // Custom user information assosiated with the request | 209 | // Custom user information assosiated with the request |
| 193 | NSDictionary *userInfo; | 210 | NSDictionary *userInfo; |
| 194 | 211 | ||
| 195 | - NSString *postBodyFilePath; | 212 | + |
| 196 | - NSOutputStream *postBodyWriteStream; | ||
| 197 | - NSInputStream *postBodyReadStream; | ||
| 198 | - BOOL shouldStreamPostDataFromDisk; | ||
| 199 | } | 213 | } |
| 200 | 214 | ||
| 201 | #pragma mark init / dealloc | 215 | #pragma mark init / dealloc |
| @@ -210,6 +224,7 @@ typedef enum _ASINetworkErrorType { | @@ -210,6 +224,7 @@ typedef enum _ASINetworkErrorType { | ||
| 210 | 224 | ||
| 211 | - (void)buildPostBody; | 225 | - (void)buildPostBody; |
| 212 | 226 | ||
| 227 | +// Called to add data to the post body. Will append to postBody when shouldStreamPostDataFromDisk is false, or write to postBodyWriteStream when true | ||
| 213 | - (void)appendPostData:(NSData *)data; | 228 | - (void)appendPostData:(NSData *)data; |
| 214 | - (void)appendPostDataFromFile:(NSString *)file; | 229 | - (void)appendPostDataFromFile:(NSString *)file; |
| 215 | 230 | ||
| @@ -239,6 +254,10 @@ typedef enum _ASINetworkErrorType { | @@ -239,6 +254,10 @@ typedef enum _ASINetworkErrorType { | ||
| 239 | // No need to call this if the request succeeds - it is removed automatically | 254 | // No need to call this if the request succeeds - it is removed automatically |
| 240 | - (void)removeTemporaryDownloadFile; | 255 | - (void)removeTemporaryDownloadFile; |
| 241 | 256 | ||
| 257 | +// Call to remove the file used as the request body | ||
| 258 | +// No need to call this if the request succeeds and you didn't specify postBodyFilePath manually - it is removed automatically | ||
| 259 | +- (void)removePostDataFile; | ||
| 260 | + | ||
| 242 | #pragma mark upload/download progress | 261 | #pragma mark upload/download progress |
| 243 | 262 | ||
| 244 | // Called on main thread to update progress delegates | 263 | // Called on main thread to update progress delegates |
| @@ -371,4 +390,5 @@ typedef enum _ASINetworkErrorType { | @@ -371,4 +390,5 @@ typedef enum _ASINetworkErrorType { | ||
| 371 | @property (retain) NSOutputStream *postBodyWriteStream; | 390 | @property (retain) NSOutputStream *postBodyWriteStream; |
| 372 | @property (retain) NSInputStream *postBodyReadStream; | 391 | @property (retain) NSInputStream *postBodyReadStream; |
| 373 | @property (assign) BOOL shouldStreamPostDataFromDisk; | 392 | @property (assign) BOOL shouldStreamPostDataFromDisk; |
| 393 | +@property (assign) BOOL didCreateTemporaryPostDataFile; | ||
| 374 | @end | 394 | @end |
| @@ -56,6 +56,7 @@ static NSError *ASIUnableToCreateRequestError; | @@ -56,6 +56,7 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 56 | [super initialize]; | 56 | [super initialize]; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | + | ||
| 59 | - (id)initWithURL:(NSURL *)newURL | 60 | - (id)initWithURL:(NSURL *)newURL |
| 60 | { | 61 | { |
| 61 | self = [super init]; | 62 | self = [super init]; |
| @@ -76,6 +77,11 @@ static NSError *ASIUnableToCreateRequestError; | @@ -76,6 +77,11 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 76 | requestAuthentication = NULL; | 77 | requestAuthentication = NULL; |
| 77 | haveBuiltPostBody = NO; | 78 | haveBuiltPostBody = NO; |
| 78 | request = NULL; | 79 | request = NULL; |
| 80 | + [self setDidCreateTemporaryPostDataFile:NO]; | ||
| 81 | + [self setPostBodyFilePath:nil]; | ||
| 82 | + [self setPostBodyWriteStream:nil]; | ||
| 83 | + [self setPostBodyReadStream:nil]; | ||
| 84 | + [self setShouldStreamPostDataFromDisk:NO]; | ||
| 79 | [self setAllowCompressedResponse:YES]; | 85 | [self setAllowCompressedResponse:YES]; |
| 80 | [self setDefaultResponseEncoding:NSISOLatin1StringEncoding]; | 86 | [self setDefaultResponseEncoding:NSISOLatin1StringEncoding]; |
| 81 | [self setUploadBufferSize:0]; | 87 | [self setUploadBufferSize:0]; |
| @@ -130,6 +136,9 @@ static NSError *ASIUnableToCreateRequestError; | @@ -130,6 +136,9 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 130 | [requestMethod release]; | 136 | [requestMethod release]; |
| 131 | [cancelledLock release]; | 137 | [cancelledLock release]; |
| 132 | [authenticationMethod release]; | 138 | [authenticationMethod release]; |
| 139 | + [postBodyFilePath release]; | ||
| 140 | + [postBodyWriteStream release]; | ||
| 141 | + [postBodyReadStream release]; | ||
| 133 | [super dealloc]; | 142 | [super dealloc]; |
| 134 | } | 143 | } |
| 135 | 144 | ||
| @@ -145,34 +154,38 @@ static NSError *ASIUnableToCreateRequestError; | @@ -145,34 +154,38 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 145 | } | 154 | } |
| 146 | 155 | ||
| 147 | 156 | ||
| 148 | -// Subclasses should override this method if they need to create POST content for this request | ||
| 149 | // This function will be called either just before a request starts, or when postLength is needed, whichever comes first | 157 | // This function will be called either just before a request starts, or when postLength is needed, whichever comes first |
| 150 | -// postLength must be set by the time this function is complete - calling setPostBody: will do this for you | 158 | +// postLength must be set by the time this function is complete |
| 151 | - (void)buildPostBody | 159 | - (void)buildPostBody |
| 152 | { | 160 | { |
| 153 | - if ([self postBodyFilePath] && [self postBodyWriteStream]) { | 161 | + // Are we submitting the request body from a file on disk |
| 154 | - [[self postBodyWriteStream] close]; | 162 | + if ([self postBodyFilePath]) { |
| 155 | - [self setPostBodyWriteStream:nil]; | 163 | + |
| 156 | - [self setPostLength:[[[NSFileManager defaultManager] fileAttributesAtPath:[self postBodyFilePath] traverseLink:NO] fileSize]]; | 164 | + // If we were writing to the post body via appendPostData or appendPostDataFromFile, close the write tream |
| 157 | - [self addRequestHeader:@"Content-Length" value:[NSString stringWithFormat:@"%llu",postLength]]; | 165 | + if ([self postBodyWriteStream]) { |
| 158 | - if (postBody && postLength > 0 && ![requestMethod isEqualToString:@"POST"] && ![requestMethod isEqualToString:@"PUT"]) { | 166 | + [[self postBodyWriteStream] close]; |
| 159 | - [self setRequestMethod:@"POST"]; | 167 | + [self setPostBodyWriteStream:nil]; |
| 160 | } | 168 | } |
| 169 | + [self setPostLength:[[[NSFileManager defaultManager] fileAttributesAtPath:[self postBodyFilePath] traverseLink:NO] fileSize]]; | ||
| 170 | + | ||
| 171 | + // Otherwise, we have an in-memory request body | ||
| 161 | } else { | 172 | } else { |
| 162 | [self setPostLength:[postBody length]]; | 173 | [self setPostLength:[postBody length]]; |
| 163 | - [self addRequestHeader:@"Content-Length" value:[NSString stringWithFormat:@"%llu",postLength]]; | 174 | + } |
| 164 | - if (postBody && postLength > 0 && ![requestMethod isEqualToString:@"POST"] && ![requestMethod isEqualToString:@"PUT"]) { | 175 | + [self addRequestHeader:@"Content-Length" value:[NSString stringWithFormat:@"%llu",postLength]]; |
| 165 | - [self setRequestMethod:@"POST"]; | 176 | + if (postLength > 0 && ![requestMethod isEqualToString:@"POST"] && ![requestMethod isEqualToString:@"PUT"]) { |
| 166 | - } | 177 | + [self setRequestMethod:@"POST"]; |
| 167 | } | 178 | } |
| 168 | haveBuiltPostBody = YES; | 179 | haveBuiltPostBody = YES; |
| 169 | } | 180 | } |
| 170 | 181 | ||
| 182 | +// Sets up storage for the post body | ||
| 171 | - (void)setupPostBody | 183 | - (void)setupPostBody |
| 172 | { | 184 | { |
| 173 | if ([self shouldStreamPostDataFromDisk]) { | 185 | if ([self shouldStreamPostDataFromDisk]) { |
| 174 | if (![self postBodyFilePath]) { | 186 | if (![self postBodyFilePath]) { |
| 175 | [self setPostBodyFilePath:[NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]]; | 187 | [self setPostBodyFilePath:[NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]]; |
| 188 | + [self setDidCreateTemporaryPostDataFile:YES]; | ||
| 176 | } | 189 | } |
| 177 | if (![self postBodyWriteStream]) { | 190 | if (![self postBodyWriteStream]) { |
| 178 | [self setPostBodyWriteStream:[[[NSOutputStream alloc] initToFileAtPath:[self postBodyFilePath] append:NO] autorelease]]; | 191 | [self setPostBodyWriteStream:[[[NSOutputStream alloc] initToFileAtPath:[self postBodyFilePath] append:NO] autorelease]]; |
| @@ -234,7 +247,7 @@ static NSError *ASIUnableToCreateRequestError; | @@ -234,7 +247,7 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 234 | } | 247 | } |
| 235 | 248 | ||
| 236 | 249 | ||
| 237 | -// Call this method to get the received data as an NSString. Don't use for Binary data! | 250 | +// Call this method to get the received data as an NSString. Don't use for binary data! |
| 238 | - (NSString *)responseString | 251 | - (NSString *)responseString |
| 239 | { | 252 | { |
| 240 | NSData *data = [self responseData]; | 253 | NSData *data = [self responseData]; |
| @@ -341,7 +354,7 @@ static NSError *ASIUnableToCreateRequestError; | @@ -341,7 +354,7 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 341 | // Add custom headers | 354 | // Add custom headers |
| 342 | NSDictionary *headers; | 355 | NSDictionary *headers; |
| 343 | 356 | ||
| 344 | - //Add headers from the main request if this is a HEAD request generated by an ASINetwork Queue | 357 | + //Add headers from the main request if this is a HEAD request generated by an ASINetworkQueue |
| 345 | if ([self mainRequest]) { | 358 | if ([self mainRequest]) { |
| 346 | headers = [mainRequest requestHeaders]; | 359 | headers = [mainRequest requestHeaders]; |
| 347 | } else { | 360 | } else { |
| @@ -440,14 +453,11 @@ static NSError *ASIUnableToCreateRequestError; | @@ -440,14 +453,11 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 440 | } | 453 | } |
| 441 | } | 454 | } |
| 442 | 455 | ||
| 443 | -// Start the request | 456 | +// This is the 'main loop' for the request. Basically, it runs the runloop that our network stuff is attached to, and checks to see if we should cancel or timeout |
| 444 | - (void)loadRequest | 457 | - (void)loadRequest |
| 445 | { | 458 | { |
| 446 | - | ||
| 447 | - | ||
| 448 | [self startRequest]; | 459 | [self startRequest]; |
| 449 | 460 | ||
| 450 | - | ||
| 451 | // Record when the request started, so we can timeout if nothing happens | 461 | // Record when the request started, so we can timeout if nothing happens |
| 452 | [self setLastActivityTime:[NSDate date]]; | 462 | [self setLastActivityTime:[NSDate date]]; |
| 453 | 463 | ||
| @@ -523,6 +533,11 @@ static NSError *ASIUnableToCreateRequestError; | @@ -523,6 +533,11 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 523 | } | 533 | } |
| 524 | } | 534 | } |
| 525 | 535 | ||
| 536 | + // Clean up any temporary file used to store request body for streaming | ||
| 537 | + if ([self didCreateTemporaryPostDataFile]) { | ||
| 538 | + [self removePostDataFile]; | ||
| 539 | + } | ||
| 540 | + | ||
| 526 | [self setResponseHeaders:nil]; | 541 | [self setResponseHeaders:nil]; |
| 527 | [cancelledLock unlock]; | 542 | [cancelledLock unlock]; |
| 528 | } | 543 | } |
| @@ -538,6 +553,15 @@ static NSError *ASIUnableToCreateRequestError; | @@ -538,6 +553,15 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 538 | } | 553 | } |
| 539 | } | 554 | } |
| 540 | 555 | ||
| 556 | +- (void)removePostDataFile | ||
| 557 | +{ | ||
| 558 | + NSError *removeError = nil; | ||
| 559 | + [[NSFileManager defaultManager] removeItemAtPath:postBodyFilePath error:&removeError]; | ||
| 560 | + if (removeError) { | ||
| 561 | + [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIFileManagementError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Failed to delete file at %@ with error: %@",postBodyFilePath,removeError],NSLocalizedDescriptionKey,removeError,NSUnderlyingErrorKey,nil]]]; | ||
| 562 | + } | ||
| 563 | +} | ||
| 564 | + | ||
| 541 | 565 | ||
| 542 | #pragma mark upload/download progress | 566 | #pragma mark upload/download progress |
| 543 | 567 | ||
| @@ -618,6 +642,7 @@ static NSError *ASIUnableToCreateRequestError; | @@ -618,6 +642,7 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 618 | } | 642 | } |
| 619 | 643 | ||
| 620 | // If this is the first time we've written to the buffer, byteCount will be the size of the buffer (currently seems to be 128KB on both Mac and iPhone) | 644 | // If this is the first time we've written to the buffer, byteCount will be the size of the buffer (currently seems to be 128KB on both Mac and iPhone) |
| 645 | + // If request body is less than 128KB, byteCount will be the total size of the request body | ||
| 621 | // We will remove this from any progress display, as kCFStreamPropertyHTTPRequestBytesWrittenCount does not tell us how much data has actually be written | 646 | // We will remove this from any progress display, as kCFStreamPropertyHTTPRequestBytesWrittenCount does not tell us how much data has actually be written |
| 622 | if (totalBytesSent > 0 && uploadBufferSize == 0 && totalBytesSent != postLength) { | 647 | if (totalBytesSent > 0 && uploadBufferSize == 0 && totalBytesSent != postLength) { |
| 623 | [self setUploadBufferSize:totalBytesSent]; | 648 | [self setUploadBufferSize:totalBytesSent]; |
| @@ -637,6 +662,10 @@ static NSError *ASIUnableToCreateRequestError; | @@ -637,6 +662,10 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 637 | 662 | ||
| 638 | [cancelledLock unlock]; | 663 | [cancelledLock unlock]; |
| 639 | 664 | ||
| 665 | + if (totalBytesSent == 0) { | ||
| 666 | + return; | ||
| 667 | + } | ||
| 668 | + | ||
| 640 | 669 | ||
| 641 | if (uploadProgressDelegate) { | 670 | if (uploadProgressDelegate) { |
| 642 | 671 | ||
| @@ -1222,6 +1251,11 @@ static NSError *ASIUnableToCreateRequestError; | @@ -1222,6 +1251,11 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 1222 | 1251 | ||
| 1223 | NSError *fileError = nil; | 1252 | NSError *fileError = nil; |
| 1224 | 1253 | ||
| 1254 | + // Delete up the request body temporary file, if it exists | ||
| 1255 | + if (didCreateTemporaryPostDataFile) { | ||
| 1256 | + [self removePostDataFile]; | ||
| 1257 | + } | ||
| 1258 | + | ||
| 1225 | // Close the output stream as we're done writing to the file | 1259 | // Close the output stream as we're done writing to the file |
| 1226 | if (temporaryFileDownloadPath) { | 1260 | if (temporaryFileDownloadPath) { |
| 1227 | [outputStream close]; | 1261 | [outputStream close]; |
| @@ -1547,4 +1581,5 @@ static NSError *ASIUnableToCreateRequestError; | @@ -1547,4 +1581,5 @@ static NSError *ASIUnableToCreateRequestError; | ||
| 1547 | @synthesize postBodyWriteStream; | 1581 | @synthesize postBodyWriteStream; |
| 1548 | @synthesize postBodyReadStream; | 1582 | @synthesize postBodyReadStream; |
| 1549 | @synthesize shouldStreamPostDataFromDisk; | 1583 | @synthesize shouldStreamPostDataFromDisk; |
| 1584 | +@synthesize didCreateTemporaryPostDataFile; | ||
| 1550 | @end | 1585 | @end |
| @@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
| 3 | // asi-http-request | 3 | // asi-http-request |
| 4 | // | 4 | // |
| 5 | // Created by Ben Copsey on 07/11/2008. | 5 | // Created by Ben Copsey on 07/11/2008. |
| 6 | -// Copyright 2008 All-Seeing Interactive. All rights reserved. | 6 | +// Copyright 2008-2009 All-Seeing Interactive. All rights reserved. |
| 7 | // | 7 | // |
| 8 | 8 | ||
| 9 | 9 |
| @@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
| 3 | // asi-http-request | 3 | // asi-http-request |
| 4 | // | 4 | // |
| 5 | // Created by Ben Copsey on 07/11/2008. | 5 | // Created by Ben Copsey on 07/11/2008. |
| 6 | -// Copyright 2008 All-Seeing Interactive. All rights reserved. | 6 | +// Copyright 2008-2009 All-Seeing Interactive. All rights reserved. |
| 7 | // | 7 | // |
| 8 | 8 | ||
| 9 | #import "ASINetworkQueue.h" | 9 | #import "ASINetworkQueue.h" |
| @@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | @implementation ASIHTTPRequestTests | 15 | @implementation ASIHTTPRequestTests |
| 16 | - | 16 | +/* |
| 17 | 17 | ||
| 18 | - (void)testBasicDownload | 18 | - (void)testBasicDownload |
| 19 | { | 19 | { |
| @@ -188,6 +188,8 @@ | @@ -188,6 +188,8 @@ | ||
| 188 | GHAssertTrue(success,@"Failed to properly increment download progress %f != 1.0",progress); | 188 | GHAssertTrue(success,@"Failed to properly increment download progress %f != 1.0",progress); |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | +*/ | ||
| 192 | + | ||
| 191 | 193 | ||
| 192 | - (void)setProgress:(float)newProgress; | 194 | - (void)setProgress:(float)newProgress; |
| 193 | { | 195 | { |
| @@ -207,7 +209,49 @@ | @@ -207,7 +209,49 @@ | ||
| 207 | GHAssertTrue(success,@"Failed to properly increment upload progress %f != 1.0",progress); | 209 | GHAssertTrue(success,@"Failed to properly increment upload progress %f != 1.0",progress); |
| 208 | } | 210 | } |
| 209 | 211 | ||
| 212 | +- (void)testPostBodyStreamedFromDisk | ||
| 213 | +{ | ||
| 214 | + NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ignore"]; | ||
| 215 | + NSString *requestContentPath = [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"testfile.txt"]; | ||
| 216 | + [[NSMutableData dataWithLength:1024*32] writeToFile:requestContentPath atomically:NO]; | ||
| 217 | + | ||
| 218 | + // Test using a user-specified file as the request body (useful for PUT) | ||
| 219 | + progress = 0; | ||
| 220 | + ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | ||
| 221 | + [request setRequestMethod:@"PUT"]; | ||
| 222 | + [request setShouldStreamPostDataFromDisk:YES]; | ||
| 223 | + [request setUploadProgressDelegate:self]; | ||
| 224 | + [request setPostBodyFilePath:requestContentPath]; | ||
| 225 | + //[request start]; | ||
| 226 | + | ||
| 227 | + | ||
| 228 | + //Wait for 1 second | ||
| 229 | + //[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; | ||
| 230 | + | ||
| 231 | + BOOL success = (progress > 0.95); | ||
| 232 | + //GHAssertTrue(success,@"Failed to properly increment upload progress %f != 1.0",progress); | ||
| 233 | + | ||
| 234 | + | ||
| 235 | + // Test building a request body by appending data | ||
| 236 | + progress = 0; | ||
| 237 | + request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | ||
| 238 | + [request setShouldStreamPostDataFromDisk:YES]; | ||
| 239 | + [request setUploadProgressDelegate:self]; | ||
| 240 | + | ||
| 241 | + NSData *d = [@"Below this will be the file I am posting:\r\n" dataUsingEncoding:NSUTF8StringEncoding]; | ||
| 242 | + [request appendPostData:[NSData dataWithBytes:[d bytes] length:[d length]]]; | ||
| 243 | + [request appendPostDataFromFile:requestContentPath]; | ||
| 244 | + [request start]; | ||
| 245 | + | ||
| 246 | + | ||
| 247 | + //Wait for 1 second | ||
| 248 | + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; | ||
| 249 | + | ||
| 250 | + success = (progress > 0.95); | ||
| 251 | + GHAssertTrue(success,@"Failed to properly increment upload progress %f != 1.0",progress); | ||
| 252 | +} | ||
| 210 | 253 | ||
| 254 | +/* | ||
| 211 | 255 | ||
| 212 | 256 | ||
| 213 | - (void)testCookies | 257 | - (void)testCookies |
| @@ -530,6 +574,6 @@ | @@ -530,6 +574,6 @@ | ||
| 530 | success = success = (progress > 0.95); | 574 | success = success = (progress > 0.95); |
| 531 | GHAssertTrue(success,@"Failed to correctly display increment progress for a partial download"); | 575 | GHAssertTrue(success,@"Failed to correctly display increment progress for a partial download"); |
| 532 | } | 576 | } |
| 533 | - | 577 | +*/ |
| 534 | 578 | ||
| 535 | @end | 579 | @end |
-
Please register or login to post a comment