Add test coverage and fix for "Stream XXX is sending an event before being opened" during multi-part file uploads. fixes #948

This commit is contained in:
Blake Watters 2013-05-18 14:45:27 -04:00
parent d6587027e7
commit f339198d14
3 changed files with 27 additions and 4 deletions

View file

@ -1067,11 +1067,22 @@ static const NSUInteger AFMultipartBodyStreamProviderDefaultBufferLength = 4096;
#pragma mark - NSStreamDelegate
- (void)stream:(NSStream __unused *)stream
handleEvent:(NSStreamEvent)eventCode
{
/**
This retry works around a nasty problem in which mutli-part uploads will fail due to the stream delegate being sent a `NSStreamEventHasSpaceAvailable` event before the input stream has finished opening. This workaround simply replays the event after allowing the run-loop to cycle, providing enough time for the input stream to finish opening. It appears that this bug is in the CFNetwork layer. (See https://github.com/AFNetworking/AFNetworking/issues/948)
*/
- (void)retryWrite:(NSStream *)stream {
[self stream:stream handleEvent:NSStreamEventHasSpaceAvailable];
}
- (void)stream:(NSStream *)stream
handleEvent:(NSStreamEvent)eventCode {
if (eventCode & NSStreamEventHasSpaceAvailable) {
[self handleOutputStreamSpaceAvailable];
if (self.inputStream.streamStatus < NSStreamStatusOpen) {
// See comments in `retryWrite:` for details
[self performSelector:@selector(retryWrite:) withObject:stream afterDelay:0.1];
} else {
[self handleOutputStreamSpaceAvailable];
}
}
}

View file

@ -199,4 +199,16 @@
expect(responseDictionary[@"form"]).to.equal(@{ @"key": @"value" });
}
- (void)testMultipartUploadDoesNotFailDueToStreamSentAnEventBeforeBeingOpenedError {
NSString *pathToImage = [[NSBundle bundleForClass:[AFHTTPClient class]] pathForResource:@"abide" ofType:@"jpg"];
NSData *imageData = [NSData dataWithContentsOfFile:pathToImage];
NSMutableURLRequest *request = [self.client multipartFormRequestWithMethod:@"POST" path:@"/post" parameters:@{ @"this": @"that" } constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:@"item[photos_attributes][][photo]" fileName:@"item-image.png" mimeType:@"image/jpg"];
}];
AFHTTPRequestOperation *operation = [self.client HTTPRequestOperationWithRequest:request success:nil failure:nil];
[self.client enqueueHTTPRequestOperation:operation];
expect(operation.isFinished).will.beTruthy();
expect(operation.error).notTo.equal(NSURLErrorTimedOut);
}
@end

BIN
Tests/abide.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB