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) { if (progressBlock) {
task.downloadProgressBlock = progressBlock; task.downloadProgressBlock = progressBlock;
} }
[task start];
return ^{ [task cancel]; }; return ^{ [task cancel]; };
} }

View File

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

View File

@ -29,18 +29,16 @@
static NSUInteger requestID = 0; static NSUInteger requestID = 0;
if ((self = [super init])) { if ((self = [super init])) {
if (!(_requestToken = [handler sendRequest:request withDelegate:self])) {
return nil;
}
_requestID = @(requestID++); _requestID = @(requestID++);
_request = request; _request = request;
_handler = handler; _handler = handler;
_completionBlock = completionBlock; _completionBlock = completionBlock;
_selfReference = self;
} }
return self; return self;
} }
RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (void)invalidate - (void)invalidate
{ {
_selfReference = nil; _selfReference = nil;
@ -51,7 +49,15 @@
_uploadProgressBlock = nil; _uploadProgressBlock = nil;
} }
RCT_NOT_IMPLEMENTED(- (instancetype)init) - (void)start
{
if (_requestToken == nil) {
if ([self validateRequestToken:[_handler sendRequest:_request
withDelegate:self]]) {
_selfReference = self;
}
}
}
- (void)cancel - (void)cancel
{ {
@ -63,6 +69,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (BOOL)validateRequestToken:(id)requestToken - (BOOL)validateRequestToken:(id)requestToken
{ {
if (_requestToken == nil) {
if (requestToken == nil) {
return NO;
}
_requestToken = requestToken;
}
if (![requestToken isEqual:_requestToken]) { if (![requestToken isEqual:_requestToken]) {
if (RCT_DEBUG) { if (RCT_DEBUG) {
RCTLogError(@"Unrecognized request token: %@ expected: %@", requestToken, _requestToken); 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); cancellationBlock = callback(error, data ? @{@"body": data, @"contentType": RCTNullIfNil(response.MIMEType)} : nil);
}]; }];
[task start];
__weak RCTDownloadTask *weakTask = task; __weak RCTDownloadTask *weakTask = task;
return ^{ return ^{
[weakTask cancel]; [weakTask cancel];
@ -362,6 +364,8 @@ RCT_EXPORT_MODULE()
_tasksByRequestID[task.requestID] = task; _tasksByRequestID[task.requestID] = task;
responseSender(@[task.requestID]); responseSender(@[task.requestID]);
} }
[task start];
} }
#pragma mark - Public API #pragma mark - Public API