diff --git a/lib/internal/inspect-protocol.js b/lib/internal/inspect-protocol.js index f0c15b0..aeb60f2 100644 --- a/lib/internal/inspect-protocol.js +++ b/lib/internal/inspect-protocol.js @@ -23,6 +23,7 @@ const crypto = require('crypto'); const { EventEmitter } = require('events'); const http = require('http'); +const URL = require('url'); const util = require('util'); const debuglog = util.debuglog('inspect'); @@ -228,7 +229,53 @@ class Client extends EventEmitter { }); } + _fetchJSON(urlPath) { + return new Promise((resolve, reject) => { + const httpReq = http.get({ + host: this._host, + port: this._port, + path: urlPath, + }); + + const chunks = []; + + function onResponse(httpRes) { + function parseChunks() { + const resBody = Buffer.concat(chunks).toString(); + if (httpRes.statusCode !== 200) { + reject(new Error(`Unexpected ${httpRes.statusCode}: ${resBody}`)); + return; + } + try { + resolve(JSON.parse(resBody)); + } catch (parseError) { + reject(new Error(`Response did not contain valid JSON: ${resBody}`)); + return; + } + } + + httpRes.on('error', reject); + httpRes.on('data', chunk => chunks.push(chunk)); + httpRes.on('end', parseChunks); + } + + httpReq.on('error', reject); + httpReq.on('response', onResponse); + }); + } + connect() { + return this._discoverWebsocketPath() + .then(urlPath => this._connectWebsocket(urlPath)); + } + + _discoverWebsocketPath() { + return this._fetchJSON('/json') + .then(([{ webSocketDebuggerUrl }]) => + URL.parse(webSocketDebuggerUrl).path); + } + + _connectWebsocket(urlPath) { this.reset(); const key1 = crypto.randomBytes(16).toString('base64'); @@ -237,11 +284,12 @@ class Client extends EventEmitter { const httpReq = this._http = http.request({ host: this._host, port: this._port, - path: '/node', + path: urlPath, headers: { Connection: 'Upgrade', Upgrade: 'websocket', 'Sec-WebSocket-Key': key1, + 'Sec-WebSocket-Version': '13', }, }); httpReq.on('error', e => { @@ -249,6 +297,7 @@ class Client extends EventEmitter { }); httpReq.on('response', httpRes => { if (httpRes.statusCode >= 400) { + process.stderr.write(`Unexpected HTTP response: ${httpRes.statusCode}\n`); httpRes.pipe(process.stderr); } else { httpRes.pipe(process.stderr);