Skip to content

Commit 9e1aaa8

Browse files
committed
Merge branch '0.85-stable' of https://github.com/facebook/react-native into 0.85-stable
2 parents f3f3506 + 410ffb0 commit 9e1aaa8

10 files changed

Lines changed: 127 additions & 35 deletions

File tree

packages/react-native/Libraries/Core/setUpReactDevTools.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,17 +146,34 @@ if (__DEV__) {
146146
? guessHostFromDevServerUrl(devServer.url)
147147
: 'localhost';
148148

149-
// Read the optional global variable for backward compatibility.
150-
// It was added in https://github.com/facebook/react-native/commit/bf2b435322e89d0aeee8792b1c6e04656c2719a0.
151-
const port =
149+
// Derive scheme and port from the dev server URL when possible,
150+
// falling back to ws://host:8097 for local development.
151+
let wsScheme = 'ws';
152+
let port = 8097;
153+
154+
if (
152155
// $FlowFixMe[prop-missing]
153156
// $FlowFixMe[incompatible-use]
154157
window.__REACT_DEVTOOLS_PORT__ != null
155-
? window.__REACT_DEVTOOLS_PORT__
156-
: 8097;
158+
) {
159+
// $FlowFixMe[prop-missing]
160+
port = window.__REACT_DEVTOOLS_PORT__;
161+
} else if (devServer.bundleLoadedFromServer) {
162+
try {
163+
const devUrl = new URL(devServer.url);
164+
if (devUrl.protocol === 'https:') {
165+
wsScheme = 'wss';
166+
}
167+
if (devUrl.port) {
168+
port = parseInt(devUrl.port, 10);
169+
} else if (devUrl.protocol === 'https:') {
170+
port = 443;
171+
}
172+
} catch (e) {}
173+
}
157174

158175
const WebSocket = require('../WebSocket/WebSocket').default;
159-
ws = new WebSocket('ws://' + host + ':' + port);
176+
ws = new WebSocket(wsScheme + '://' + host + ':' + port);
160177
ws.addEventListener('close', event => {
161178
isWebSocketOpen = false;
162179
});

packages/react-native/Libraries/Network/RCTHTTPRequestHandler.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ typedef NSURLSessionConfiguration * (^NSURLSessionConfigurationProvider)(void);
1414
* app.
1515
*/
1616
RCT_EXTERN void RCTSetCustomNSURLSessionConfigurationProvider(NSURLSessionConfigurationProvider /*provider*/);
17+
18+
typedef NSURLRequest *_Nullable (^RCTHTTPRequestInterceptor)(NSURLRequest *request);
19+
/**
20+
* The block provided via this function can inspect/modify HTTP requests before
21+
* they are sent. Return a modified request to override, or nil to use the
22+
* original request unchanged.
23+
*/
24+
RCT_EXTERN void RCTSetCustomHTTPRequestInterceptor(RCTHTTPRequestInterceptor /*interceptor*/);
25+
1726
/**
1827
* This is the default RCTURLRequestHandler implementation for HTTP requests.
1928
*/

packages/react-native/Libraries/Network/RCTHTTPRequestHandler.mm

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ void RCTSetCustomNSURLSessionConfigurationProvider(NSURLSessionConfigurationProv
2525
urlSessionConfigurationProvider = provider;
2626
}
2727

28+
static RCTHTTPRequestInterceptor httpRequestInterceptor;
29+
30+
void RCTSetCustomHTTPRequestInterceptor(RCTHTTPRequestInterceptor interceptor)
31+
{
32+
httpRequestInterceptor = interceptor;
33+
}
34+
2835
@implementation RCTHTTPRequestHandler {
2936
NSMapTable *_delegates;
3037
NSURLSession *_session;
@@ -99,7 +106,14 @@ - (NSURLSessionDataTask *)sendRequest:(NSURLRequest *)request withDelegate:(id<R
99106
valueOptions:NSPointerFunctionsStrongMemory
100107
capacity:0];
101108
}
102-
NSURLSessionDataTask *task = [_session dataTaskWithRequest:request];
109+
NSURLRequest *finalRequest = request;
110+
if (httpRequestInterceptor != nullptr) {
111+
NSURLRequest *intercepted = httpRequestInterceptor(request);
112+
if (intercepted != nil) {
113+
finalRequest = intercepted;
114+
}
115+
}
116+
NSURLSessionDataTask *task = [_session dataTaskWithRequest:finalRequest];
103117
[_delegates setObject:delegate forKey:task];
104118
[task resume];
105119
return task;

packages/react-native/React/Base/RCTMultipartDataTask.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#import <Foundation/Foundation.h>
99

10+
#import <React/RCTDefines.h>
1011
#import <React/RCTMultipartStreamReader.h>
1112

1213
typedef void (^RCTMultipartDataTaskCallback)(
@@ -16,6 +17,14 @@ typedef void (^RCTMultipartDataTaskCallback)(
1617
NSError *error,
1718
BOOL done);
1819

20+
typedef NSURLRequest * _Nullable (^RCTMultipartDataTaskRequestInterceptor)(NSURLRequest *request);
21+
/**
22+
* The block provided via this function can inspect/modify multipart data task
23+
* requests before they are sent. Return a modified request to override, or nil
24+
* to use the original request unchanged.
25+
*/
26+
RCT_EXTERN void RCTSetCustomMultipartDataTaskRequestInterceptor(RCTMultipartDataTaskRequestInterceptor /*interceptor*/);
27+
1928
@interface RCTMultipartDataTask : NSObject
2029

2130
- (instancetype)initWithURL:(NSURL *)url

packages/react-native/React/Base/RCTMultipartDataTask.m

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77

88
#import "RCTMultipartDataTask.h"
99

10+
static RCTMultipartDataTaskRequestInterceptor multipartRequestInterceptor;
11+
12+
void RCTSetCustomMultipartDataTaskRequestInterceptor(RCTMultipartDataTaskRequestInterceptor interceptor)
13+
{
14+
multipartRequestInterceptor = interceptor;
15+
}
16+
1017
#import "RCTDevSupportHttpHeaders.h"
1118

1219
@interface RCTMultipartDataTask () <NSURLSessionDataDelegate, NSURLSessionDataDelegate>
@@ -43,7 +50,15 @@ - (void)startTask
4350
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url];
4451
[request addValue:@"multipart/mixed" forHTTPHeaderField:@"Accept"];
4552
[[RCTDevSupportHttpHeaders sharedInstance] applyHeadersToRequest:request];
46-
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
53+
NSURLRequest *finalRequest = request;
54+
if (multipartRequestInterceptor != nil) {
55+
NSURLRequest *intercepted = multipartRequestInterceptor(request);
56+
if (intercepted != nil) {
57+
finalRequest = intercepted;
58+
}
59+
}
60+
NSLog(@"[RCTMultipartDataTask] %@ %@", finalRequest.HTTPMethod ?: @"GET", finalRequest.URL.absoluteString);
61+
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:finalRequest];
4762
[dataTask resume];
4863
[session finishTasksAndInvalidate];
4964
}

packages/react-native/React/CoreModules/RCTWebSocketModule.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ NS_ASSUME_NONNULL_BEGIN
1818

1919
@end
2020

21+
@class SRWebSocket;
22+
23+
typedef SRWebSocket * (^SRWebSocketProvider)(NSURLRequest *request);
24+
25+
RCT_EXTERN void RCTSetCustomSRWebSocketProvider(SRWebSocketProvider provider);
26+
2127
@interface RCTWebSocketModule : RCTEventEmitter
2228

2329
// Register a custom handler for a specific websocket. The handler will be strongly held by the WebSocketModule.

packages/react-native/React/CoreModules/RCTWebSocketModule.mm

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ @interface RCTWebSocketModule () <SRWebSocketDelegate, NativeWebSocketModuleSpec
3434

3535
@end
3636

37+
static SRWebSocketProvider srWebSocketProvider;
38+
39+
void RCTSetCustomSRWebSocketProvider(SRWebSocketProvider provider)
40+
{
41+
srWebSocketProvider = provider;
42+
}
43+
3744
@implementation RCTWebSocketModule {
3845
NSMutableDictionary<NSNumber *, SRWebSocket *> *_sockets;
3946
NSMutableDictionary<NSNumber *, id<RCTWebSocketContentHandler>> *_contentHandlers;
@@ -88,7 +95,13 @@ - (void)invalidate
8895
}];
8996
}
9097

91-
SRWebSocket *webSocket = [[SRWebSocket alloc] initWithURLRequest:request protocols:protocols];
98+
SRWebSocket *webSocket;
99+
if (srWebSocketProvider != nullptr) {
100+
webSocket = srWebSocketProvider(request);
101+
}
102+
if (webSocket == nil) {
103+
webSocket = [[SRWebSocket alloc] initWithURLRequest:request protocols:protocols];
104+
}
92105
[webSocket setDelegateDispatchQueue:[self methodQueue]];
93106
webSocket.delegate = self;
94107
webSocket.reactTag = @(socketID);

packages/react-native/React/DevSupport/RCTInspectorDevServerHelper.mm

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,33 @@
2020
#import <jsinspector-modern/InspectorFlags.h>
2121

2222
static NSString *const kDebuggerMsgDisable = @"{ \"id\":1,\"method\":\"Debugger.disable\" }";
23+
static const int kDefaultMetroPort = 8081;
2324

2425
static NSString *getServerHost(NSURL *bundleURL)
2526
{
26-
NSNumber *port = @8081;
27-
NSString *portStr = [[[NSProcessInfo processInfo] environment] objectForKey:@"RCT_METRO_PORT"];
28-
if ((portStr != nullptr) && [portStr length] > 0) {
29-
port = [NSNumber numberWithInt:[portStr intValue]];
30-
}
31-
if ([bundleURL port] != nullptr) {
32-
port = [bundleURL port];
33-
}
3427
NSString *host = [bundleURL host];
3528
if (host == nullptr) {
3629
host = @"localhost";
3730
}
3831

39-
// this is consistent with the Android implementation, where http:// is the
40-
// hardcoded implicit scheme for the debug server. Note, packagerURL
41-
// technically looks like it could handle schemes/protocols other than HTTP,
42-
// so rather than force HTTP, leave it be for now, in case someone is relying
43-
// on that ability when developing against iOS.
44-
return [NSString stringWithFormat:@"%@:%@", host, port];
32+
// Use explicit port from URL if available
33+
if ([bundleURL port] != nullptr) {
34+
return [NSString stringWithFormat:@"%@:%@", host, [bundleURL port]];
35+
}
36+
37+
// Check environment variable
38+
NSString *portStr = [[[NSProcessInfo processInfo] environment] objectForKey:@"RCT_METRO_PORT"];
39+
if ((portStr != nullptr) && [portStr length] > 0) {
40+
return [NSString stringWithFormat:@"%@:%@", host, portStr];
41+
}
42+
43+
// For https, omit port — the scheme implies 443
44+
if ([[bundleURL scheme] isEqualToString:@"https"]) {
45+
return host;
46+
}
47+
48+
// Default to 8081 for local development (Metro's default port)
49+
return [NSString stringWithFormat:@"%@:%d", host, kDefaultMetroPort];
4550
}
4651

4752
static NSString *getSHA256(NSString *string)
@@ -112,13 +117,15 @@
112117
NSString *escapedInspectorDeviceId = [getInspectorDeviceId()
113118
stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet];
114119

115-
return [NSURL
116-
URLWithString:[NSString stringWithFormat:@"http://%@/inspector/device?name=%@&app=%@&device=%@&profiling=%@",
117-
getServerHost(bundleURL),
118-
escapedDeviceName,
119-
escapedAppName,
120-
escapedInspectorDeviceId,
121-
isProfilingBuild ? @"true" : @"false"]];
120+
NSString *scheme = [bundleURL scheme] != nullptr ? [bundleURL scheme] : @"http";
121+
return
122+
[NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/inspector/device?name=%@&app=%@&device=%@&profiling=%@",
123+
scheme,
124+
getServerHost(bundleURL),
125+
escapedDeviceName,
126+
escapedAppName,
127+
escapedInspectorDeviceId,
128+
isProfilingBuild ? @"true" : @"false"]];
122129
}
123130

124131
@implementation RCTInspectorDevServerHelper
@@ -150,7 +157,9 @@ + (void)openDebugger:(NSURL *)bundleURL withErrorMessage:(NSString *)errorMessag
150157
NSString *escapedInspectorDeviceId = [getInspectorDeviceId()
151158
stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet];
152159

153-
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@/open-debugger?device=%@",
160+
NSString *scheme = [bundleURL scheme] != nullptr ? [bundleURL scheme] : @"http";
161+
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/open-debugger?device=%@",
162+
scheme,
154163
getServerHost(bundleURL),
155164
escapedInspectorDeviceId]];
156165
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/WebSocketModule.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import com.facebook.react.common.ReactConstants
2222
import com.facebook.react.module.annotations.ReactModule
2323
import com.facebook.react.modules.network.CustomClientBuilder
2424
import com.facebook.react.modules.network.ForwardingCookieHandler
25+
import com.facebook.react.modules.network.OkHttpClientProvider
2526
import java.io.IOException
2627
import java.net.URI
2728
import java.net.URISyntaxException
@@ -80,7 +81,8 @@ public class WebSocketModule(context: ReactApplicationContext) :
8081
) {
8182
val id = socketID.toInt()
8283
val okHttpBuilder =
83-
OkHttpClient.Builder()
84+
OkHttpClientProvider.getOkHttpClient()
85+
.newBuilder()
8486
.connectTimeout(10, TimeUnit.SECONDS)
8587
.writeTimeout(10, TimeUnit.SECONDS)
8688
.readTimeout(0, TimeUnit.MINUTES) // Disable timeouts for read
@@ -198,9 +200,6 @@ public class WebSocketModule(context: ReactApplicationContext) :
198200
}
199201
},
200202
)
201-
202-
// Trigger shutdown of the dispatcher's executor so this process can exit cleanly
203-
client.dispatcher().executorService().shutdown()
204203
}
205204

206205
override fun close(code: Double, reason: String?, socketID: Double) {

packages/react-native/scripts/ios-prebuild/templates/React-umbrella.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
#import <React/RCTDevLoadingViewProtocol.h>
8787
#import <React/RCTDevLoadingViewSetEnabled.h>
8888
#import <React/RCTDevMenu.h>
89+
#import <React/RCTDevSupportHttpHeaders.h>
8990
#import <React/RCTDevSettings.h>
9091
#import <React/RCTDevToolsRuntimeSettingsModule.h>
9192
#import <React/RCTDeviceInfo.h>

0 commit comments

Comments
 (0)