Showing
5 changed files
with
31 additions
and
22 deletions
| @@ -455,10 +455,10 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -455,10 +455,10 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
| 455 | // Only works on Mac OS, will always return 'application/octet-stream' on iPhone | 455 | // Only works on Mac OS, will always return 'application/octet-stream' on iPhone |
| 456 | + (NSString *)mimeTypeForFileAtPath:(NSString *)path; | 456 | + (NSString *)mimeTypeForFileAtPath:(NSString *)path; |
| 457 | 457 | ||
| 458 | -#pragma mark bandwidth throttling | 458 | +#pragma mark bandwidth measurement / throttling |
| 459 | 459 | ||
| 460 | // The maximum number of bytes ALL requests can send / receive in a second | 460 | // The maximum number of bytes ALL requests can send / receive in a second |
| 461 | -// This is a rough figure. The actual amount used may be slightly more | 461 | +// This is a rough figure. The actual amount used will be slightly more, this does not include HTTP headers |
| 462 | + (unsigned long)maxBandwidthPerSecond; | 462 | + (unsigned long)maxBandwidthPerSecond; |
| 463 | + (void)setMaxBandwidthPerSecond:(unsigned long)bytes; | 463 | + (void)setMaxBandwidthPerSecond:(unsigned long)bytes; |
| 464 | 464 |
| @@ -265,7 +265,7 @@ BOOL shouldThrottleBandwidth = NO; | @@ -265,7 +265,7 @@ BOOL shouldThrottleBandwidth = NO; | ||
| 265 | if (![requestMethod isEqualToString:@"POST"] && ![requestMethod isEqualToString:@"PUT"]) { | 265 | if (![requestMethod isEqualToString:@"POST"] && ![requestMethod isEqualToString:@"PUT"]) { |
| 266 | [self setRequestMethod:@"POST"]; | 266 | [self setRequestMethod:@"POST"]; |
| 267 | } | 267 | } |
| 268 | - //[self addRequestHeader:@"Content-Length" value:[NSString stringWithFormat:@"%llu",[self postLength]]]; | 268 | + [self addRequestHeader:@"Content-Length" value:[NSString stringWithFormat:@"%llu",[self postLength]]]; |
| 269 | } | 269 | } |
| 270 | [self setHaveBuiltPostBody:YES]; | 270 | [self setHaveBuiltPostBody:YES]; |
| 271 | } | 271 | } |
| @@ -525,7 +525,9 @@ BOOL shouldThrottleBandwidth = NO; | @@ -525,7 +525,9 @@ BOOL shouldThrottleBandwidth = NO; | ||
| 525 | if (![self downloadDestinationPath]) { | 525 | if (![self downloadDestinationPath]) { |
| 526 | [self setRawResponseData:[[[NSMutableData alloc] init] autorelease]]; | 526 | [self setRawResponseData:[[[NSMutableData alloc] init] autorelease]]; |
| 527 | } | 527 | } |
| 528 | - // Create the stream for the request. | 528 | + // Create the stream for the request |
| 529 | + | ||
| 530 | + // Do we need to stream the request body from disk | ||
| 529 | if ([self shouldStreamPostDataFromDisk] && [self postBodyFilePath] && [[NSFileManager defaultManager] fileExistsAtPath:[self postBodyFilePath]]) { | 531 | if ([self shouldStreamPostDataFromDisk] && [self postBodyFilePath] && [[NSFileManager defaultManager] fileExistsAtPath:[self postBodyFilePath]]) { |
| 530 | 532 | ||
| 531 | // Are we gzipping the request body? | 533 | // Are we gzipping the request body? |
| @@ -536,7 +538,14 @@ BOOL shouldThrottleBandwidth = NO; | @@ -536,7 +538,14 @@ BOOL shouldThrottleBandwidth = NO; | ||
| 536 | } | 538 | } |
| 537 | readStream = CFReadStreamCreateForStreamedHTTPRequest(kCFAllocatorDefault, request,(CFReadStreamRef)[self postBodyReadStream]); | 539 | readStream = CFReadStreamCreateForStreamedHTTPRequest(kCFAllocatorDefault, request,(CFReadStreamRef)[self postBodyReadStream]); |
| 538 | } else { | 540 | } else { |
| 539 | - readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request); | 541 | + // If we have a request body, we'll stream it from memory using our custom stream, so that it can be bandwidth-throttled if nescessary |
| 542 | + if ([self postBody]) { | ||
| 543 | + [self setPostBodyReadStream:[ASIInputStream inputStreamWithData:[self postBody]]]; | ||
| 544 | + readStream = CFReadStreamCreateForStreamedHTTPRequest(kCFAllocatorDefault, request,(CFReadStreamRef)[self postBodyReadStream]); | ||
| 545 | + | ||
| 546 | + } else { | ||
| 547 | + readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request); | ||
| 548 | + } | ||
| 540 | } | 549 | } |
| 541 | if (!readStream) { | 550 | if (!readStream) { |
| 542 | [[self cancelledLock] unlock]; | 551 | [[self cancelledLock] unlock]; |
| @@ -659,8 +668,6 @@ BOOL shouldThrottleBandwidth = NO; | @@ -659,8 +668,6 @@ BOOL shouldThrottleBandwidth = NO; | ||
| 659 | 668 | ||
| 660 | NSDate *now = [NSDate date]; | 669 | NSDate *now = [NSDate date]; |
| 661 | 670 | ||
| 662 | - //NSLog(@"loop"); | ||
| 663 | - | ||
| 664 | // See if we need to timeout | 671 | // See if we need to timeout |
| 665 | if (lastActivityTime && timeOutSeconds > 0 && [now timeIntervalSinceDate:lastActivityTime] > timeOutSeconds) { | 672 | if (lastActivityTime && timeOutSeconds > 0 && [now timeIntervalSinceDate:lastActivityTime] > timeOutSeconds) { |
| 666 | 673 | ||
| @@ -698,9 +705,6 @@ BOOL shouldThrottleBandwidth = NO; | @@ -698,9 +705,6 @@ BOOL shouldThrottleBandwidth = NO; | ||
| 698 | 705 | ||
| 699 | // Find out if we've sent any more data than last time, and reset the timeout if so | 706 | // Find out if we've sent any more data than last time, and reset the timeout if so |
| 700 | if (totalBytesSent > lastBytesSent) { | 707 | if (totalBytesSent > lastBytesSent) { |
| 701 | - | ||
| 702 | -// // For bandwidth measurement / throttling | ||
| 703 | -// [ASIHTTPRequest incrementBandwidthUsedInLastSecond:(totalBytesSent-lastBytesSent)]; | ||
| 704 | [self setLastActivityTime:[NSDate date]]; | 708 | [self setLastActivityTime:[NSDate date]]; |
| 705 | [self setLastBytesSent:totalBytesSent]; | 709 | [self setLastBytesSent:totalBytesSent]; |
| 706 | } | 710 | } |
| @@ -2313,7 +2317,7 @@ BOOL shouldThrottleBandwidth = NO; | @@ -2313,7 +2317,7 @@ BOOL shouldThrottleBandwidth = NO; | ||
| 2313 | #endif | 2317 | #endif |
| 2314 | } | 2318 | } |
| 2315 | 2319 | ||
| 2316 | -#pragma mark bandwidth throttling | 2320 | +#pragma mark bandwidth measurement / throttling |
| 2317 | 2321 | ||
| 2318 | + (BOOL)shouldThrottleBandwidth | 2322 | + (BOOL)shouldThrottleBandwidth |
| 2319 | { | 2323 | { |
| @@ -2355,7 +2359,6 @@ BOOL shouldThrottleBandwidth = NO; | @@ -2355,7 +2359,6 @@ BOOL shouldThrottleBandwidth = NO; | ||
| 2355 | 2359 | ||
| 2356 | + (void)recordBandwidthUsage | 2360 | + (void)recordBandwidthUsage |
| 2357 | { | 2361 | { |
| 2358 | - //NSLog(@"--Mark-- %lu",bandwidthUsedInLastSecond); | ||
| 2359 | if (bandwidthUsedInLastSecond == 0) { | 2362 | if (bandwidthUsedInLastSecond == 0) { |
| 2360 | [bandwidthUsageTracker removeAllObjects]; | 2363 | [bandwidthUsageTracker removeAllObjects]; |
| 2361 | } else { | 2364 | } else { |
| @@ -2382,9 +2385,9 @@ BOOL shouldThrottleBandwidth = NO; | @@ -2382,9 +2385,9 @@ BOOL shouldThrottleBandwidth = NO; | ||
| 2382 | { | 2385 | { |
| 2383 | [bandwidthThrottlingLock lock]; | 2386 | [bandwidthThrottlingLock lock]; |
| 2384 | 2387 | ||
| 2385 | -// if (!bandwidthMeasurementDate || [bandwidthMeasurementDate timeIntervalSinceNow] < 0) { | 2388 | + if (!bandwidthMeasurementDate || [bandwidthMeasurementDate timeIntervalSinceNow] < 0) { |
| 2386 | -// [self recordBandwidthUsage]; | 2389 | + [self recordBandwidthUsage]; |
| 2387 | -// } | 2390 | + } |
| 2388 | unsigned long amount = averageBandwidthUsedPerSecond; | 2391 | unsigned long amount = averageBandwidthUsedPerSecond; |
| 2389 | [bandwidthThrottlingLock unlock]; | 2392 | [bandwidthThrottlingLock unlock]; |
| 2390 | return amount; | 2393 | return amount; |
| @@ -2403,9 +2406,7 @@ BOOL shouldThrottleBandwidth = NO; | @@ -2403,9 +2406,7 @@ BOOL shouldThrottleBandwidth = NO; | ||
| 2403 | if (maxBandwidthPerSecond > 0) { | 2406 | if (maxBandwidthPerSecond > 0) { |
| 2404 | // How much data can we still send or receive this second? | 2407 | // How much data can we still send or receive this second? |
| 2405 | long long bytesRemaining = (long long)maxBandwidthPerSecond - (long long)bandwidthUsedInLastSecond; | 2408 | long long bytesRemaining = (long long)maxBandwidthPerSecond - (long long)bandwidthUsedInLastSecond; |
| 2406 | - | 2409 | + |
| 2407 | - //NSLog(@"%qi",bytesRemaining); | ||
| 2408 | - | ||
| 2409 | // Have we used up our allowance? | 2410 | // Have we used up our allowance? |
| 2410 | if (bytesRemaining < 8) { | 2411 | if (bytesRemaining < 8) { |
| 2411 | 2412 | ||
| @@ -2458,7 +2459,6 @@ BOOL shouldThrottleBandwidth = NO; | @@ -2458,7 +2459,6 @@ BOOL shouldThrottleBandwidth = NO; | ||
| 2458 | if (maxBandwidthPerSecond) { | 2459 | if (maxBandwidthPerSecond) { |
| 2459 | toRead = maxBandwidthPerSecond/32; | 2460 | toRead = maxBandwidthPerSecond/32; |
| 2460 | } | 2461 | } |
| 2461 | - //NSLog(@"max: %lu used: %lu",maxBandwidthPerSecond,bandwidthUsedInLastSecond); | ||
| 2462 | if (maxBandwidthPerSecond > 0 && (bandwidthUsedInLastSecond + toRead > maxBandwidthPerSecond)) { | 2462 | if (maxBandwidthPerSecond > 0 && (bandwidthUsedInLastSecond + toRead > maxBandwidthPerSecond)) { |
| 2463 | toRead = 0; | 2463 | toRead = 0; |
| 2464 | } | 2464 | } |
| @@ -8,11 +8,14 @@ | @@ -8,11 +8,14 @@ | ||
| 8 | 8 | ||
| 9 | #import <Foundation/Foundation.h> | 9 | #import <Foundation/Foundation.h> |
| 10 | 10 | ||
| 11 | +// This is a wrapper for NSInputStream that pretends to be an NSInputStream itself | ||
| 12 | +// Subclassing NSInputStream seems to be tricky, and may involve overriding undocumented methods, so we'll cheat instead. | ||
| 11 | 13 | ||
| 12 | @interface ASIInputStream : NSObject { | 14 | @interface ASIInputStream : NSObject { |
| 13 | NSInputStream *stream; | 15 | NSInputStream *stream; |
| 14 | } | 16 | } |
| 15 | + (id)inputStreamWithFileAtPath:(NSString *)path; | 17 | + (id)inputStreamWithFileAtPath:(NSString *)path; |
| 18 | ++ (id)inputStreamWithData:(NSData *)data; | ||
| 16 | 19 | ||
| 17 | @property (retain) NSInputStream *stream; | 20 | @property (retain) NSInputStream *stream; |
| 18 | @end | 21 | @end |
| @@ -9,9 +9,6 @@ | @@ -9,9 +9,6 @@ | ||
| 9 | #import "ASIInputStream.h" | 9 | #import "ASIInputStream.h" |
| 10 | #import "ASIHTTPRequest.h" | 10 | #import "ASIHTTPRequest.h" |
| 11 | 11 | ||
| 12 | -// This is a wrapper for NSInputStream that pretends to be an NSInputStream itself | ||
| 13 | -// Subclassing NSInputStream seems to be tricky, and may involve overriding undocumented methods, so we'll cheat instead. | ||
| 14 | - | ||
| 15 | @implementation ASIInputStream | 12 | @implementation ASIInputStream |
| 16 | 13 | ||
| 17 | + (id)inputStreamWithFileAtPath:(NSString *)path | 14 | + (id)inputStreamWithFileAtPath:(NSString *)path |
| @@ -21,6 +18,13 @@ | @@ -21,6 +18,13 @@ | ||
| 21 | return stream; | 18 | return stream; |
| 22 | } | 19 | } |
| 23 | 20 | ||
| 21 | ++ (id)inputStreamWithData:(NSData *)data | ||
| 22 | +{ | ||
| 23 | + ASIInputStream *stream = [[[self alloc] init] autorelease]; | ||
| 24 | + [stream setStream:[NSInputStream inputStreamWithData:data]]; | ||
| 25 | + return stream; | ||
| 26 | +} | ||
| 27 | + | ||
| 24 | - (void)dealloc | 28 | - (void)dealloc |
| 25 | { | 29 | { |
| 26 | [stream release]; | 30 | [stream release]; |
| @@ -30,8 +34,10 @@ | @@ -30,8 +34,10 @@ | ||
| 30 | - (BOOL)hasBytesAvailable | 34 | - (BOOL)hasBytesAvailable |
| 31 | { | 35 | { |
| 32 | if ([ASIHTTPRequest maxUploadReadLength] == 0) { | 36 | if ([ASIHTTPRequest maxUploadReadLength] == 0) { |
| 37 | + NSLog(@"no"); | ||
| 33 | return NO; | 38 | return NO; |
| 34 | } | 39 | } |
| 40 | + NSLog(@"yes"); | ||
| 35 | return [[self stream] hasBytesAvailable]; | 41 | return [[self stream] hasBytesAvailable]; |
| 36 | 42 | ||
| 37 | } | 43 | } |
This diff was suppressed by a .gitattributes entry.
-
Please register or login to post a comment