Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions packages/react-native/Libraries/Core/setUpReactDevTools.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,34 @@ if (__DEV__) {
? guessHostFromDevServerUrl(devServer.url)
: 'localhost';

// Read the optional global variable for backward compatibility.
// It was added in https://github.com/facebook/react-native/commit/bf2b435322e89d0aeee8792b1c6e04656c2719a0.
const port =
// Derive scheme and port from the dev server URL when possible,
// falling back to ws://host:8097 for local development.
let wsScheme = 'ws';
let port = 8097;

if (
// $FlowFixMe[prop-missing]
// $FlowFixMe[incompatible-use]
window.__REACT_DEVTOOLS_PORT__ != null
? window.__REACT_DEVTOOLS_PORT__
: 8097;
) {
// $FlowFixMe[prop-missing]
port = window.__REACT_DEVTOOLS_PORT__;
} else if (devServer.bundleLoadedFromServer) {
try {
const devUrl = new URL(devServer.url);
if (devUrl.protocol === 'https:') {
wsScheme = 'wss';
}
if (devUrl.port) {
port = parseInt(devUrl.port, 10);
} else if (devUrl.protocol === 'https:') {
port = 443;
}
} catch (e) {}
}

const WebSocket = require('../WebSocket/WebSocket').default;
ws = new WebSocket('ws://' + host + ':' + port);
ws = new WebSocket(wsScheme + '://' + host + ':' + port);
ws.addEventListener('close', event => {
isWebSocketOpen = false;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ typedef NSURLSessionConfiguration * (^NSURLSessionConfigurationProvider)(void);
* app.
*/
RCT_EXTERN void RCTSetCustomNSURLSessionConfigurationProvider(NSURLSessionConfigurationProvider /*provider*/);

typedef NSURLRequest *_Nullable (^RCTHTTPRequestInterceptor)(NSURLRequest *request);
/**
* The block provided via this function can inspect/modify HTTP requests before
* they are sent. Return a modified request to override, or nil to use the
* original request unchanged.
*/
RCT_EXTERN void RCTSetCustomHTTPRequestInterceptor(RCTHTTPRequestInterceptor /*interceptor*/);

/**
* This is the default RCTURLRequestHandler implementation for HTTP requests.
*/
Expand Down
16 changes: 15 additions & 1 deletion packages/react-native/Libraries/Network/RCTHTTPRequestHandler.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ void RCTSetCustomNSURLSessionConfigurationProvider(NSURLSessionConfigurationProv
urlSessionConfigurationProvider = provider;
}

static RCTHTTPRequestInterceptor httpRequestInterceptor;

void RCTSetCustomHTTPRequestInterceptor(RCTHTTPRequestInterceptor interceptor)
{
httpRequestInterceptor = interceptor;
}

@implementation RCTHTTPRequestHandler {
NSMapTable *_delegates;
NSURLSession *_session;
Expand Down Expand Up @@ -99,7 +106,14 @@ - (NSURLSessionDataTask *)sendRequest:(NSURLRequest *)request withDelegate:(id<R
valueOptions:NSPointerFunctionsStrongMemory
capacity:0];
}
NSURLSessionDataTask *task = [_session dataTaskWithRequest:request];
NSURLRequest *finalRequest = request;
if (httpRequestInterceptor != nullptr) {
NSURLRequest *intercepted = httpRequestInterceptor(request);
if (intercepted != nil) {
finalRequest = intercepted;
}
}
NSURLSessionDataTask *task = [_session dataTaskWithRequest:finalRequest];
[_delegates setObject:delegate forKey:task];
[task resume];
return task;
Expand Down
6 changes: 6 additions & 0 deletions packages/react-native/React/CoreModules/RCTWebSocketModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ NS_ASSUME_NONNULL_BEGIN

@end

@class SRWebSocket;

typedef SRWebSocket * (^SRWebSocketProvider)(NSURLRequest *request);

RCT_EXTERN void RCTSetCustomSRWebSocketProvider(SRWebSocketProvider provider);

@interface RCTWebSocketModule : RCTEventEmitter

// Register a custom handler for a specific websocket. The handler will be strongly held by the WebSocketModule.
Expand Down
15 changes: 14 additions & 1 deletion packages/react-native/React/CoreModules/RCTWebSocketModule.mm
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ @interface RCTWebSocketModule () <SRWebSocketDelegate, NativeWebSocketModuleSpec

@end

static SRWebSocketProvider srWebSocketProvider;

void RCTSetCustomSRWebSocketProvider(SRWebSocketProvider provider)
{
srWebSocketProvider = provider;
}

@implementation RCTWebSocketModule {
NSMutableDictionary<NSNumber *, SRWebSocket *> *_sockets;
NSMutableDictionary<NSNumber *, id<RCTWebSocketContentHandler>> *_contentHandlers;
Expand Down Expand Up @@ -88,7 +95,13 @@ - (void)invalidate
}];
}

SRWebSocket *webSocket = [[SRWebSocket alloc] initWithURLRequest:request protocols:protocols];
SRWebSocket *webSocket;
if (srWebSocketProvider != nullptr) {
webSocket = srWebSocketProvider(request);
}
if (webSocket == nil) {
webSocket = [[SRWebSocket alloc] initWithURLRequest:request protocols:protocols];
}
[webSocket setDelegateDispatchQueue:[self methodQueue]];
webSocket.delegate = self;
webSocket.reactTag = @(socketID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,33 @@
#import <jsinspector-modern/InspectorFlags.h>

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

static NSString *getServerHost(NSURL *bundleURL)
{
NSNumber *port = @8081;
NSString *portStr = [[[NSProcessInfo processInfo] environment] objectForKey:@"RCT_METRO_PORT"];
if ((portStr != nullptr) && [portStr length] > 0) {
port = [NSNumber numberWithInt:[portStr intValue]];
}
if ([bundleURL port] != nullptr) {
port = [bundleURL port];
}
NSString *host = [bundleURL host];
if (host == nullptr) {
host = @"localhost";
}

// this is consistent with the Android implementation, where http:// is the
// hardcoded implicit scheme for the debug server. Note, packagerURL
// technically looks like it could handle schemes/protocols other than HTTP,
// so rather than force HTTP, leave it be for now, in case someone is relying
// on that ability when developing against iOS.
return [NSString stringWithFormat:@"%@:%@", host, port];
// Use explicit port from URL if available
if ([bundleURL port] != nullptr) {
return [NSString stringWithFormat:@"%@:%@", host, [bundleURL port]];
}

// Check environment variable
NSString *portStr = [[[NSProcessInfo processInfo] environment] objectForKey:@"RCT_METRO_PORT"];
if ((portStr != nullptr) && [portStr length] > 0) {
return [NSString stringWithFormat:@"%@:%@", host, portStr];
}

// For https, omit port — the scheme implies 443
if ([[bundleURL scheme] isEqualToString:@"https"]) {
return host;
}

// Default to 8081 for local development (Metro's default port)
return [NSString stringWithFormat:@"%@:%d", host, kDefaultMetroPort];
}

static NSString *getSHA256(NSString *string)
Expand Down Expand Up @@ -112,13 +117,15 @@
NSString *escapedInspectorDeviceId = [getInspectorDeviceId()
stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet];

return [NSURL
URLWithString:[NSString stringWithFormat:@"http://%@/inspector/device?name=%@&app=%@&device=%@&profiling=%@",
getServerHost(bundleURL),
escapedDeviceName,
escapedAppName,
escapedInspectorDeviceId,
isProfilingBuild ? @"true" : @"false"]];
NSString *scheme = [bundleURL scheme] != nullptr ? [bundleURL scheme] : @"http";
return
[NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/inspector/device?name=%@&app=%@&device=%@&profiling=%@",
scheme,
getServerHost(bundleURL),
escapedDeviceName,
escapedAppName,
escapedInspectorDeviceId,
isProfilingBuild ? @"true" : @"false"]];
}

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

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@/open-debugger?device=%@",
NSString *scheme = [bundleURL scheme] != nullptr ? [bundleURL scheme] : @"http";
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/open-debugger?device=%@",
scheme,
getServerHost(bundleURL),
escapedInspectorDeviceId]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
Expand Down
Loading