rejigger things to do callbacks and end-of-stream read properly
This commit is contained in:
parent
d434de241f
commit
c7f6fb09bf
2 changed files with 383 additions and 387 deletions
|
|
@ -503,7 +503,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
|
||||||
|
|
||||||
__block AFStreamingMultipartFormData * formData = [[[AFStreamingMultipartFormData alloc] initWithURLRequest:request stringEncoding:self.stringEncoding] autorelease];
|
__block AFStreamingMultipartFormData * formData = [[[AFStreamingMultipartFormData alloc] initWithURLRequest:request stringEncoding:self.stringEncoding] autorelease];
|
||||||
|
|
||||||
// __block AFMultipartFormData *formData = [[[AFMultipartFormData alloc] initWithURLRequest:request stringEncoding:self.stringEncoding] autorelease];
|
// __block AFMultipartFormData *formData = [[[AFMultipartFormData alloc] initWithURLRequest:request stringEncoding:self.stringEncoding] autorelease];
|
||||||
|
|
||||||
for (AFQueryStringComponent *component in AFQueryStringComponentsFromKeyAndValue(nil, parameters)) {
|
for (AFQueryStringComponent *component in AFQueryStringComponentsFromKeyAndValue(nil, parameters)) {
|
||||||
NSData *data = nil;
|
NSData *data = nil;
|
||||||
|
|
@ -813,7 +813,7 @@ static inline NSString * AFMultipartFormFinalBoundary() {
|
||||||
stringEncoding = NSUTF8StringEncoding;
|
stringEncoding = NSUTF8StringEncoding;
|
||||||
streamStatus = NSStreamStatusNotOpen;
|
streamStatus = NSStreamStatusNotOpen;
|
||||||
[self resetCursors];
|
[self resetCursors];
|
||||||
[self setDelegate:self];
|
// [self setDelegate:self];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -938,7 +938,7 @@ static inline NSString * AFMultipartFormFinalBoundary() {
|
||||||
}
|
}
|
||||||
|
|
||||||
-(NSInteger)readData:(NSData *)data intoBuffer:(uint8_t *)buffer maxLength:(NSUInteger)len offsetCursor:(NSUInteger*)offsetCursorPtr {
|
-(NSInteger)readData:(NSData *)data intoBuffer:(uint8_t *)buffer maxLength:(NSUInteger)len offsetCursor:(NSUInteger*)offsetCursorPtr {
|
||||||
NSUInteger bytesAvailable = [data length] - *offsetCursorPtr;
|
NSInteger bytesAvailable = [data length] - *offsetCursorPtr;
|
||||||
if (len > bytesAvailable) {
|
if (len > bytesAvailable) {
|
||||||
[data getBytes:buffer range:NSMakeRange(*offsetCursorPtr, bytesAvailable)];
|
[data getBytes:buffer range:NSMakeRange(*offsetCursorPtr, bytesAvailable)];
|
||||||
*offsetCursorPtr += bytesAvailable;
|
*offsetCursorPtr += bytesAvailable;
|
||||||
|
|
@ -979,7 +979,7 @@ static inline NSString * AFMultipartFormFinalBoundary() {
|
||||||
}
|
}
|
||||||
|
|
||||||
-(NSUInteger)totalElements {
|
-(NSUInteger)totalElements {
|
||||||
return [formDatas count] + [fileURLs count];
|
return [formDatas count] + [fileURLs count] + 1; //one extra for final boundary
|
||||||
}
|
}
|
||||||
|
|
||||||
-(NSData *)finalBoundaryData {
|
-(NSData *)finalBoundaryData {
|
||||||
|
|
@ -1036,10 +1036,14 @@ static inline NSString * AFMultipartFormFinalBoundary() {
|
||||||
#pragma mark - NSInputStream subclass overrides
|
#pragma mark - NSInputStream subclass overrides
|
||||||
|
|
||||||
-(NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len {
|
-(NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len {
|
||||||
|
if ([self streamStatus] == NSStreamStatusClosed) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
assert ([self streamStatus] == NSStreamStatusOpen);
|
assert ([self streamStatus] == NSStreamStatusOpen);
|
||||||
|
|
||||||
NSUInteger bytesRead = 0;
|
NSInteger bytesRead = 0;
|
||||||
NSUInteger readFileCursor = (readElementCursor - [formNames count]);
|
NSInteger readFileCursor = (readElementCursor - [formNames count]);
|
||||||
|
|
||||||
if (readElementCursor < [formNames count]) {
|
if (readElementCursor < [formNames count]) {
|
||||||
//reading from formDatas
|
//reading from formDatas
|
||||||
|
|
@ -1056,7 +1060,7 @@ static inline NSString * AFMultipartFormFinalBoundary() {
|
||||||
[self nextElement];
|
[self nextElement];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (readElementCursor >= [formNames count] && readFileCursor < [fileNames count]) {
|
else if (readFileCursor >= 0 && readFileCursor < [fileNames count]) {
|
||||||
//reading from files
|
//reading from files
|
||||||
NSString * currentFileName = [fileNames objectAtIndex:readFileCursor];
|
NSString * currentFileName = [fileNames objectAtIndex:readFileCursor];
|
||||||
NSURL * currentFileURL = [fileURLs objectForKey:currentFileName];
|
NSURL * currentFileURL = [fileURLs objectForKey:currentFileName];
|
||||||
|
|
@ -1069,7 +1073,7 @@ static inline NSString * AFMultipartFormFinalBoundary() {
|
||||||
} else {
|
} else {
|
||||||
if (!currentFileStream) {
|
if (!currentFileStream) {
|
||||||
currentFileStream = [[NSInputStream inputStreamWithURL:currentFileURL] retain];
|
currentFileStream = [[NSInputStream inputStreamWithURL:currentFileURL] retain];
|
||||||
currentFileStream.delegate = self;
|
// currentFileStream.delegate = self;
|
||||||
[currentFileStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
|
[currentFileStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
|
||||||
[currentFileStream open];
|
[currentFileStream open];
|
||||||
}
|
}
|
||||||
|
|
@ -1081,44 +1085,37 @@ static inline NSString * AFMultipartFormFinalBoundary() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (readElementCursor < [self totalElements]) {
|
||||||
//add final boundary
|
//add final boundary
|
||||||
bytesRead = [self readData:[self finalBoundaryData] intoBuffer:buffer maxLength:len offsetCursor:&readOffsetCursor];
|
bytesRead = [self readData:[self finalBoundaryData] intoBuffer:buffer maxLength:len offsetCursor:&readOffsetCursor];
|
||||||
if (readOffsetCursor == [[self finalBoundaryData] length]) {
|
if (readOffsetCursor == [[self finalBoundaryData] length]) {
|
||||||
[self nextElement];
|
[self nextElement];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (bytesRead < len && readElementCursor <= [self totalElements]) {
|
[self nextElement];
|
||||||
//recurse to fill out the buffer, this is critical if the above read operations produce a zero length buffer for some reason (empty form data, end of file) because returning zero from this method will result in the stream being closed.
|
|
||||||
bytesRead += [self read:buffer+bytesRead maxLength:len-bytesRead];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (readElementCursor <= [self totalElements]) {
|
||||||
|
if (bytesRead < len) {
|
||||||
|
bytesRead += [self read:buffer+bytesRead maxLength:len-bytesRead];
|
||||||
|
} else {
|
||||||
|
// no deeper recursion so call callback if necessary
|
||||||
|
if (copiedCallback && (requestedEvents & kCFStreamEventHasBytesAvailable)) {
|
||||||
|
copiedCallback((CFReadStreamRef)self, kCFStreamEventHasBytesAvailable, &copiedContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//doesn't seem to make a diff if we do the callbacks or not for the HTTP request use anyway,
|
|
||||||
//and it sometimes crashes if the callback reciever or context have been released.
|
|
||||||
// if (CFReadStreamGetStatus((CFReadStreamRef)self) == kCFStreamStatusOpen) {
|
|
||||||
// double delayInSeconds = 0;
|
|
||||||
// dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
|
|
||||||
// dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
|
|
||||||
// if (copiedCallback && (requestedEvents & kCFStreamEventHasBytesAvailable)) {
|
|
||||||
// NSLog(@"callback kCFStreamEventHasBytesAvailable... bytes read: %d", bytesRead);
|
|
||||||
// copiedCallback((CFReadStreamRef)self, kCFStreamEventHasBytesAvailable, &copiedContext);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
assert(bytesRead > 0); //really should never return zero from this call
|
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(BOOL)hasBytesAvailable {
|
-(BOOL)hasBytesAvailable {
|
||||||
if ([self totalElements] == 0) {
|
if ([self streamStatus] != NSStreamStatusOpen) {
|
||||||
return NO;
|
return NO;
|
||||||
} else if (readElementCursor < ([self totalElements] + 1)) {
|
}
|
||||||
|
else {
|
||||||
return YES;
|
return YES;
|
||||||
} else {
|
|
||||||
return NO;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1161,7 +1158,6 @@ static inline NSString * AFMultipartFormFinalBoundary() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue