Issue: Timeout when buffer ends during ending boundry

This commit is contained in:
Tomohisa Takaoka 2012-11-09 14:23:51 -08:00
parent 247863cfc2
commit c92f306c6d

View file

@ -28,15 +28,15 @@
#import <Availability.h> #import <Availability.h>
#ifdef _SYSTEMCONFIGURATION_H #ifdef _SYSTEMCONFIGURATION_H
#import <netinet/in.h> #import <netinet/in.h>
#import <netinet6/in6.h> #import <netinet6/in6.h>
#import <arpa/inet.h> #import <arpa/inet.h>
#import <ifaddrs.h> #import <ifaddrs.h>
#import <netdb.h> #import <netdb.h>
#endif #endif
#if __IPHONE_OS_VERSION_MIN_REQUIRED #if __IPHONE_OS_VERSION_MIN_REQUIRED
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#endif #endif
#ifdef _SYSTEMCONFIGURATION_H #ifdef _SYSTEMCONFIGURATION_H
@ -107,7 +107,7 @@ static NSString * AFPercentEscapedQueryStringPairMemberFromStringWithEncoding(NS
if (!self) { if (!self) {
return nil; return nil;
} }
self.field = field; self.field = field;
self.value = value; self.value = value;
@ -146,7 +146,7 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) {
NSMutableArray *mutableQueryStringComponents = [NSMutableArray array]; NSMutableArray *mutableQueryStringComponents = [NSMutableArray array];
if([value isKindOfClass:[NSDictionary class]]) { if([value isKindOfClass:[NSDictionary class]]) {
// Sort dictionary keys to ensure consistent ordering in query string, which is important when deserializing potentially ambiguous sequences, such as an array of dictionaries // Sort dictionary keys to ensure consistent ordering in query string, which is important when deserializing potentially ambiguous sequences, such as an array of dictionaries
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES selector:@selector(caseInsensitiveCompare:)]; NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES selector:@selector(caseInsensitiveCompare:)];
[[[value allKeys] sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]] enumerateObjectsUsingBlock:^(id nestedKey, NSUInteger idx, BOOL *stop) { [[[value allKeys] sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]] enumerateObjectsUsingBlock:^(id nestedKey, NSUInteger idx, BOOL *stop) {
id nestedValue = [value objectForKey:nestedKey]; id nestedValue = [value objectForKey:nestedKey];
@ -210,7 +210,7 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) {
- (id)initWithBaseURL:(NSURL *)url { - (id)initWithBaseURL:(NSURL *)url {
NSParameterAssert(url); NSParameterAssert(url);
self = [super init]; self = [super init];
if (!self) { if (!self) {
return nil; return nil;
@ -317,7 +317,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {}
} }
self.networkReachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [[self.baseURL host] UTF8String]); self.networkReachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [[self.baseURL host] UTF8String]);
__weak __typeof(&*self)weakSelf = self; __weak __typeof(&*self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status){ AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status){
__strong __typeof(&*weakSelf)strongSelf = weakSelf; __strong __typeof(&*weakSelf)strongSelf = weakSelf;
@ -460,7 +460,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {}
NSParameterAssert(![method isEqualToString:@"GET"] && ![method isEqualToString:@"HEAD"]); NSParameterAssert(![method isEqualToString:@"GET"] && ![method isEqualToString:@"HEAD"]);
NSMutableURLRequest *request = [self requestWithMethod:method path:path parameters:nil]; NSMutableURLRequest *request = [self requestWithMethod:method path:path parameters:nil];
__block AFStreamingMultipartFormData *formData = [[AFStreamingMultipartFormData alloc] initWithURLRequest:request stringEncoding:self.stringEncoding]; __block AFStreamingMultipartFormData *formData = [[AFStreamingMultipartFormData alloc] initWithURLRequest:request stringEncoding:self.stringEncoding];
if (parameters) { if (parameters) {
@ -518,7 +518,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {}
- (void)cancelAllHTTPOperationsWithMethod:(NSString *)method - (void)cancelAllHTTPOperationsWithMethod:(NSString *)method
path:(NSString *)path path:(NSString *)path
{ {
NSString *URLStringToMatched = [[[self requestWithMethod:(method ?: @"GET") path:path parameters:nil] URL] absoluteString]; NSString *URLStringToMatched = [[[self requestWithMethod:(method ?: @"GET") path:path parameters:nil] URL] absoluteString];
for (NSOperation *operation in [self.operationQueue operations]) { for (NSOperation *operation in [self.operationQueue operations]) {
@ -657,8 +657,8 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {}
return nil; return nil;
} }
self.stringEncoding = (NSStringEncoding)[aDecoder decodeIntegerForKey:@"stringEncoding"]; self.stringEncoding = [aDecoder decodeIntegerForKey:@"stringEncoding"];
self.parameterEncoding = (AFHTTPClientParameterEncoding)[aDecoder decodeIntegerForKey:@"parameterEncoding"]; self.parameterEncoding = [aDecoder decodeIntegerForKey:@"parameterEncoding"];
self.registeredHTTPOperationClassNames = [aDecoder decodeObjectForKey:@"registeredHTTPOperationClassNames"]; self.registeredHTTPOperationClassNames = [aDecoder decodeObjectForKey:@"registeredHTTPOperationClassNames"];
self.defaultHeaders = [aDecoder decodeObjectForKey:@"defaultHeaders"]; self.defaultHeaders = [aDecoder decodeObjectForKey:@"defaultHeaders"];
@ -824,7 +824,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
NSParameterAssert(name); NSParameterAssert(name);
NSParameterAssert(fileName); NSParameterAssert(fileName);
NSParameterAssert(mimeType); NSParameterAssert(mimeType);
NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
[mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"];
[mutableHeaders setValue:mimeType forKey:@"Content-Type"]; [mutableHeaders setValue:mimeType forKey:@"Content-Type"];
@ -836,7 +836,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
name:(NSString *)name name:(NSString *)name
{ {
NSParameterAssert(name); NSParameterAssert(name);
NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
[mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"", name] forKey:@"Content-Disposition"]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"", name] forKey:@"Content-Disposition"];
@ -907,7 +907,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
return nil; return nil;
} }
self.stringEncoding = encoding; self.stringEncoding = encoding;
self.HTTPBodyParts = [NSMutableArray array]; self.HTTPBodyParts = [NSMutableArray array];
self.numberOfBytesInPacket = NSIntegerMax; self.numberOfBytesInPacket = NSIntegerMax;
@ -920,7 +920,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
bodyPart.hasInitialBoundary = NO; bodyPart.hasInitialBoundary = NO;
bodyPart.hasFinalBoundary = NO; bodyPart.hasFinalBoundary = NO;
} }
[[self.HTTPBodyParts objectAtIndex:0] setHasInitialBoundary:YES]; [[self.HTTPBodyParts objectAtIndex:0] setHasInitialBoundary:YES];
[[self.HTTPBodyParts lastObject] setHasFinalBoundary:YES]; [[self.HTTPBodyParts lastObject] setHasFinalBoundary:YES];
} }
@ -940,7 +940,6 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
if ([self streamStatus] == NSStreamStatusClosed) { if ([self streamStatus] == NSStreamStatusClosed) {
return 0; return 0;
} }
NSInteger bytesRead = 0; NSInteger bytesRead = 0;
while ((NSUInteger)bytesRead < MIN(length, self.numberOfBytesInPacket)) { while ((NSUInteger)bytesRead < MIN(length, self.numberOfBytesInPacket)) {
@ -955,7 +954,6 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
} }
} }
} }
return bytesRead; return bytesRead;
} }
@ -975,7 +973,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
} }
self.streamStatus = NSStreamStatusOpen; self.streamStatus = NSStreamStatusOpen;
[self setInitialAndFinalBoundaries]; [self setInitialAndFinalBoundaries];
self.HTTPBodyPartEnumerator = [self.HTTPBodyParts objectEnumerator]; self.HTTPBodyPartEnumerator = [self.HTTPBodyParts objectEnumerator];
} }
@ -1034,6 +1032,7 @@ typedef enum {
AFHeaderPhase = 2, AFHeaderPhase = 2,
AFBodyPhase = 3, AFBodyPhase = 3,
AFFinalBoundaryPhase = 4, AFFinalBoundaryPhase = 4,
AFEndPhase = 5,
} AFHTTPBodyPartReadPhase; } AFHTTPBodyPartReadPhase;
@interface AFHTTPBodyPart () { @interface AFHTTPBodyPart () {
@ -1067,7 +1066,7 @@ typedef enum {
if (_inputStream) { if (_inputStream) {
[_inputStream close]; [_inputStream close];
_inputStream = nil; _inputStream = nil;
} }
} }
- (NSString *)stringForHeaders { - (NSString *)stringForHeaders {
@ -1098,6 +1097,9 @@ typedef enum {
} }
- (BOOL)hasBytesAvailable { - (BOOL)hasBytesAvailable {
if (_phase == AFFinalBoundaryPhase) {
return YES;
}
switch (self.inputStream.streamStatus) { switch (self.inputStream.streamStatus) {
case NSStreamStatusNotOpen: case NSStreamStatusNotOpen:
case NSStreamStatusOpening: case NSStreamStatusOpening:
@ -1114,7 +1116,6 @@ typedef enum {
- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length { - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length {
NSInteger bytesRead = 0; NSInteger bytesRead = 0;
if (_phase == AFEncapsulationBoundaryPhase) { if (_phase == AFEncapsulationBoundaryPhase) {
NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary() : AFMultipartFormEncapsulationBoundary()) dataUsingEncoding:self.stringEncoding]; NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary() : AFMultipartFormEncapsulationBoundary()) dataUsingEncoding:self.stringEncoding];
bytesRead += [self readData:encapsulationBoundaryData intoBuffer:&buffer[bytesRead] maxLength:(length - bytesRead)]; bytesRead += [self readData:encapsulationBoundaryData intoBuffer:&buffer[bytesRead] maxLength:(length - bytesRead)];
@ -1137,9 +1138,9 @@ typedef enum {
if (_phase == AFFinalBoundaryPhase) { if (_phase == AFFinalBoundaryPhase) {
NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary() dataUsingEncoding:self.stringEncoding] : [NSData data]); NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary() dataUsingEncoding:self.stringEncoding] : [NSData data]);
bytesRead += [self readData:closingBoundaryData intoBuffer:&buffer[bytesRead] maxLength:(length - bytesRead)]; bytesRead += [self readData:closingBoundaryData intoBuffer:&buffer[bytesRead] maxLength:(length - bytesRead)];
} }
return bytesRead; return bytesRead;
} }
@ -1178,11 +1179,13 @@ typedef enum {
[self.inputStream close]; [self.inputStream close];
_phase = AFFinalBoundaryPhase; _phase = AFFinalBoundaryPhase;
break; break;
case AFFinalBoundaryPhase:
_phase = AFEndPhase;
break;
default: default:
_phase = AFEncapsulationBoundaryPhase; _phase = AFEncapsulationBoundaryPhase;
break; break;
} }
_phaseReadOffset = 0; _phaseReadOffset = 0;
return YES; return YES;