diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 424897b7a3..420b6e0b35 100755 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -687,23 +687,6 @@ - (id)copyWithZone:(NSZone *)zone { #pragma mark - -static NSString * const kAFMultipartTemporaryFileDirectoryName = @"com.alamofire.uploads"; - -static NSString * AFMultipartTemporaryFileDirectoryPath() { - static NSString *multipartTemporaryFilePath = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - multipartTemporaryFilePath = [[NSTemporaryDirectory() stringByAppendingPathComponent:kAFMultipartTemporaryFileDirectoryName] copy]; - - NSError *error = nil; - if(![[NSFileManager defaultManager] createDirectoryAtPath:multipartTemporaryFilePath withIntermediateDirectories:YES attributes:nil error:&error]) { - NSLog(@"Failed to create multipary temporary file directory at %@", multipartTemporaryFilePath); - } - }); - - return multipartTemporaryFilePath; -} - static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY"; static NSString * const kAFMultipartFormCRLF = @"\r\n"; @@ -882,7 +865,6 @@ - (BOOL)appendPartWithFileURL:(NSURL *)fileURL } - (NSMutableURLRequest *)requestByFinalizingMultipartFormData { - // Return the original request if no data has been added if ([self.bodyStream isEmpty]) { return self.request; } @@ -922,47 +904,68 @@ - (id)initWithStringEncoding:(NSStringEncoding)encoding { } - (void)setInitialAndFinalBoundaries { - if ([self.HTTPBodyParts count] > 0) { // If there's any HTTP body parts... - // Reset all HTTP body parts boundary settings first. - for (AFHTTPBodyPart *theHTTPBodyPart in self.HTTPBodyParts) { - theHTTPBodyPart.hasInitialBoundary = NO; - theHTTPBodyPart.hasFinalBoundary = NO; + if ([self.HTTPBodyParts count] > 0) { + for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) { + bodyPart.hasInitialBoundary = NO; + bodyPart.hasFinalBoundary = NO; } - // Set the first and last object boundary settings. + [[self.HTTPBodyParts objectAtIndex:0] setHasInitialBoundary:YES]; [[self.HTTPBodyParts lastObject] setHasFinalBoundary:YES]; } } -#pragma mark - NSStream subclass overrides +- (BOOL)isEmpty { + return [self.HTTPBodyParts count] == 0; +} + +#pragma mark - NSInputStream + +- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length { + if ([self streamStatus] == NSStreamStatusClosed) { + return 0; + } + + NSInteger bytesRead = 0; + + while ((NSUInteger)bytesRead < length) { + if (!self.currentHTTPBodyPart || ![self.currentHTTPBodyPart hasBytesAvailable]) { + if (!(self.currentHTTPBodyPart = [self.HTTPBodyPartEnumerator nextObject])) { + break; + } + } else { + bytesRead += [self.currentHTTPBodyPart read:&buffer[bytesRead] maxLength:length - bytesRead]; + } + } + + return bytesRead; +} + +- (BOOL)getBuffer:(uint8_t **)buffer length:(NSUInteger *)len { + return NO; +} + +- (BOOL)hasBytesAvailable { + return [self streamStatus] == NSStreamStatusOpen; +} + +#pragma mark - NSStream - (void)open { - if ([self.HTTPBodyParts count] > 0) { - // This call might be redundant but can be a good safety measure - // to make sure that the boundary settings are correctly set. - // But even so, the length might be screw up if the user try to - // mess with the HTTP body part between finalizing the multipart - // form data request and here. - [self setInitialAndFinalBoundaries]; - - self.HTTPBodyPartEnumerator = [self.HTTPBodyParts objectEnumerator]; + if (self.streamStatus == NSStreamStatusOpen) { + return; } streamStatus = NSStreamStatusOpen; + + [self setInitialAndFinalBoundaries]; + self.HTTPBodyPartEnumerator = [self.HTTPBodyParts objectEnumerator]; } - (void)close { streamStatus = NSStreamStatusClosed; } -- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop - forMode:(NSString *)mode -{} - -- (void)removeFromRunLoop:(NSRunLoop *)aRunLoop - forMode:(NSString *)mode -{} - - (id)propertyForKey:(NSString *)key { return nil; } @@ -971,6 +974,14 @@ - (BOOL)setProperty:(id)property forKey:(NSString *)key { return NO; } +- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop + forMode:(NSString *)mode +{} + +- (void)removeFromRunLoop:(NSRunLoop *)aRunLoop + forMode:(NSString *)mode +{} + - (NSStreamStatus)streamStatus { return streamStatus; } @@ -979,10 +990,6 @@ - (NSError *)streamError { return nil; } -- (BOOL)isEmpty { - return [self.HTTPBodyParts count] == 0; -} - - (unsigned long long)contentLength { unsigned long long length = 0; for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) { @@ -992,37 +999,7 @@ - (unsigned long long)contentLength { return length; } -#pragma mark - NSInputStream subclass overrides - -- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length { - if ([self streamStatus] == NSStreamStatusClosed) { - return 0; - } - - NSInteger bytesRead = 0; - - while ((NSUInteger)bytesRead < length) { - if (!self.currentHTTPBodyPart || ![self.currentHTTPBodyPart hasBytesAvailable]) { - if (!(self.currentHTTPBodyPart = [self.HTTPBodyPartEnumerator nextObject])) { - break; - } - } else { - bytesRead += [self.currentHTTPBodyPart read:&buffer[bytesRead] maxLength:length - bytesRead]; - } - } - - return bytesRead; -} - -- (BOOL)hasBytesAvailable { - return [self streamStatus] == NSStreamStatusOpen; -} - -- (BOOL)getBuffer:(uint8_t **)buffer length:(NSUInteger *)len { - return NO; -} - -#pragma mark - Undocumented CFReadStream bridged methods +#pragma mark - Undocumented CFReadStream Bridged Methods - (void)_scheduleInCFRunLoop:(CFRunLoopRef)aRunLoop forMode:(CFStringRef)aMode @@ -1082,62 +1059,16 @@ - (void)dealloc { } } -- (BOOL)transitionToNextPhase { - if (![[NSThread currentThread] isMainThread]) { - [self performSelectorOnMainThread:@selector(transitionToNextPhase) withObject:nil waitUntilDone:YES]; - return YES; - } - - switch (_phase) { - case AFEncapsulationBoundaryPhase: - _phase = AFHeaderPhase; - break; - case AFHeaderPhase: - [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; - [self.inputStream open]; - _phase = AFBodyPhase; - break; - case AFBodyPhase: - [self.inputStream close]; - _phase = AFFinalBoundaryPhase; - break; - default: - _phase = AFEncapsulationBoundaryPhase; - break; - } - - _phaseReadOffset = 0; - - return YES; -} - - (NSString *)stringForHeaders { NSMutableString *headerString = [NSMutableString string]; for (NSString *field in [self.headers allKeys]) { [headerString appendString:[NSString stringWithFormat:@"%@: %@%@", field, [self.headers valueForKey:field], kAFMultipartFormCRLF]]; } - // There's a CRLF after the header string. [headerString appendString:kAFMultipartFormCRLF]; return [NSString stringWithString:headerString]; } -- (NSInteger)readData:(NSData *)data - intoBuffer:(uint8_t *)buffer - maxLength:(NSUInteger)length -{ - NSRange range = NSMakeRange(_phaseReadOffset, MIN([data length], length)); - [data getBytes:buffer range:range]; - - _phaseReadOffset += range.length; - - if (range.length >= [data length]) { - [self transitionToNextPhase]; - } - - return range.length; -} - - (unsigned long long)contentLength { unsigned long long length = 0; @@ -1155,6 +1086,16 @@ - (unsigned long long)contentLength { return length; } +- (BOOL)hasBytesAvailable { + switch (self.inputStream.streamStatus) { + case NSStreamStatusAtEnd: + case NSStreamStatusClosed: + case NSStreamStatusError: + return NO; + default: + return YES; + } +} - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length { NSInteger bytesRead = 0; @@ -1187,15 +1128,49 @@ - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length { return bytesRead; } -- (BOOL)hasBytesAvailable { - switch (self.inputStream.streamStatus) { - case NSStreamStatusAtEnd: - case NSStreamStatusClosed: - case NSStreamStatusError: - return NO; +- (NSInteger)readData:(NSData *)data + intoBuffer:(uint8_t *)buffer + maxLength:(NSUInteger)length +{ + NSRange range = NSMakeRange(_phaseReadOffset, MIN([data length], length)); + [data getBytes:buffer range:range]; + + _phaseReadOffset += range.length; + + if (range.length >= [data length]) { + [self transitionToNextPhase]; + } + + return range.length; +} + +- (BOOL)transitionToNextPhase { + if (![[NSThread currentThread] isMainThread]) { + [self performSelectorOnMainThread:@selector(transitionToNextPhase) withObject:nil waitUntilDone:YES]; + return YES; + } + + switch (_phase) { + case AFEncapsulationBoundaryPhase: + _phase = AFHeaderPhase; + break; + case AFHeaderPhase: + [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + [self.inputStream open]; + _phase = AFBodyPhase; + break; + case AFBodyPhase: + [self.inputStream close]; + _phase = AFFinalBoundaryPhase; + break; default: - return YES; + _phase = AFEncapsulationBoundaryPhase; + break; } + + _phaseReadOffset = 0; + + return YES; } @end