Inspector proxy: Rewrite 127.0.0.1 to localhost in source map URLs to support IPv4->IPv6 tunnels (#44092)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44092

In a setup where a device retrieves a bundle from `http://127.0.0.1:8081`, but this is tunnelled to a remote host with only an IPv6 stack (eg, FB dev servers), the host running the inspector-proxy will fail to fetch source or source maps from 127.0.0.1 despite typically being on the same host (indeed, process) as Metro.

This causes a surprising inconsistency where using a bundler URL of `localhost` from the device results in source maps being inlined into `Debugger.scriptParsed`, but using a bundler URL of `127.0.0.1` causes inspector-proxy to fall back to preserving URLs, which are typically fetched lazily by CDT later.

This should be unnecessary once we've implemented CDP `Network.loadNetworkResource` and removed `Debugger.scriptParsed` rewriting, but for now it brings IPv6 tunnelled servers in line with local servers.

Changelog:
[General][Changed] Inspector proxy: Rewrite 127.0.0.1 to localhost in source map URLs for better IPv4->IPv6 tunnelling support.

Reviewed By: motiz88

Differential Revision: D56138742

fbshipit-source-id: b65c9cc8225a0ed54cf32171f640ef9e6408c762
This commit is contained in:
Rob Hogan
2024-04-16 03:00:13 -07:00
committed by Facebook GitHub Bot
parent 47c6311422
commit a52bd7dd08
2 changed files with 24 additions and 13 deletions
@@ -192,7 +192,7 @@ describe.each(['HTTP', 'HTTPS'])(
}
});
describe.each(['10.0.2.2', '10.0.3.2'])(
describe.each(['10.0.2.2', '10.0.3.2', '127.0.0.1'])(
'%s aliasing to and from localhost',
sourceHost => {
test('in source map fetching during Debugger.scriptParsed', async () => {
@@ -37,8 +37,21 @@ const debug = require('debug')('Metro:InspectorProxy');
const PAGES_POLLING_INTERVAL = 1000;
// Android's stock emulator and other emulators such as genymotion use a standard localhost alias.
const EMULATOR_LOCALHOST_ADDRESSES: Array<string> = ['10.0.2.2', '10.0.3.2'];
// Replace hosts appearing in the `url` and `sourceMapURL` fields of
// `Debugger.scriptParsed`, and back again in messages from the debugger,
// to account for device/debugger/proxy running on different networks.
const REWRITE_HOSTS_TO_LOCALHOST: Array<string> = [
// A device may retrieve a bundle through 127.0.0.1 via a (SSH) tunnel, but
// the (remote) Metro server may be on a host without an IPv4 loopback, so
// 127.0.0.1 may not be addressible locally for (e.g., for source map
// fetching). Replacing with the more general 'localhost' should always be
// safe while also more compatible with IPv6-only setups.
'127.0.0.1',
// Android's stock emulator and other emulators such as genymotion use a
// standard localhost alias.
'10.0.2.2',
'10.0.3.2',
];
// Prefix for script URLs that are alphanumeric IDs. See comment in #processMessageFromDeviceLegacy method for
// more details.
@@ -621,15 +634,14 @@ export default class Device {
) {
const params = payload.params;
if ('sourceMapURL' in params) {
for (let i = 0; i < EMULATOR_LOCALHOST_ADDRESSES.length; ++i) {
const address = EMULATOR_LOCALHOST_ADDRESSES[i];
if (params.sourceMapURL.includes(address)) {
for (const hostToRewrite of REWRITE_HOSTS_TO_LOCALHOST) {
if (params.sourceMapURL.includes(hostToRewrite)) {
// $FlowFixMe[cannot-write]
payload.params.sourceMapURL = params.sourceMapURL.replace(
address,
hostToRewrite,
'localhost',
);
debuggerInfo.originalSourceURLAddress = address;
debuggerInfo.originalSourceURLAddress = hostToRewrite;
}
}
@@ -654,12 +666,11 @@ export default class Device {
}
}
if ('url' in params) {
for (let i = 0; i < EMULATOR_LOCALHOST_ADDRESSES.length; ++i) {
const address = EMULATOR_LOCALHOST_ADDRESSES[i];
if (params.url.indexOf(address) >= 0) {
for (const hostToRewrite of REWRITE_HOSTS_TO_LOCALHOST) {
if (params.url.includes(hostToRewrite)) {
// $FlowFixMe[cannot-write]
payload.params.url = params.url.replace(address, 'localhost');
debuggerInfo.originalSourceURLAddress = address;
payload.params.url = params.url.replace(hostToRewrite, 'localhost');
debuggerInfo.originalSourceURLAddress = hostToRewrite;
}
}