Skip to content

Commit 4a59f90

Browse files
hannojgmeta-codesync[bot]
authored andcommitted
fix(ios): devsupport IPv6 host parsing for packager and inspector (#55923)
Summary: When Metro host is an IPv6, iOS dev-support had two parsing issues, causing SIGABRTs): 1. `RCTPackagerConnection` parsed `host:port` by splitting on `:`, which breaks IPv6 literals and can build an invalid websocket URL for `/message`. 2. `RCTInspectorDevServerHelper` used `NSURL.host` directly to compose `host[:port]`. For IPv6, `NSURL.host` is unbracketed, producing an invalid authority for inspector endpoints. Changes: - `RCTPackagerConnection`: parse host/port via `NSURLComponents` from a synthesized URL instead of splitting by `:`. - `RCTInspectorDevServerHelper`: re-add IPv6 brackets when composing authority strings from `NSURL.host`. ## Changelog: [IOS] [FIXED] - Fix iOS dev-support IPv6 handling for packager and inspector connections. Pull Request resolved: #55923 Test Plan: - Built RNTester Debug (Hermes + New Architecture) for iOS simulator. - Started Metro on IPv6: - `RCT_METRO_PORT=8088 yarn --cwd packages/rn-tester start --host :: --port 8088` - Launched RNTester with IPv6 Metro host in settings: - `RCT_packager_scheme = http` - `RCT_jsLocation = [2a02:...]:8088` - Verified in logs: - `http://[2a02:...]:8088/status` returns 200 - bundle loads from `http://[2a02:...]:8088/js/RNTesterApp.ios.bundle?...` - Verified app remains running and renders RNTester UI (no SIGABRT in packager/inspector startup paths). Reviewed By: vzaidman, cortinico Differential Revision: D95564862 Pulled By: cipolleschi fbshipit-source-id: 4fbdf00ca604a2b2ec40dd0ba9b92a146e6b10f2
1 parent 77332d2 commit 4a59f90

2 files changed

Lines changed: 17 additions & 11 deletions

File tree

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
if (host == nullptr) {
2929
host = @"localhost";
3030
}
31+
// NSURL.host strips IPv6 brackets, but URL authority requires them.
32+
if ([host containsString:@":"] && ![host hasPrefix:@"["] && ![host hasSuffix:@"]"]) {
33+
host = [NSString stringWithFormat:@"[%@]", host];
34+
}
3135

3236
// Use explicit port from URL if available
3337
if ([bundleURL port] != nullptr) {

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

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,22 +64,24 @@ - (instancetype)init
6464

6565
static RCTReconnectingWebSocket *socketForLocation(NSString *const serverHostPort, NSString *scheme)
6666
{
67-
NSString *serverHost;
68-
NSString *serverPort;
69-
NSArray *locationComponents = [serverHostPort componentsSeparatedByString:@":"];
70-
if ([locationComponents count] > 0) {
71-
serverHost = locationComponents[0];
72-
}
73-
if ([locationComponents count] > 1) {
74-
serverPort = locationComponents[1];
75-
}
7667
if (![scheme length]) {
7768
scheme = @"http";
7869
}
70+
71+
NSString *location = serverHostPort;
72+
if (![location length]) {
73+
location = @"localhost";
74+
}
75+
76+
NSString *locationURLString = [location rangeOfString:@"://"].location == NSNotFound
77+
? [NSString stringWithFormat:@"%@://%@/", scheme, location]
78+
: location;
79+
NSURLComponents *locationURL = [NSURLComponents componentsWithString:locationURLString];
80+
7981
NSURLComponents *const components = [NSURLComponents new];
80-
components.host = serverHost ?: @"localhost";
82+
components.host = locationURL.host ?: @"localhost";
8183
components.scheme = scheme;
82-
components.port = serverPort ? @(serverPort.integerValue) : @(kRCTBundleURLProviderDefaultPort);
84+
components.port = locationURL.port ?: @(kRCTBundleURLProviderDefaultPort);
8385
components.path = @"/message";
8486
components.queryItems = @[ [NSURLQueryItem queryItemWithName:@"role" value:RCTPlatformName] ];
8587
static dispatch_queue_t queue;

0 commit comments

Comments
 (0)