diff --git a/lib/_http_client.js b/lib/_http_client.js index 065d74268f0df1..09ccd2e4dbf61c 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -24,7 +24,6 @@ const { ArrayIsArray, Boolean, - DateNow, Error, FunctionPrototypeCall, NumberIsFinite, @@ -71,7 +70,6 @@ const { isTraceHTTPEnabled, traceBegin, traceEnd, - getNextInspectorEventId, getNextTraceEventId, } = require('internal/http'); const { @@ -95,14 +93,6 @@ const { stopPerf, } = require('internal/perf/observe'); -const { - isEnabled: isInspectorEnabled, - requestWillBeSent, - responseReceived, - dataReceived, - loadingFinished, -} = internalBinding('inspector'); - const kClientRequestStatistics = Symbol('ClientRequestStatistics'); const dc = require('diagnostics_channel'); @@ -385,7 +375,6 @@ ObjectSetPrototypeOf(ClientRequest, OutgoingMessage); ClientRequest.prototype._finish = function _finish() { FunctionPrototypeCall(OutgoingMessage.prototype._finish, this); - const url = `${this.protocol}//${this.host}${this.path}`; if (hasObserver('http')) { startPerf(this, kClientRequestStatistics, { type: 'http', @@ -393,7 +382,7 @@ ClientRequest.prototype._finish = function _finish() { detail: { req: { method: this.method, - url, + url: `${this.protocol}//${this.host}${this.path}`, headers: typeof this.getHeaders === 'function' ? this.getHeaders() : {}, }, }, @@ -404,14 +393,6 @@ ClientRequest.prototype._finish = function _finish() { request: this, }); } - - if (isInspectorEnabled()) { - this._inspectorEventId = getNextInspectorEventId(); - const wallTime = DateNow(); - const timestamp = wallTime / 1000; - requestWillBeSent(this._inspectorEventId, url, this.method, timestamp, wallTime); - } - if (isTraceHTTPEnabled()) { this._traceEventId = getNextTraceEventId(); traceBegin(HTTP_CLIENT_TRACE_EVENT_NAME, this._traceEventId); @@ -699,21 +680,6 @@ function parserOnIncomingClient(res, shouldKeepAlive) { response: res, }); } - - if (isInspectorEnabled() && typeof req._inspectorEventId === 'string') { - responseReceived(req._inspectorEventId, DateNow() / 1000); - let response = ''; - const onData = (chunk) => { - dataReceived(req._inspectorEventId, DateNow() / 1000, chunk.length); - response += chunk.toString(); - }; - res.on('data', onData); - res.on('end', () => { - loadingFinished(req._inspectorEventId, response, DateNow() / 1000, response.length); - res.removeListener('data', onData); - }); - } - if (isTraceHTTPEnabled() && typeof req._traceEventId === 'number') { traceEnd(HTTP_CLIENT_TRACE_EVENT_NAME, req._traceEventId, { path: req.path, diff --git a/lib/internal/http.js b/lib/internal/http.js index 4fdd69f86747af..da1e8d3332de0e 100644 --- a/lib/internal/http.js +++ b/lib/internal/http.js @@ -31,13 +31,6 @@ function resetCache() { utcCache = undefined; } -let inspectorEventId = 0; - -function getNextInspectorEventId() { - const id = ++inspectorEventId; - return `node-network-inspect-event-${id}`; -} - let traceEventId = 0; function getNextTraceEventId() { @@ -64,7 +57,6 @@ module.exports = { utcDate, traceBegin, traceEnd, - getNextInspectorEventId, getNextTraceEventId, isTraceHTTPEnabled, }; diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js index 27df0a9440a03c..b996e417ee41cc 100644 --- a/lib/internal/process/pre_execution.js +++ b/lib/internal/process/pre_execution.js @@ -3,6 +3,7 @@ const { ArrayPrototypeForEach, Date, + DateNow, DatePrototypeGetDate, DatePrototypeGetFullYear, DatePrototypeGetHours, @@ -98,6 +99,7 @@ function prepareExecution(options) { const mainEntry = patchProcessObject(expandArgv1); setupTraceCategoryState(); setupInspectorHooks(); + setupNetworkInspection(); setupNavigator(); setupWarningHandler(); setupWebStorage(); @@ -438,6 +440,51 @@ function setupInspectorHooks() { } } +function setupNetworkInspection() { + if (!internalBinding('config').hasInspector) { + return; + } + const dc = require('diagnostics_channel'); + const { + dataReceived, + loadingFinished, + requestWillBeSent, + responseReceived, + } = internalBinding('inspector'); + + let requestId = 0; + const getNextRequestId = () => `node-network-event-${++requestId}`; + + dc.subscribe('http.client.request.start', ({ request }) => { + const url = `${request.protocol}//${request.host}${request.path}`; + const wallTime = DateNow(); + const timestamp = wallTime / 1000; + request._inspectorRequestId = getNextRequestId(); + requestWillBeSent(request._inspectorRequestId, url, request.method, timestamp, wallTime); + }); + dc.subscribe('http.client.response.finish', ({ request, response }) => { + responseReceived(request._inspectorRequestId, DateNow() / 1000); + let responseString = ''; + const onData = (chunk) => { + dataReceived(request._inspectorRequestId, DateNow() / 1000, chunk.length); + responseString += chunk.toString(); + }; + response.on('data', onData); + response.on('end', () => { + loadingFinished(request._inspectorRequestId, responseString, DateNow() / 1000, responseString.length); + response.removeListener('data', onData); + }); + }); + + dc.subscribe('undici:request:create', ({ request }) => { + const url = `${request.origin}${request.path}`; + const wallTime = DateNow(); + const timestamp = wallTime / 1000; + request._inspectorRequestId = getNextRequestId(); + requestWillBeSent(request._inspectorRequestId, url, request.method, timestamp, wallTime); + }); +} + // In general deprecations are initialized wherever the APIs are implemented, // this is used to deprecate APIs implemented in C++ where the deprecation // utilities are not easily accessible. diff --git a/src/inspector/network_agent.cc b/src/inspector/network_agent.cc index 657338d60c1a5d..76d7eeec6ed89f 100644 --- a/src/inspector/network_agent.cc +++ b/src/inspector/network_agent.cc @@ -23,6 +23,7 @@ DispatchResponse NetworkAgent::getResponseBody(const String& in_requestId, auto it = request_id_to_response_.find(in_requestId); if (it != request_id_to_response_.end()) { *out_body = it->second; + request_id_to_response_.erase(it); } return DispatchResponse::OK(); } diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index bacd88d9ac17ba..54845ba5f289f8 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -245,6 +245,8 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel, } runtime_agent_->disable(); runtime_agent_.reset(); // Dispose before the dispatchers + network_agent_->disable(); + network_agent_.reset(); // Dispose before the dispatchers } void dispatchProtocolMessage(const StringView& message) {