mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-28 12:15:37 +08:00
Added RCTDataRequestHandler
Summary: public Added RCTDataRequestHandler, which is responsible for loading data URLs. This moves the logic for data URL handling out of RCTImageDownloader (no longer needed) and into the RCTNetwork library, where it makes more sense. This also means that it is now possible to load data URLs via XHR, and use them for purposes other than just images. Reviewed By: javache Differential Revision: D2540964 fb-gh-sync-id: 4f0418bd6b9186f047cc8297276bb970795af104
This commit is contained in:
committed by
facebook-github-bot-4
parent
31f9a690f3
commit
1076f4a172
18
Libraries/Network/RCTDataRequestHandler.h
Normal file
18
Libraries/Network/RCTDataRequestHandler.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "RCTURLRequestHandler.h"
|
||||
#import "RCTInvalidating.h"
|
||||
|
||||
/**
|
||||
* This is the default RCTURLRequestHandler implementation for data URL requests.
|
||||
*/
|
||||
@interface RCTDataRequestHandler : NSObject <RCTURLRequestHandler, RCTInvalidating>
|
||||
|
||||
@end
|
||||
73
Libraries/Network/RCTDataRequestHandler.m
Normal file
73
Libraries/Network/RCTDataRequestHandler.m
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "RCTDataRequestHandler.h"
|
||||
|
||||
@implementation RCTDataRequestHandler
|
||||
{
|
||||
NSOperationQueue *_queue;
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
[_queue cancelAllOperations];
|
||||
_queue = nil;
|
||||
}
|
||||
|
||||
- (BOOL)canHandleRequest:(NSURLRequest *)request
|
||||
{
|
||||
return [request.URL.scheme caseInsensitiveCompare:@"data"] == NSOrderedSame;
|
||||
}
|
||||
|
||||
- (NSOperation *)sendRequest:(NSURLRequest *)request
|
||||
withDelegate:(id<RCTURLRequestDelegate>)delegate
|
||||
{
|
||||
// Lazy setup
|
||||
if (!_queue) {
|
||||
_queue = [NSOperationQueue new];
|
||||
_queue.maxConcurrentOperationCount = 2;
|
||||
}
|
||||
|
||||
__block NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
|
||||
|
||||
// Get mime type
|
||||
NSRange firstSemicolon = [request.URL.resourceSpecifier rangeOfString:@";"];
|
||||
NSString *mimeType = firstSemicolon.length ? [request.URL.resourceSpecifier substringToIndex:firstSemicolon.location] : nil;
|
||||
|
||||
// Send response
|
||||
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:request.URL
|
||||
MIMEType:mimeType
|
||||
expectedContentLength:-1
|
||||
textEncodingName:nil];
|
||||
|
||||
[delegate URLRequest:op didReceiveResponse:response];
|
||||
|
||||
// Load data
|
||||
NSError *error;
|
||||
NSData *data = [NSData dataWithContentsOfURL:request.URL
|
||||
options:NSDataReadingMappedIfSafe
|
||||
error:&error];
|
||||
if (data) {
|
||||
[delegate URLRequest:op didReceiveData:data];
|
||||
}
|
||||
[delegate URLRequest:op didCompleteWithError:error];
|
||||
}];
|
||||
|
||||
[_queue addOperation:op];
|
||||
return op;
|
||||
}
|
||||
|
||||
- (void)cancelRequest:(NSOperation *)op
|
||||
{
|
||||
[op cancel];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -11,13 +11,13 @@
|
||||
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
|
||||
#import "RCTUtils.h"
|
||||
|
||||
@implementation RCTFileRequestHandler
|
||||
{
|
||||
NSOperationQueue *_fileQueue;
|
||||
}
|
||||
|
||||
@synthesize methodQueue = _methodQueue;
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (void)invalidate
|
||||
@@ -28,7 +28,9 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
- (BOOL)canHandleRequest:(NSURLRequest *)request
|
||||
{
|
||||
return [request.URL.scheme caseInsensitiveCompare:@"file"] == NSOrderedSame;
|
||||
return
|
||||
[request.URL.scheme caseInsensitiveCompare:@"file"] == NSOrderedSame
|
||||
&& !RCTIsXCAssetURL(request.URL);
|
||||
}
|
||||
|
||||
- (NSOperation *)sendRequest:(NSURLRequest *)request
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
134E969A1BCEB7F800AFFDA1 /* RCTDataRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 134E96991BCEB7F800AFFDA1 /* RCTDataRequestHandler.m */; settings = {ASSET_TAGS = (); }; };
|
||||
1372B7371AB03E7B00659ED6 /* RCTNetInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 1372B7361AB03E7B00659ED6 /* RCTNetInfo.m */; };
|
||||
13D6D66A1B5FCF8200883BE9 /* RCTDownloadTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 13D6D6691B5FCF8200883BE9 /* RCTDownloadTask.m */; };
|
||||
13D6D66A1B5FCF8200883BE9 /* RCTNetworkTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 13D6D6691B5FCF8200883BE9 /* RCTNetworkTask.m */; };
|
||||
13EF800E1BCBE015003F47DD /* RCTFileRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 13EF800D1BCBE015003F47DD /* RCTFileRequestHandler.m */; settings = {ASSET_TAGS = (); }; };
|
||||
352DA0BA1B17855800AA15A8 /* RCTHTTPRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 352DA0B81B17855800AA15A8 /* RCTHTTPRequestHandler.m */; };
|
||||
58B512081A9E6CE300147676 /* RCTNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B512071A9E6CE300147676 /* RCTNetworking.m */; };
|
||||
@@ -27,10 +28,12 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
134E96981BCEB7F800AFFDA1 /* RCTDataRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDataRequestHandler.h; sourceTree = "<group>"; };
|
||||
134E96991BCEB7F800AFFDA1 /* RCTDataRequestHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDataRequestHandler.m; sourceTree = "<group>"; };
|
||||
1372B7351AB03E7B00659ED6 /* RCTNetInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTNetInfo.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
1372B7361AB03E7B00659ED6 /* RCTNetInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = RCTNetInfo.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
13D6D6681B5FCF8200883BE9 /* RCTDownloadTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDownloadTask.h; sourceTree = "<group>"; };
|
||||
13D6D6691B5FCF8200883BE9 /* RCTDownloadTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDownloadTask.m; sourceTree = "<group>"; };
|
||||
13D6D6681B5FCF8200883BE9 /* RCTNetworkTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTNetworkTask.h; sourceTree = "<group>"; };
|
||||
13D6D6691B5FCF8200883BE9 /* RCTNetworkTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTNetworkTask.m; sourceTree = "<group>"; };
|
||||
13EF800C1BCBE015003F47DD /* RCTFileRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTFileRequestHandler.h; sourceTree = "<group>"; };
|
||||
13EF800D1BCBE015003F47DD /* RCTFileRequestHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTFileRequestHandler.m; sourceTree = "<group>"; };
|
||||
352DA0B71B17855800AA15A8 /* RCTHTTPRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTHTTPRequestHandler.h; sourceTree = "<group>"; };
|
||||
@@ -54,12 +57,14 @@
|
||||
58B511D21A9E6C8500147676 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13D6D6681B5FCF8200883BE9 /* RCTDownloadTask.h */,
|
||||
13D6D6691B5FCF8200883BE9 /* RCTDownloadTask.m */,
|
||||
13D6D6681B5FCF8200883BE9 /* RCTNetworkTask.h */,
|
||||
13D6D6691B5FCF8200883BE9 /* RCTNetworkTask.m */,
|
||||
352DA0B71B17855800AA15A8 /* RCTHTTPRequestHandler.h */,
|
||||
352DA0B81B17855800AA15A8 /* RCTHTTPRequestHandler.m */,
|
||||
13EF800C1BCBE015003F47DD /* RCTFileRequestHandler.h */,
|
||||
13EF800D1BCBE015003F47DD /* RCTFileRequestHandler.m */,
|
||||
134E96981BCEB7F800AFFDA1 /* RCTDataRequestHandler.h */,
|
||||
134E96991BCEB7F800AFFDA1 /* RCTDataRequestHandler.m */,
|
||||
1372B7351AB03E7B00659ED6 /* RCTNetInfo.h */,
|
||||
1372B7361AB03E7B00659ED6 /* RCTNetInfo.m */,
|
||||
58B512061A9E6CE300147676 /* RCTNetworking.h */,
|
||||
@@ -134,8 +139,9 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13D6D66A1B5FCF8200883BE9 /* RCTDownloadTask.m in Sources */,
|
||||
13D6D66A1B5FCF8200883BE9 /* RCTNetworkTask.m in Sources */,
|
||||
13EF800E1BCBE015003F47DD /* RCTFileRequestHandler.m in Sources */,
|
||||
134E969A1BCEB7F800AFFDA1 /* RCTDataRequestHandler.m in Sources */,
|
||||
1372B7371AB03E7B00659ED6 /* RCTNetInfo.m in Sources */,
|
||||
58B512081A9E6CE300147676 /* RCTNetworking.m in Sources */,
|
||||
352DA0BA1B17855800AA15A8 /* RCTHTTPRequestHandler.m in Sources */,
|
||||
|
||||
@@ -18,7 +18,7 @@ typedef void (^RCTURLRequestIncrementalDataBlock)(NSData *data);
|
||||
typedef void (^RCTURLRequestProgressBlock)(int64_t progress, int64_t total);
|
||||
typedef void (^RCTURLRequestResponseBlock)(NSURLResponse *response);
|
||||
|
||||
@interface RCTDownloadTask : NSObject <RCTURLRequestDelegate>
|
||||
@interface RCTNetworkTask : NSObject <RCTURLRequestDelegate>
|
||||
|
||||
@property (nonatomic, readonly) NSURLRequest *request;
|
||||
@property (nonatomic, readonly) NSNumber *requestID;
|
||||
@@ -7,15 +7,15 @@
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "RCTDownloadTask.h"
|
||||
#import "RCTNetworkTask.h"
|
||||
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RCTDownloadTask
|
||||
@implementation RCTNetworkTask
|
||||
{
|
||||
NSMutableData *_data;
|
||||
id<RCTURLRequestHandler> _handler;
|
||||
RCTDownloadTask *_selfReference;
|
||||
RCTNetworkTask *_selfReference;
|
||||
}
|
||||
|
||||
- (instancetype)initWithRequest:(NSURLRequest *)request
|
||||
@@ -10,12 +10,21 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTDownloadTask.h"
|
||||
#import "RCTNetworkTask.h"
|
||||
|
||||
@interface RCTNetworking : NSObject <RCTBridgeModule>
|
||||
|
||||
- (RCTDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
|
||||
completionBlock:(RCTURLRequestCompletionBlock)completionBlock;
|
||||
/**
|
||||
* Does a handler exist for the specified request?
|
||||
*/
|
||||
- (BOOL)canHandleRequest:(NSURLRequest *)request;
|
||||
|
||||
/**
|
||||
* Return an RCTNetworkTask for the specified request. This is useful for
|
||||
* invoking the React Native networking stack from within native code.
|
||||
*/
|
||||
- (RCTNetworkTask *)networkTaskWithRequest:(NSURLRequest *)request
|
||||
completionBlock:(RCTURLRequestCompletionBlock)completionBlock;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTDownloadTask.h"
|
||||
#import "RCTNetworkTask.h"
|
||||
#import "RCTURLRequestHandler.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTHTTPRequestHandler.h"
|
||||
@@ -37,10 +37,10 @@ typedef RCTURLRequestCancellationBlock (^RCTHTTPQueryResult)(NSError *error, NSD
|
||||
|
||||
@implementation RCTHTTPFormDataHelper
|
||||
{
|
||||
NSMutableArray *parts;
|
||||
NSMutableData *multipartBody;
|
||||
NSMutableArray *_parts;
|
||||
NSMutableData *_multipartBody;
|
||||
RCTHTTPQueryResult _callback;
|
||||
NSString *boundary;
|
||||
NSString *_boundary;
|
||||
}
|
||||
|
||||
static NSString *RCTGenerateFormBoundary()
|
||||
@@ -56,19 +56,19 @@ static NSString *RCTGenerateFormBoundary()
|
||||
return [[NSString alloc] initWithBytesNoCopy:bytes length:boundaryLength encoding:NSUTF8StringEncoding freeWhenDone:YES];
|
||||
}
|
||||
|
||||
- (RCTURLRequestCancellationBlock)process:(NSArray *)formData
|
||||
- (RCTURLRequestCancellationBlock)process:(NSDictionaryArray *)formData
|
||||
callback:(RCTHTTPQueryResult)callback
|
||||
{
|
||||
if (formData.count == 0) {
|
||||
return callback(nil, nil);
|
||||
}
|
||||
|
||||
parts = [formData mutableCopy];
|
||||
_parts = [formData mutableCopy];
|
||||
_callback = callback;
|
||||
multipartBody = [NSMutableData new];
|
||||
boundary = RCTGenerateFormBoundary();
|
||||
_multipartBody = [NSMutableData new];
|
||||
_boundary = RCTGenerateFormBoundary();
|
||||
|
||||
return [_networker processDataForHTTPQuery:parts[0] callback:^(NSError *error, NSDictionary *result) {
|
||||
return [_networker processDataForHTTPQuery:_parts[0] callback:^(NSError *error, NSDictionary *result) {
|
||||
return [self handleResult:result error:error];
|
||||
}];
|
||||
}
|
||||
@@ -81,37 +81,37 @@ static NSString *RCTGenerateFormBoundary()
|
||||
}
|
||||
|
||||
// Start with boundary.
|
||||
[multipartBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary]
|
||||
dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[_multipartBody appendData:[[NSString stringWithFormat:@"--%@\r\n", _boundary]
|
||||
dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
// Print headers.
|
||||
NSMutableDictionary *headers = [parts[0][@"headers"] mutableCopy];
|
||||
NSMutableDictionary *headers = [_parts[0][@"headers"] mutableCopy];
|
||||
NSString *partContentType = result[@"contentType"];
|
||||
if (partContentType != nil) {
|
||||
headers[@"content-type"] = partContentType;
|
||||
}
|
||||
[headers enumerateKeysAndObjectsUsingBlock:^(NSString *parameterKey, NSString *parameterValue, BOOL *stop) {
|
||||
[multipartBody appendData:[[NSString stringWithFormat:@"%@: %@\r\n", parameterKey, parameterValue]
|
||||
dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[_multipartBody appendData:[[NSString stringWithFormat:@"%@: %@\r\n", parameterKey, parameterValue]
|
||||
dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
}];
|
||||
|
||||
// Add the body.
|
||||
[multipartBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[multipartBody appendData:result[@"body"]];
|
||||
[multipartBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[_multipartBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[_multipartBody appendData:result[@"body"]];
|
||||
[_multipartBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
[parts removeObjectAtIndex:0];
|
||||
if (parts.count) {
|
||||
return [_networker processDataForHTTPQuery:parts[0] callback:^(NSError *err, NSDictionary *res) {
|
||||
[_parts removeObjectAtIndex:0];
|
||||
if (_parts.count) {
|
||||
return [_networker processDataForHTTPQuery:_parts[0] callback:^(NSError *err, NSDictionary *res) {
|
||||
return [self handleResult:res error:err];
|
||||
}];
|
||||
}
|
||||
|
||||
// We've processed the last item. Finish and return.
|
||||
[multipartBody appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary]
|
||||
dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=\"%@\"", boundary];
|
||||
return _callback(nil, @{@"body": multipartBody, @"contentType": contentType});
|
||||
[_multipartBody appendData:[[NSString stringWithFormat:@"--%@--\r\n", _boundary]
|
||||
dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=\"%@\"", _boundary];
|
||||
return _callback(nil, @{@"body": _multipartBody, @"contentType": contentType});
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -122,6 +122,7 @@ static NSString *RCTGenerateFormBoundary()
|
||||
@implementation RCTNetworking
|
||||
{
|
||||
NSMutableDictionary *_tasksByRequestID;
|
||||
NSArray *_handlers;
|
||||
}
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
@@ -129,12 +130,65 @@ static NSString *RCTGenerateFormBoundary()
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (instancetype)init
|
||||
- (void)setBridge:(RCTBridge *)bridge
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_tasksByRequestID = [NSMutableDictionary new];
|
||||
// get handlers
|
||||
NSMutableArray *handlers = [NSMutableArray array];
|
||||
for (id<RCTBridgeModule> module in bridge.modules.allValues) {
|
||||
if ([module conformsToProtocol:@protocol(RCTURLRequestHandler)]) {
|
||||
[handlers addObject:module];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
|
||||
// Sort handlers in reverse priority order (highest priority first)
|
||||
[handlers sortUsingComparator:^NSComparisonResult(id<RCTURLRequestHandler> a, id<RCTURLRequestHandler> b) {
|
||||
float priorityA = [a respondsToSelector:@selector(handlerPriority)] ? [a handlerPriority] : 0;
|
||||
float priorityB = [b respondsToSelector:@selector(handlerPriority)] ? [b handlerPriority] : 0;
|
||||
if (priorityA > priorityB) {
|
||||
return NSOrderedAscending;
|
||||
} else if (priorityA < priorityB) {
|
||||
return NSOrderedDescending;
|
||||
} else {
|
||||
return NSOrderedSame;
|
||||
}
|
||||
}];
|
||||
|
||||
_bridge = bridge;
|
||||
_handlers = handlers;
|
||||
_tasksByRequestID = [NSMutableDictionary new];
|
||||
}
|
||||
|
||||
- (id<RCTURLRequestHandler>)handlerForRequest:(NSURLRequest *)request
|
||||
{
|
||||
if (RCT_DEBUG) {
|
||||
// Check for handler conflicts
|
||||
float previousPriority = 0;
|
||||
id<RCTURLRequestHandler> previousHandler = nil;
|
||||
for (id<RCTURLRequestHandler> handler in _handlers) {
|
||||
if ([handler canHandleRequest:request]) {
|
||||
float priority = [handler respondsToSelector:@selector(handlerPriority)] ? [handler handlerPriority] : 0;
|
||||
if (previousHandler) {
|
||||
if (priority == previousPriority) {
|
||||
RCTLogError(@"The RCTURLRequestHandlers %@ and %@ both reported that"
|
||||
" they can handle the request %@, and have equal priority"
|
||||
" (%g). This could result in non-deterministic behavior.",
|
||||
handler, previousHandler, request, priority);
|
||||
}
|
||||
} else {
|
||||
previousHandler = handler;
|
||||
previousPriority = priority;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Normal code path
|
||||
for (id<RCTURLRequestHandler> handler in _handlers) {
|
||||
if ([handler canHandleRequest:request]) {
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (RCTURLRequestCancellationBlock)buildRequest:(NSDictionary *)query
|
||||
@@ -169,37 +223,9 @@ RCT_EXPORT_MODULE()
|
||||
}];
|
||||
}
|
||||
|
||||
- (id<RCTURLRequestHandler>)handlerForRequest:(NSURLRequest *)request
|
||||
- (BOOL)canHandleRequest:(NSURLRequest *)request
|
||||
{
|
||||
NSMutableArray *handlers = [NSMutableArray array];
|
||||
for (id<RCTBridgeModule> module in _bridge.modules.allValues) {
|
||||
if ([module conformsToProtocol:@protocol(RCTURLRequestHandler)]) {
|
||||
if ([(id<RCTURLRequestHandler>)module canHandleRequest:request]) {
|
||||
[handlers addObject:module];
|
||||
}
|
||||
}
|
||||
}
|
||||
[handlers sortUsingComparator:^NSComparisonResult(id<RCTURLRequestHandler> a, id<RCTURLRequestHandler> b) {
|
||||
float priorityA = [a respondsToSelector:@selector(handlerPriority)] ? [a handlerPriority] : 0;
|
||||
float priorityB = [b respondsToSelector:@selector(handlerPriority)] ? [b handlerPriority] : 0;
|
||||
if (priorityA < priorityB) {
|
||||
return NSOrderedAscending;
|
||||
} else if (priorityA > priorityB) {
|
||||
return NSOrderedDescending;
|
||||
} else {
|
||||
RCTLogError(@"The RCTURLRequestHandlers %@ and %@ both reported that"
|
||||
" they can handle the request %@, and have equal priority"
|
||||
" (%g). This could result in non-deterministic behavior.",
|
||||
a, b, request, priorityA);
|
||||
|
||||
return NSOrderedSame;
|
||||
}
|
||||
}];
|
||||
id<RCTURLRequestHandler> handler = handlers.lastObject;
|
||||
if (!handler) {
|
||||
RCTLogError(@"No suitable request handler found for %@", request.URL);
|
||||
}
|
||||
return handler;
|
||||
return [self handlerForRequest:request] != nil;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,13 +260,13 @@ RCT_EXPORT_MODULE()
|
||||
if (request) {
|
||||
|
||||
__block RCTURLRequestCancellationBlock cancellationBlock = nil;
|
||||
RCTDownloadTask *task = [self downloadTaskWithRequest:request completionBlock:^(NSURLResponse *response, NSData *data, NSError *error) {
|
||||
RCTNetworkTask *task = [self networkTaskWithRequest:request completionBlock:^(NSURLResponse *response, NSData *data, NSError *error) {
|
||||
cancellationBlock = callback(error, data ? @{@"body": data, @"contentType": RCTNullIfNil(response.MIMEType)} : nil);
|
||||
}];
|
||||
|
||||
[task start];
|
||||
|
||||
__weak RCTDownloadTask *weakTask = task;
|
||||
__weak RCTNetworkTask *weakTask = task;
|
||||
return ^{
|
||||
[weakTask cancel];
|
||||
if (cancellationBlock) {
|
||||
@@ -259,7 +285,7 @@ RCT_EXPORT_MODULE()
|
||||
return callback(nil, nil);
|
||||
}
|
||||
|
||||
- (void)sendData:(NSData *)data forTask:(RCTDownloadTask *)task
|
||||
- (void)sendData:(NSData *)data forTask:(RCTNetworkTask *)task
|
||||
{
|
||||
if (data.length == 0) {
|
||||
return;
|
||||
@@ -278,7 +304,7 @@ RCT_EXPORT_MODULE()
|
||||
if (!responseText && data.length) {
|
||||
|
||||
// We don't have an encoding, or the encoding is incorrect, so now we
|
||||
// try to guess (unfortunately, this feature is available of iOS 8+ only)
|
||||
// try to guess (unfortunately, this feature is available in iOS 8+ only)
|
||||
if ([NSString respondsToSelector:@selector(stringEncodingForData:
|
||||
encodingOptions:
|
||||
convertedString:
|
||||
@@ -305,7 +331,7 @@ RCT_EXPORT_MODULE()
|
||||
incrementalUpdates:(BOOL)incrementalUpdates
|
||||
responseSender:(RCTResponseSenderBlock)responseSender
|
||||
{
|
||||
__block RCTDownloadTask *task;
|
||||
__block RCTNetworkTask *task;
|
||||
|
||||
RCTURLRequestProgressBlock uploadProgressBlock = ^(int64_t progress, int64_t total) {
|
||||
dispatch_async(_methodQueue, ^{
|
||||
@@ -355,7 +381,7 @@ RCT_EXPORT_MODULE()
|
||||
});
|
||||
};
|
||||
|
||||
task = [self downloadTaskWithRequest:request completionBlock:completionBlock];
|
||||
task = [self networkTaskWithRequest:request completionBlock:completionBlock];
|
||||
task.incrementalDataBlock = incrementalDataBlock;
|
||||
task.responseBlock = responseBlock;
|
||||
task.uploadProgressBlock = uploadProgressBlock;
|
||||
@@ -370,15 +396,16 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
#pragma mark - Public API
|
||||
|
||||
- (RCTDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
|
||||
- (RCTNetworkTask *)networkTaskWithRequest:(NSURLRequest *)request
|
||||
completionBlock:(RCTURLRequestCompletionBlock)completionBlock
|
||||
{
|
||||
id<RCTURLRequestHandler> handler = [self handlerForRequest:request];
|
||||
if (!handler) {
|
||||
RCTLogError(@"No suitable URL request handler found for %@", request.URL);
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [[RCTDownloadTask alloc] initWithRequest:request
|
||||
return [[RCTNetworkTask alloc] initWithRequest:request
|
||||
handler:handler
|
||||
completionBlock:completionBlock];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user