From 560b2a1677c1a209927d0c8e29c01ff4a6535864 Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Sat, 2 Nov 2024 08:46:20 -0500 Subject: [PATCH] http: add diagnostic channel `http.server.response.created` PR-URL: https://github.com/nodejs/node/pull/55622 Reviewed-By: Matteo Collina Reviewed-By: Paolo Insogna --- doc/api/diagnostics_channel.md | 8 ++++ lib/_http_server.js | 7 +++ ...iagnostic-channel-http-response-created.js | 45 +++++++++++++++++++ .../parallel/test-diagnostics-channel-http.js | 8 ++++ 4 files changed, 68 insertions(+) create mode 100644 test/parallel/test-diagnostic-channel-http-response-created.js diff --git a/doc/api/diagnostics_channel.md b/doc/api/diagnostics_channel.md index 2467329c772..6fa1a57f3ee 100644 --- a/doc/api/diagnostics_channel.md +++ b/doc/api/diagnostics_channel.md @@ -1159,6 +1159,14 @@ Emitted when client receives a response. Emitted when server receives a request. +`http.server.response.created` + +* `request` {http.IncomingMessage} +* `response` {http.ServerResponse} + +Emitted when server creates a response. +The event is emitted before the response is sent. + `http.server.response.finish` * `request` {http.IncomingMessage} diff --git a/lib/_http_server.js b/lib/_http_server.js index c8b38866923..e00d3cac049 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -97,6 +97,7 @@ let debug = require('internal/util/debuglog').debuglog('http', (fn) => { const dc = require('diagnostics_channel'); const onRequestStartChannel = dc.channel('http.server.request.start'); +const onResponseCreatedChannel = dc.channel('http.server.response.created'); const onResponseFinishChannel = dc.channel('http.server.response.finish'); const kServerResponse = Symbol('ServerResponse'); @@ -224,6 +225,12 @@ function ServerResponse(req, options) { this._traceEventId = getNextTraceEventId(); traceBegin(HTTP_SERVER_TRACE_EVENT_NAME, this._traceEventId); } + if (onResponseCreatedChannel.hasSubscribers) { + onResponseCreatedChannel.publish({ + request: req, + response: this, + }); + } } ObjectSetPrototypeOf(ServerResponse.prototype, OutgoingMessage.prototype); ObjectSetPrototypeOf(ServerResponse, OutgoingMessage); diff --git a/test/parallel/test-diagnostic-channel-http-response-created.js b/test/parallel/test-diagnostic-channel-http-response-created.js new file mode 100644 index 00000000000..5dac865a50d --- /dev/null +++ b/test/parallel/test-diagnostic-channel-http-response-created.js @@ -0,0 +1,45 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const dc = require('diagnostics_channel'); + +const isOutgoingMessage = (object) => object instanceof http.OutgoingMessage; +const isIncomingMessage = (object) => object instanceof http.IncomingMessage; + +dc.subscribe('http.server.response.created', common.mustCall(({ + request, + response, +}) => { + assert.strictEqual(request.headers.foo, 'bar'); + assert.strictEqual(response.getHeader('baz'), undefined); + assert.strictEqual(isIncomingMessage(request), true); + assert.strictEqual(isOutgoingMessage(response), true); +})); + +dc.subscribe('http.server.response.finish', common.mustCall(({ + request, + response, +}) => { + assert.strictEqual(request.headers.foo, 'bar'); + assert.strictEqual(response.getHeader('baz'), 'bar'); + assert.strictEqual(isIncomingMessage(request), true); + assert.strictEqual(isOutgoingMessage(response), true); +})); + +const server = http.createServer(common.mustCall((_, res) => { + res.setHeader('baz', 'bar'); + res.end('done'); +})); + +server.listen(() => { + const { port } = server.address(); + http.get({ + port, + headers: { + 'foo': 'bar', + } + }, common.mustCall(() => { + server.close(); + })); +}); diff --git a/test/parallel/test-diagnostics-channel-http.js b/test/parallel/test-diagnostics-channel-http.js index cc212e3f620..fd371a5d259 100644 --- a/test/parallel/test-diagnostics-channel-http.js +++ b/test/parallel/test-diagnostics-channel-http.js @@ -53,6 +53,14 @@ dc.subscribe('http.server.response.finish', common.mustCall(({ assert.strictEqual(isHTTPServer(server), true); })); +dc.subscribe('http.server.response.created', common.mustCall(({ + request, + response, +}) => { + assert.strictEqual(isIncomingMessage(request), true); + assert.strictEqual(isOutgoingMessage(response), true); +})); + dc.subscribe('http.client.request.created', common.mustCall(({ request }) => { assert.strictEqual(isOutgoingMessage(request), true); assert.strictEqual(isHTTPServer(server), true);