Fixed "Unrecognized request token" red box

Summary: public

There was a race condition issue in RCTDownLoadTask whereby the request handler would sometimes call one of the delegate methods before setup was complete, causing an error to be logged because the request token had not been set, and causing te request to fail because the class was not yet set up.

This diff fixes that issue by adding an explicit `start` method to RCTDownloadTask, and changing the setup order to allow for the request to call back immediately without this being treated as an error.

Reviewed By: tadeuzagallo

Differential Revision: D2553628

fb-gh-sync-id: 5ca4e791574a632ccbf2e873e28ac88bffdf851d
This commit is contained in:
Nick Lockwood 2015-10-17 09:33:09 -07:00 committed by facebook-github-bot-0
parent f01272b031
commit 16a48ae0c3
4 changed files with 23 additions and 5 deletions

View File

@ -96,6 +96,7 @@ RCT_EXPORT_MODULE()
if (progressBlock) {
task.downloadProgressBlock = progressBlock;
}
[task start];
return ^{ [task cancel]; };
}

View File

@ -35,6 +35,7 @@ typedef void (^RCTURLRequestResponseBlock)(NSURLResponse *response);
handler:(id<RCTURLRequestHandler>)handler
completionBlock:(RCTURLRequestCompletionBlock)completionBlock NS_DESIGNATED_INITIALIZER;
- (void)start;
- (void)cancel;
@end

View File

@ -29,18 +29,16 @@
static NSUInteger requestID = 0;
if ((self = [super init])) {
if (!(_requestToken = [handler sendRequest:request withDelegate:self])) {
return nil;
}
_requestID = @(requestID++);
_request = request;
_handler = handler;
_completionBlock = completionBlock;
_selfReference = self;
}
return self;
}
RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (void)invalidate
{
_selfReference = nil;
@ -51,7 +49,15 @@
_uploadProgressBlock = nil;
}
RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (void)start
{
if (_requestToken == nil) {
if ([self validateRequestToken:[_handler sendRequest:_request
withDelegate:self]]) {
_selfReference = self;
}
}
}
- (void)cancel
{
@ -63,6 +69,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (BOOL)validateRequestToken:(id)requestToken
{
if (_requestToken == nil) {
if (requestToken == nil) {
return NO;
}
_requestToken = requestToken;
}
if (![requestToken isEqual:_requestToken]) {
if (RCT_DEBUG) {
RCTLogError(@"Unrecognized request token: %@ expected: %@", requestToken, _requestToken);

View File

@ -238,6 +238,8 @@ RCT_EXPORT_MODULE()
cancellationBlock = callback(error, data ? @{@"body": data, @"contentType": RCTNullIfNil(response.MIMEType)} : nil);
}];
[task start];
__weak RCTDownloadTask *weakTask = task;
return ^{
[weakTask cancel];
@ -362,6 +364,8 @@ RCT_EXPORT_MODULE()
_tasksByRequestID[task.requestID] = task;
responseSender(@[task.requestID]);
}
[task start];
}
#pragma mark - Public API