This commit is contained in:
parent
70b7e0522c
commit
1c1b204513
2 changed files with 36 additions and 2 deletions
|
|
@ -501,6 +501,9 @@ extern NSString * const AFNetworkingReachabilityNotificationStatusItem;
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
||||||
|
extern NSUInteger const kAFUploadStream3GSuggestedPacketSize;
|
||||||
|
extern NSUInteger const kAFUploadStream3GSuggestedDelay;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The `AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `AFHTTPClient -multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:`.
|
The `AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `AFHTTPClient -multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:`.
|
||||||
*/
|
*/
|
||||||
|
|
@ -544,4 +547,15 @@ extern NSString * const AFNetworkingReachabilityNotificationStatusItem;
|
||||||
- (void)appendPartWithFormData:(NSData *)data
|
- (void)appendPartWithFormData:(NSData *)data
|
||||||
name:(NSString *)name;
|
name:(NSString *)name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Throttles request bandwidth by limiting the packet size and adding a delay for each chunk read from the upload stream.
|
||||||
|
|
||||||
|
@param numberOfBytes Maximum packet size, in number of bytes. The default packet size for an input stream is 32kb.
|
||||||
|
@param delay Duration of delay each time a packet is read. By default, no delay is set.
|
||||||
|
|
||||||
|
@discussion When uploading over a 3G or EDGE connection, requests may fail with "request body stream exhausted". Setting a maximum packet size and delay according to the recommended values (`kAFUploadStream3GSuggestedPacketSize` and `kAFUploadStream3GSuggestedDelay`) lowers the risk of the input stream exceeding its allocated bandwidth. Unfortunately, as of iOS 6, there is no definite way to distinguish between a 3G, EDGE, or LTE connection. As such, it is not recommended that you throttle bandwidth based solely on network reachability. Instead, you should consider checking for the "request body stream exhausted" in a failure block, and then retrying the request with throttled bandwidth.
|
||||||
|
*/
|
||||||
|
- (void)throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes
|
||||||
|
delay:(NSTimeInterval)delay;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
||||||
|
|
@ -708,6 +708,9 @@ static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSUInteger const kAFUploadStream3GSuggestedPacketSize = 1024 * 16;
|
||||||
|
NSUInteger const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||||
|
|
||||||
@interface AFHTTPBodyPart : NSObject
|
@interface AFHTTPBodyPart : NSObject
|
||||||
|
|
||||||
@property (nonatomic, assign) NSStringEncoding stringEncoding;
|
@property (nonatomic, assign) NSStringEncoding stringEncoding;
|
||||||
|
|
@ -727,6 +730,8 @@ static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
|
||||||
|
|
||||||
@interface AFMultipartBodyStream : NSInputStream <NSStreamDelegate>
|
@interface AFMultipartBodyStream : NSInputStream <NSStreamDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, assign) NSUInteger numberOfBytesInPacket;
|
||||||
|
@property (nonatomic, assign) NSTimeInterval delay;
|
||||||
@property (readonly) unsigned long long contentLength;
|
@property (readonly) unsigned long long contentLength;
|
||||||
@property (readonly, getter = isEmpty) BOOL empty;
|
@property (readonly, getter = isEmpty) BOOL empty;
|
||||||
|
|
||||||
|
|
@ -834,6 +839,13 @@ static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
|
||||||
[self.bodyStream appendHTTPBodyPart:bodyPart];
|
[self.bodyStream appendHTTPBodyPart:bodyPart];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes
|
||||||
|
delay:(NSTimeInterval)delay
|
||||||
|
{
|
||||||
|
self.bodyStream.numberOfBytesInPacket = numberOfBytes;
|
||||||
|
self.bodyStream.delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSMutableURLRequest *)requestByFinalizingMultipartFormData {
|
- (NSMutableURLRequest *)requestByFinalizingMultipartFormData {
|
||||||
if ([self.bodyStream isEmpty]) {
|
if ([self.bodyStream isEmpty]) {
|
||||||
return self.request;
|
return self.request;
|
||||||
|
|
@ -861,6 +873,8 @@ static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
|
||||||
@property (nonatomic, retain) NSMutableArray *HTTPBodyParts;
|
@property (nonatomic, retain) NSMutableArray *HTTPBodyParts;
|
||||||
@property (nonatomic, retain) NSEnumerator *HTTPBodyPartEnumerator;
|
@property (nonatomic, retain) NSEnumerator *HTTPBodyPartEnumerator;
|
||||||
@property (nonatomic, retain) AFHTTPBodyPart *currentHTTPBodyPart;
|
@property (nonatomic, retain) AFHTTPBodyPart *currentHTTPBodyPart;
|
||||||
|
@property (nonatomic, retain) NSDate *lastReadAt;
|
||||||
|
@property (nonatomic, assign) NSInteger lastBytesRead;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation AFMultipartBodyStream
|
@implementation AFMultipartBodyStream
|
||||||
|
|
@ -870,6 +884,8 @@ static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
|
||||||
@synthesize HTTPBodyParts = _HTTPBodyParts;
|
@synthesize HTTPBodyParts = _HTTPBodyParts;
|
||||||
@synthesize HTTPBodyPartEnumerator = _HTTPBodyPartEnumerator;
|
@synthesize HTTPBodyPartEnumerator = _HTTPBodyPartEnumerator;
|
||||||
@synthesize currentHTTPBodyPart = _currentHTTPBodyPart;
|
@synthesize currentHTTPBodyPart = _currentHTTPBodyPart;
|
||||||
|
@synthesize numberOfBytesInPacket = _numberOfBytesInPacket;
|
||||||
|
@synthesize delay = _delay;
|
||||||
|
|
||||||
- (id)initWithStringEncoding:(NSStringEncoding)encoding {
|
- (id)initWithStringEncoding:(NSStringEncoding)encoding {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
@ -879,6 +895,7 @@ static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
|
||||||
|
|
||||||
self.stringEncoding = encoding;
|
self.stringEncoding = encoding;
|
||||||
self.HTTPBodyParts = [NSMutableArray array];
|
self.HTTPBodyParts = [NSMutableArray array];
|
||||||
|
self.numberOfBytesInPacket = NSIntegerMax;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
@ -912,16 +929,19 @@ static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
|
||||||
|
|
||||||
NSInteger bytesRead = 0;
|
NSInteger bytesRead = 0;
|
||||||
|
|
||||||
while ((NSUInteger)bytesRead < length) {
|
while ((NSUInteger)bytesRead < MIN(length, self.numberOfBytesInPacket)) {
|
||||||
if (!self.currentHTTPBodyPart || ![self.currentHTTPBodyPart hasBytesAvailable]) {
|
if (!self.currentHTTPBodyPart || ![self.currentHTTPBodyPart hasBytesAvailable]) {
|
||||||
if (!(self.currentHTTPBodyPart = [self.HTTPBodyPartEnumerator nextObject])) {
|
if (!(self.currentHTTPBodyPart = [self.HTTPBodyPartEnumerator nextObject])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bytesRead += [self.currentHTTPBodyPart read:&buffer[bytesRead] maxLength:length - bytesRead];
|
bytesRead += [self.currentHTTPBodyPart read:&buffer[bytesRead] maxLength:length - bytesRead];
|
||||||
|
if (self.delay > 0.0f) {
|
||||||
|
[NSThread sleepForTimeInterval:self.delay];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue