From da61ffdaae93ec399be7b260b4159098499c4966 Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Sat, 17 Oct 2015 09:33:09 -0700 Subject: [PATCH] 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 --- Libraries/Image/RCTImageDownloader.m | 1 + Libraries/Network/RCTDownloadTask.h | 1 + Libraries/Network/RCTDownloadTask.m | 22 +++++++++++++++++----- Libraries/Network/RCTNetworking.m | 4 ++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Libraries/Image/RCTImageDownloader.m b/Libraries/Image/RCTImageDownloader.m index e1c6d1d1cf4..dab71ee6436 100644 --- a/Libraries/Image/RCTImageDownloader.m +++ b/Libraries/Image/RCTImageDownloader.m @@ -96,6 +96,7 @@ RCT_EXPORT_MODULE() if (progressBlock) { task.downloadProgressBlock = progressBlock; } + [task start]; return ^{ [task cancel]; }; } diff --git a/Libraries/Network/RCTDownloadTask.h b/Libraries/Network/RCTDownloadTask.h index a6151a4d062..2cb2a8f0bfa 100644 --- a/Libraries/Network/RCTDownloadTask.h +++ b/Libraries/Network/RCTDownloadTask.h @@ -35,6 +35,7 @@ typedef void (^RCTURLRequestResponseBlock)(NSURLResponse *response); handler:(id)handler completionBlock:(RCTURLRequestCompletionBlock)completionBlock NS_DESIGNATED_INITIALIZER; +- (void)start; - (void)cancel; @end diff --git a/Libraries/Network/RCTDownloadTask.m b/Libraries/Network/RCTDownloadTask.m index a70c64113f5..a0492d542c7 100644 --- a/Libraries/Network/RCTDownloadTask.m +++ b/Libraries/Network/RCTDownloadTask.m @@ -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); diff --git a/Libraries/Network/RCTNetworking.m b/Libraries/Network/RCTNetworking.m index 7c3a83bb1e9..73f9dc57c62 100644 --- a/Libraries/Network/RCTNetworking.m +++ b/Libraries/Network/RCTNetworking.m @@ -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