Skip to content

Commit 74995bc

Browse files
robhoganfacebook-github-bot
authored andcommitted
dev-middleware: Generalise URL rewriting, don't only rewrite for Android emulators (#47880)
Summary: Pull Request resolved: #47880 The previous diffs in this stack have aimed to make URL rewriting by inspector-proxy robust to any configuration of device->server, debugger->server and server->server connections. Though rewriting was originally introduced to support Android emulator networking, we can now expand it to cover other use cases, like the device reaching the server over an internet address not reachable from the dev machine, or the debugger routing to the server through a tunnel on a different port, without needing CORS workarounds. Changelog [General][Fixed] dev-middleware: Rewrite URLs in the inspector proxy to cover all configurations, not just Android emulators. Reviewed By: huntie Differential Revision: D66247355 fbshipit-source-id: e9201ebc1f7f5fe2119c71cd4d7b4ca895645404
1 parent aec7a66 commit 74995bc

File tree

4 files changed

+121
-160
lines changed

4 files changed

+121
-160
lines changed

packages/dev-middleware/src/__tests__/InspectorDebuggerUtils.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ export class DebuggerAgent {
2323
#ws: ?WebSocket;
2424
#readyPromise: Promise<void>;
2525

26-
constructor(url: string, signal?: AbortSignal) {
26+
constructor(url: string, signal?: AbortSignal, hostHeader?: ?string) {
2727
const ws = new WebSocket(url, {
2828
// The mock server uses a self-signed certificate.
2929
rejectUnauthorized: false,
30+
...(hostHeader != null ? {headers: {Host: hostHeader}} : {}),
3031
});
3132
this.#ws = ws;
3233
ws.on('message', data => {
@@ -115,8 +116,9 @@ export class DebuggerMock extends DebuggerAgent {
115116
export async function createDebuggerMock(
116117
url: string,
117118
signal: AbortSignal,
119+
hostHeader?: ?string,
118120
): Promise<DebuggerMock> {
119-
const debuggerMock = new DebuggerMock(url, signal);
121+
const debuggerMock = new DebuggerMock(url, signal, hostHeader);
120122
await debuggerMock.ready();
121123
return debuggerMock;
122124
}

packages/dev-middleware/src/__tests__/InspectorProtocolUtils.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,13 @@ export async function createAndConnectTarget(
127127
signal: AbortSignal,
128128
page: PageFromDevice,
129129
{
130+
debuggerHostHeader = null,
130131
deviceId = null,
131-
host = null,
132+
deviceHostHeader = null,
132133
}: $ReadOnly<{
134+
debuggerHostHeader?: ?string,
133135
deviceId?: ?string,
134-
host?: ?string,
136+
deviceHostHeader?: ?string,
135137
}> = {},
136138
): Promise<{device: DeviceMock, debugger_: DebuggerMock}> {
137139
let device;
@@ -142,7 +144,7 @@ export async function createAndConnectTarget(
142144
deviceId ?? 'device' + Date.now()
143145
}&name=foo&app=bar`,
144146
signal,
145-
host,
147+
deviceHostHeader,
146148
);
147149
device.getPages.mockImplementation(() => [page]);
148150

@@ -157,7 +159,11 @@ export async function createAndConnectTarget(
157159
const [{webSocketDebuggerUrl}] = pageList;
158160
expect(webSocketDebuggerUrl).toBeDefined();
159161

160-
debugger_ = await createDebuggerMock(webSocketDebuggerUrl, signal);
162+
debugger_ = await createDebuggerMock(
163+
webSocketDebuggerUrl,
164+
signal,
165+
debuggerHostHeader,
166+
);
161167
await until(() => expect(device.connect).toBeCalled());
162168
} catch (e) {
163169
device?.close();

packages/dev-middleware/src/__tests__/InspectorProxyCdpRewritingHacks-test.js

Lines changed: 24 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ describe.each(['HTTP', 'HTTPS'])(
207207
vm: 'bar-vm',
208208
},
209209
{
210-
host: '192.168.0.123:' + serverRef.port,
210+
deviceHostHeader: '192.168.0.123:' + serverRef.port,
211211
},
212212
);
213213
try {
@@ -240,52 +240,7 @@ describe.each(['HTTP', 'HTTPS'])(
240240
}
241241
});
242242

243-
test('does not rewrite urls in Debugger.scriptParsed that match the device connection host but are not allowlisted for rewriting', async () => {
244-
serverRef.app.use('/source-map', serveStaticJson({version: 3}));
245-
const {device, debugger_} = await createAndConnectTarget(
246-
serverRef,
247-
autoCleanup.signal,
248-
{
249-
app: 'bar-app',
250-
id: 'page1',
251-
title: 'bar-title',
252-
vm: 'bar-vm',
253-
},
254-
{
255-
host: '192.168.0.123:' + serverRef.port,
256-
},
257-
);
258-
try {
259-
let fetchCalledWithURL;
260-
fetchSpy.mockImplementationOnce(url => {
261-
fetchCalledWithURL = url instanceof URL ? url : null;
262-
throw new Error('Unreachable');
263-
});
264-
const sourceMapURL = `${protocol.toLowerCase()}://192.168.0.123:${
265-
serverRef.port
266-
}/source-map`;
267-
const scriptParsedMessage = await sendFromTargetToDebugger(
268-
device,
269-
debugger_,
270-
'page1',
271-
{
272-
method: 'Debugger.scriptParsed',
273-
params: {
274-
sourceMapURL,
275-
},
276-
},
277-
);
278-
expect(fetchCalledWithURL?.href).toEqual(sourceMapURL);
279-
expect(scriptParsedMessage.params.sourceMapURL).toEqual(
280-
`${protocol.toLowerCase()}://192.168.0.123:${serverRef.port}/source-map`,
281-
);
282-
} finally {
283-
device.close();
284-
debugger_.close();
285-
}
286-
});
287-
288-
describe.each(['10.0.2.2', '10.0.3.2', '127.0.0.1'])(
243+
describe.each(['10.0.2.2:8080', '[::1]', 'example.com:2000'])(
289244
'%s aliasing to and from localhost',
290245
sourceHost => {
291246
test('in source map fetching during Debugger.scriptParsed', async () => {
@@ -300,7 +255,7 @@ describe.each(['HTTP', 'HTTPS'])(
300255
vm: 'bar-vm',
301256
},
302257
{
303-
host: sourceHost + ':' + serverRef.port,
258+
deviceHostHeader: sourceHost,
304259
},
305260
);
306261
try {
@@ -311,9 +266,7 @@ describe.each(['HTTP', 'HTTPS'])(
311266
{
312267
method: 'Debugger.scriptParsed',
313268
params: {
314-
sourceMapURL: `${protocol.toLowerCase()}://${sourceHost}:${
315-
serverRef.port
316-
}/source-map`,
269+
sourceMapURL: `${protocol.toLowerCase()}://${sourceHost}/source-map`,
317270
},
318271
},
319272
);
@@ -337,7 +290,8 @@ describe.each(['HTTP', 'HTTPS'])(
337290
vm: 'bar-vm',
338291
},
339292
{
340-
host: sourceHost + ':' + serverRef.port,
293+
debuggerHostHeader: 'localhost:' + serverRef.port,
294+
deviceHostHeader: sourceHost,
341295
},
342296
);
343297
try {
@@ -348,9 +302,7 @@ describe.each(['HTTP', 'HTTPS'])(
348302
{
349303
method: 'Debugger.scriptParsed',
350304
params: {
351-
url: `${protocol.toLowerCase()}://${sourceHost}:${
352-
serverRef.port
353-
}/some/file.js`,
305+
url: `${protocol.toLowerCase()}://${sourceHost}/some/file.js`,
354306
},
355307
},
356308
);
@@ -376,9 +328,7 @@ describe.each(['HTTP', 'HTTPS'])(
376328
},
377329
);
378330
expect(setBreakpointByUrlMessage.params.url).toEqual(
379-
`${protocol.toLowerCase()}://${sourceHost}:${
380-
serverRef.port
381-
}/some/file.js`,
331+
`${protocol.toLowerCase()}://${sourceHost}/some/file.js`,
382332
);
383333

384334
const setBreakpointByUrlRegexMessage =
@@ -390,9 +340,20 @@ describe.each(['HTTP', 'HTTPS'])(
390340
urlRegex: `localhost:${serverRef.port}|example.com:2000`,
391341
},
392342
});
393-
expect(setBreakpointByUrlRegexMessage.params.urlRegex).toEqual(
394-
`${sourceHost.replaceAll('.', '\\.')}:${serverRef.port}|example.com:2000`,
395-
);
343+
344+
// urlRegex rewriting is restricted to specific Android IPs that
345+
// are well-known to route to the host. In this case we only
346+
// replace hostname - longstanding behaviour.
347+
if (sourceHost === '10.0.2.2:8080') {
348+
expect(setBreakpointByUrlRegexMessage.params.urlRegex).toEqual(
349+
`10\\.0\\.2\\.2:${serverRef.port}|example.com:2000`,
350+
);
351+
} else {
352+
// Otherwise expect no change.
353+
expect(setBreakpointByUrlRegexMessage.params.urlRegex).toEqual(
354+
`localhost:${serverRef.port}|example.com:2000`,
355+
);
356+
}
396357
} finally {
397358
device.close();
398359
debugger_.close();
@@ -411,7 +372,7 @@ describe.each(['HTTP', 'HTTPS'])(
411372
vm: 'bar-vm',
412373
},
413374
{
414-
host: sourceHost + ':' + serverRef.port,
375+
deviceHostHeader: sourceHost,
415376
},
416377
);
417378
try {
@@ -451,7 +412,7 @@ describe.each(['HTTP', 'HTTPS'])(
451412
vm: 'bar-vm',
452413
},
453414
{
454-
host: '127.0.0.1:' + serverRef.port,
415+
deviceHostHeader: '127.0.0.1:' + serverRef.port,
455416
},
456417
);
457418
try {

0 commit comments

Comments
 (0)