Skip to content

Commit 14e3ad0

Browse files
author
Eugene Ostroukhov
committed
inspector: proper WS URLs when bound to 0.0.0.0
JSON target list response will now return appropriate IP address for instances listening on 0.0.0.0. Backport of #11755 PR-URL: #11850 Refs: #11591 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Italo A. Casas <[email protected]> Reviewed-By: James Snell <[email protected]>
1 parent 753adee commit 14e3ad0

4 files changed

+99
-16
lines changed

src/inspector_socket_server.cc

+25-1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,28 @@ void SendProtocolJson(InspectorSocket* socket) {
139139
SendHttpResponse(socket, data);
140140
}
141141

142+
int GetSocketHost(uv_tcp_t* socket, std::string* out_host) {
143+
char ip[INET6_ADDRSTRLEN];
144+
sockaddr_storage addr;
145+
int len = sizeof(addr);
146+
int err = uv_tcp_getsockname(socket,
147+
reinterpret_cast<struct sockaddr*>(&addr),
148+
&len);
149+
if (err != 0)
150+
return err;
151+
if (addr.ss_family == AF_INET6) {
152+
const sockaddr_in6* v6 = reinterpret_cast<const sockaddr_in6*>(&addr);
153+
err = uv_ip6_name(v6, ip, sizeof(ip));
154+
} else {
155+
const sockaddr_in* v4 = reinterpret_cast<const sockaddr_in*>(&addr);
156+
err = uv_ip4_name(v4, ip, sizeof(ip));
157+
}
158+
if (err != 0)
159+
return err;
160+
*out_host = ip;
161+
return err;
162+
}
163+
142164
int GetPort(uv_tcp_t* socket, int* out_port) {
143165
sockaddr_storage addr;
144166
int len = sizeof(addr);
@@ -341,7 +363,9 @@ void InspectorSocketServer::SendListResponse(InspectorSocket* socket) {
341363
}
342364
}
343365
if (!connected) {
344-
std::string address = GetWsUrl(host_, port_, id);
366+
std::string host;
367+
GetSocketHost(&socket->client, &host);
368+
std::string address = GetWsUrl(host, port_, id);
345369
std::ostringstream frontend_url;
346370
frontend_url << "chrome-devtools://devtools/bundled";
347371
frontend_url << "/inspector.html?experiments=true&v8only=true&ws=";

test/inspector/inspector-helper.js

+16-9
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ function tearDown(child, err) {
8080
}
8181
}
8282

83-
function checkHttpResponse(port, path, callback) {
84-
http.get({port, path}, function(res) {
83+
function checkHttpResponse(host, port, path, callback, errorcb) {
84+
const req = http.get({host, port, path}, function(res) {
8585
let response = '';
8686
res.setEncoding('utf8');
8787
res
@@ -98,6 +98,8 @@ function checkHttpResponse(port, path, callback) {
9898
callback(err, json);
9999
});
100100
});
101+
if (errorcb)
102+
req.on('error', errorcb);
101103
}
102104

103105
function makeBufferingDataCallback(dataCallback) {
@@ -295,7 +297,7 @@ TestSession.prototype.disconnect = function(childDone) {
295297

296298
TestSession.prototype.testHttpResponse = function(path, check) {
297299
return this.enqueue((callback) =>
298-
checkHttpResponse(this.harness_.port, path, (err, response) => {
300+
checkHttpResponse(null, this.harness_.port, path, (err, response) => {
299301
check.call(this, err, response);
300302
callback();
301303
}));
@@ -361,12 +363,17 @@ Harness.prototype.enqueue_ = function(task) {
361363
return this;
362364
};
363365

364-
Harness.prototype.testHttpResponse = function(path, check) {
366+
Harness.prototype.testHttpResponse = function(host, path, check, errorcb) {
365367
return this.enqueue_((doneCallback) => {
366-
checkHttpResponse(this.port, path, (err, response) => {
367-
check.call(this, err, response);
368-
doneCallback();
369-
});
368+
function wrap(callback) {
369+
if (callback) {
370+
return function() {
371+
callback(...arguments);
372+
doneCallback();
373+
};
374+
}
375+
}
376+
checkHttpResponse(host, this.port, path, wrap(check), wrap(errorcb));
370377
});
371378
};
372379

@@ -404,7 +411,7 @@ Harness.prototype.wsHandshake = function(devtoolsUrl, tests, readyCallback) {
404411

405412
Harness.prototype.runFrontendSession = function(tests) {
406413
return this.enqueue_((callback) => {
407-
checkHttpResponse(this.port, '/json/list', (err, response) => {
414+
checkHttpResponse(null, this.port, '/json/list', (err, response) => {
408415
assert.ifError(err);
409416
this.wsHandshake(response[0]['webSocketDebuggerUrl'], tests, callback);
410417
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
const common = require('../common');
3+
common.skipIfInspectorDisabled && common.skipIfInspectorDisabled();
4+
5+
const assert = require('assert');
6+
const helper = require('./inspector-helper.js');
7+
const os = require('os');
8+
9+
const ip = pickIPv4Address();
10+
11+
if (!ip) {
12+
common.skip('No IP address found');
13+
return;
14+
}
15+
16+
function checkListResponse(instance, err, response) {
17+
assert.ifError(err);
18+
const res = response[0];
19+
const wsUrl = res['webSocketDebuggerUrl'];
20+
assert.ok(wsUrl);
21+
const match = wsUrl.match(/^ws:\/\/(.*):9229\/(.*)/);
22+
assert.strictEqual(ip, match[1]);
23+
assert.strictEqual(res['id'], match[2]);
24+
assert.strictEqual(ip, res['devtoolsFrontendUrl'].match(/.*ws=(.*):9229/)[1]);
25+
instance.childInstanceDone = true;
26+
}
27+
28+
function checkError(instance, error) {
29+
// Some OSes will not allow us to connect
30+
if (error.code === 'EHOSTUNREACH') {
31+
common.skip('Unable to connect to self');
32+
} else {
33+
throw error;
34+
}
35+
instance.childInstanceDone = true;
36+
}
37+
38+
function runTests(instance) {
39+
instance
40+
.testHttpResponse(ip, '/json/list', checkListResponse.bind(null, instance),
41+
checkError.bind(null, instance))
42+
.kill();
43+
}
44+
45+
function pickIPv4Address() {
46+
for (const i of [].concat(...Object.values(os.networkInterfaces()))) {
47+
if (i.family === 'IPv4' && i.address !== '127.0.0.1')
48+
return i.address;
49+
}
50+
}
51+
52+
helper.startNodeForInspectorTest(runTests, '--inspect-brk=0.0.0.0');

test/inspector/test-inspector.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,12 @@ function testWaitsForFrontendDisconnect(session, harness) {
208208

209209
function runTests(harness) {
210210
harness
211-
.testHttpResponse('/json', checkListResponse)
212-
.testHttpResponse('/json/list', checkListResponse)
213-
.testHttpResponse('/json/version', checkVersion)
214-
.testHttpResponse('/json/activate', checkBadPath)
215-
.testHttpResponse('/json/activate/boom', checkBadPath)
216-
.testHttpResponse('/json/badpath', checkBadPath)
211+
.testHttpResponse(null, '/json', checkListResponse)
212+
.testHttpResponse(null, '/json/list', checkListResponse)
213+
.testHttpResponse(null, '/json/version', checkVersion)
214+
.testHttpResponse(null, '/json/activate', checkBadPath)
215+
.testHttpResponse(null, '/json/activate/boom', checkBadPath)
216+
.testHttpResponse(null, '/json/badpath', checkBadPath)
217217
.runFrontendSession([
218218
testNoUrlsWhenConnected,
219219
testBreakpointOnStart,

0 commit comments

Comments
 (0)