From c299694c87e9912d4c884b5acec04c708ed0f841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Knutzen?= <2263015+hakonk@users.noreply.github.com> Date: Wed, 2 Jun 2021 18:38:52 -0700 Subject: [PATCH] Custom NSURLSession configuration (#27701) Summary: While it is possible in the React Native implementation for Android to provide a custom configuration for HTTP requests, the iOS implementation does not allow for the same customization. As the NSURLSession used for HTTP requests on iOS is configured internally, one may for instance not supply an ephemeral configuration for HTTP requests. Other concerns related to the given problem have been addressed in the community: https://github.com/react-native-community/discussions-and-proposals/issues/166. I did make a PR with an RFC in the community repo, but after some discussion in the said repo, I figured I might as well make a PR with a suggestion :) ## Changelog [iOS] [Added] - Allow for configuring the NSURLSessionConfiguration Implement a C function `RCTSetCustomNSURLSessionConfigurationProvider` which gives the app programmer the ability to provide a block which provides an NSURLSessionConfiguration that will be used for all HTTP requests instead of the default configuration. The provided block will be called when the session configuration is needed. Pull Request resolved: https://github.com/facebook/react-native/pull/27701 Test Plan: Unsure if this can be tested in any other way than uncommenting the example code in `RNTester/RNTester/AppDelegate.mm`. Reviewed By: yungsters Differential Revision: D28680384 Pulled By: JoshuaGross fbshipit-source-id: ae24399955581a1cc9f4202f0f6f497bfe067a5c --- Libraries/Network/RCTHTTPRequestHandler.h | 5 +++++ Libraries/Network/RCTHTTPRequestHandler.mm | 26 ++++++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/Libraries/Network/RCTHTTPRequestHandler.h b/Libraries/Network/RCTHTTPRequestHandler.h index 75b84eb1224354..5a91bd0a71fa3a 100644 --- a/Libraries/Network/RCTHTTPRequestHandler.h +++ b/Libraries/Network/RCTHTTPRequestHandler.h @@ -8,6 +8,11 @@ #import #import +typedef NSURLSessionConfiguration* (^NSURLSessionConfigurationProvider)(void); +/** + * The block provided via this function will provide the NSURLSessionConfiguration for all HTTP requests made by the app. +*/ +RCT_EXTERN void RCTSetCustomNSURLSessionConfigurationProvider(NSURLSessionConfigurationProvider); /** * This is the default RCTURLRequestHandler implementation for HTTP requests. */ diff --git a/Libraries/Network/RCTHTTPRequestHandler.mm b/Libraries/Network/RCTHTTPRequestHandler.mm index b7f524395a77c6..d160a9e72f9e4f 100644 --- a/Libraries/Network/RCTHTTPRequestHandler.mm +++ b/Libraries/Network/RCTHTTPRequestHandler.mm @@ -18,6 +18,12 @@ @interface RCTHTTPRequestHandler () @end +static NSURLSessionConfigurationProvider urlSessionConfigurationProvider; + +void RCTSetCustomNSURLSessionConfigurationProvider(NSURLSessionConfigurationProvider provider) { + urlSessionConfigurationProvider = provider; +} + @implementation RCTHTTPRequestHandler { NSMapTable *_delegates; @@ -75,14 +81,20 @@ - (NSURLSessionDataTask *)sendRequest:(NSURLRequest *)request NSOperationQueue *callbackQueue = [NSOperationQueue new]; callbackQueue.maxConcurrentOperationCount = 1; callbackQueue.underlyingQueue = [[_moduleRegistry moduleForName:"Networking"] methodQueue]; - NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; - // Set allowsCellularAccess to NO ONLY if key ReactNetworkForceWifiOnly exists AND its value is YES - if (useWifiOnly) { - configuration.allowsCellularAccess = ![useWifiOnly boolValue]; + NSURLSessionConfiguration *configuration; + if (urlSessionConfigurationProvider) { + configuration = urlSessionConfigurationProvider(); + } else { + configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; + // Set allowsCellularAccess to NO ONLY if key ReactNetworkForceWifiOnly exists AND its value is YES + if (useWifiOnly) { + configuration.allowsCellularAccess = ![useWifiOnly boolValue]; + } + [configuration setHTTPShouldSetCookies:YES]; + [configuration setHTTPCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; + [configuration setHTTPCookieStorage:[NSHTTPCookieStorage sharedHTTPCookieStorage]]; } - [configuration setHTTPShouldSetCookies:YES]; - [configuration setHTTPCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; - [configuration setHTTPCookieStorage:[NSHTTPCookieStorage sharedHTTPCookieStorage]]; + assert(configuration != nil); _session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:callbackQueue];