From 143bb0afbce8cd65a281784b8291aadb2b4f51f0 Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Wed, 3 Jan 2024 12:24:14 +0100 Subject: [PATCH 01/10] feat: add debug support through diagnostics channel --- lib/core/diagnostics.js | 214 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 lib/core/diagnostics.js diff --git a/lib/core/diagnostics.js b/lib/core/diagnostics.js new file mode 100644 index 00000000000..e97207c6108 --- /dev/null +++ b/lib/core/diagnostics.js @@ -0,0 +1,214 @@ +let channels +try { + const diagnosticsChannel = require('diagnostics_channel') + let isClientSet = false + channels = { + // Client + beforeConnect: diagnosticsChannel.channel('undici:client:beforeConnect'), + connected: diagnosticsChannel.channel('undici:client:connected'), + connectError: diagnosticsChannel.channel('undici:client:connectError'), + sendHeaders: diagnosticsChannel.channel('undici:client:sendHeaders'), + // Request + create: diagnosticsChannel.channel('undici:request:create'), + bodySent: diagnosticsChannel.channel('undici:request:bodySent'), + headers: diagnosticsChannel.channel('undici:request:headers'), + trailers: diagnosticsChannel.channel('undici:request:trailers'), + error: diagnosticsChannel.channel('undici:request:error'), + // WebSocket + open: diagnosticsChannel.channel('undici:websocket:open'), + close: diagnosticsChannel.channel('undici:websocket:close'), + socketError: diagnosticsChannel.channel('undici:websocket:socket_error'), + ping: diagnosticsChannel.channel('undici:websocket:ping'), + pong: diagnosticsChannel.channel('undici:websocket:pong') + } + + if (process.env.NODE_DEBUG.match(/(fetch|undici)/) != null) { + // Track all Client events + diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => { + const { + connectParams: { version, protocol, port, host } + } = evt + console.log( + `HTTP:undici ${process.pid}: connecting to ${host}${ + port ? `:${port}` : '' + } using ${protocol}${version}` + ) + }) + + diagnosticsChannel.channel('undici:client:connected').subscribe(evt => { + const { + connectParams: { version, protocol, port, host } + } = evt + console.log( + `HTTP:undici ${process.pid}: connected to ${host}${ + port ? `:${port}` : '' + } using ${protocol}${version}` + ) + }) + + diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => { + const { + connectParams: { version, protocol, port, host }, + error + } = evt + console.log( + `HTTP:undici ${process.pid}: connection to ${host}${ + port ? `:${port}` : '' + } using ${protocol}${version} errored - ${error.message}` + ) + }) + + diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => { + const { + request: { method, path, origin } + } = evt + console.log( + `HTTP:undici ${process.pid}: sending request to ${method} ${origin}/${path}` + ) + }) + + // Track Request events + diagnosticsChannel.channel('undici:request:headers').subscribe(evt => { + const { + request: { method, path, origin }, + response: { statusCode } + } = evt + console.log( + `HTTP:undici ${process.pid}: received response ${method} ${origin}/${path} - HTTP ${statusCode}` + ) + }) + + diagnosticsChannel.channel('undici:request:trailers').subscribe(evt => { + const { + request: { method, path, origin } + } = evt + console.log( + `HTTP:undici ${process.pid}: trailers received from ${method} ${origin}/${path}` + ) + }) + + diagnosticsChannel.channel('undici:request:error').subscribe(evt => { + const { + request: { method, path, origin }, + error + } = evt + console.log( + `HTTP:undici ${process.pid}: request errored ${method} ${origin}/${path} - ${error.message}` + ) + }) + + isClientSet = true + } + + if (process.env.NODE_DEBUG.match(/websocket/) != null) { + if (!isClientSet) { + diagnosticsChannel + .channel('undici:client:beforeConnect') + .subscribe(evt => { + const { + connectParams: { version, protocol, port, host } + } = evt + console.log( + `HTTP:undici ${process.pid}: connecting to ${host}${ + port ? `:${port}` : '' + } using ${protocol}${version}` + ) + }) + + diagnosticsChannel.channel('undici:client:connected').subscribe(evt => { + const { + connectParams: { version, protocol, port, host } + } = evt + console.log( + `HTTP:undici ${process.pid}: connected to ${host}${ + port ? `:${port}` : '' + } using ${protocol}${version}` + ) + }) + + diagnosticsChannel + .channel('undici:client:connectError') + .subscribe(evt => { + const { + connectParams: { version, protocol, port, host }, + error + } = evt + console.log( + `HTTP:undici ${process.pid}: connection to ${host}${ + port ? `:${port}` : '' + } using ${protocol}${version} errored - ${error.message}` + ) + }) + + diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => { + const { + request: { method, path, origin } + } = evt + console.log( + `HTTP:undici ${process.pid}: sending request to ${method} ${origin}/${path}` + ) + }) + } + + // Track all Client events + diagnosticsChannel.channel('undici:websocket:open').subscribe(evt => { + const { + address: { address, port }, + protocol, + extensions + } = evt + console.log( + `WebSocket:undici ${process.pid}: connection opened ${address}${ + port ? `:${port}` : '' + } using ${protocol}-${extensions}` + ) + }) + + diagnosticsChannel.channel('undici:websocket:close').subscribe(evt => { + const { websocket, code, reason } = evt + console.log( + `WebSocket:undici ${process.pid}: closed connection to ${websocket.url} - ${code} ${reason}` + ) + }) + + diagnosticsChannel + .channel('undici:websocket:socket_error') + .subscribe(err => { + console.log( + `WebSocket:undici ${process.pid}: connection errored - ${err.message}` + ) + }) + + diagnosticsChannel.channel('undici:websocket:ping').subscribe(evt => { + console.log(`WebSocket:undici ${process.pid}: ping received`) + }) + + diagnosticsChannel.channel('undici:websocket:pong').subscribe(evt => { + console.log(`WebSocket:undici ${process.pid}: pong received`) + }) + } +} catch (error) { + channels = { + // Client + sendHeaders: { hasSubcribers: false }, + beforeConnect: { hasSubcribers: false }, + connectError: { hasSubcribers: false }, + connected: { hasSubcribers: false }, + // Request + create: { hasSubcribers: false }, + bodySent: { hasSubcribers: false }, + headers: { hasSubcribers: false }, + trailers: { hasSubcribers: false }, + error: { hasSubcribers: false }, + // WebSocket + open: { hasSubcribers: false }, + close: { hasSubcribers: false }, + socketError: { hasSubcribers: false }, + ping: { hasSubcribers: false }, + pong: { hasSubcribers: false } + } +} + +module.exports = { + channels +} From 67be3a8800e01e012899b4895be28c1983770986 Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Wed, 3 Jan 2024 12:24:56 +0100 Subject: [PATCH 02/10] refactor: replace old diagnostics with new abstraction --- lib/client.js | 31 +++++++++++++++++-------------- lib/core/request.js | 31 ++++++++++++++++--------------- lib/websocket/connection.js | 10 +++++----- lib/websocket/receiver.js | 8 ++++---- 4 files changed, 42 insertions(+), 38 deletions(-) diff --git a/lib/client.js b/lib/client.js index 25f3478490e..377e2e4d52f 100644 --- a/lib/client.js +++ b/lib/client.js @@ -9,6 +9,7 @@ const net = require('net') const http = require('http') const { pipeline } = require('stream') const util = require('./core/util') +const { channels } = require('./core/diagnostics') const timers = require('./timers') const Request = require('./core/request') const DispatcherBase = require('./dispatcher-base') @@ -108,20 +109,20 @@ const FastBuffer = Buffer[Symbol.species] const kClosedResolve = Symbol('kClosedResolve') -const channels = {} - -try { - const diagnosticsChannel = require('diagnostics_channel') - channels.sendHeaders = diagnosticsChannel.channel('undici:client:sendHeaders') - channels.beforeConnect = diagnosticsChannel.channel('undici:client:beforeConnect') - channels.connectError = diagnosticsChannel.channel('undici:client:connectError') - channels.connected = diagnosticsChannel.channel('undici:client:connected') -} catch { - channels.sendHeaders = { hasSubscribers: false } - channels.beforeConnect = { hasSubscribers: false } - channels.connectError = { hasSubscribers: false } - channels.connected = { hasSubscribers: false } -} +// const channels = {} + +// try { +// const diagnosticsChannel = require('diagnostics_channel') +// channels.sendHeaders = diagnosticsChannel.channel('undici:client:sendHeaders') +// channels.beforeConnect = diagnosticsChannel.channel('undici:client:beforeConnect') +// channels.connectError = diagnosticsChannel.channel('undici:client:connectError') +// channels.connected = diagnosticsChannel.channel('undici:client:connected') +// } catch { +// channels.sendHeaders = { hasSubscribers: false } +// channels.beforeConnect = { hasSubscribers: false } +// channels.connectError = { hasSubscribers: false } +// channels.connected = { hasSubscribers: false } +// } /** * @type {import('../types/client').default} @@ -1191,6 +1192,7 @@ async function connect (client) { hostname, protocol, port, + version: client[kHTTPConnVersion], servername: client[kServerName], localAddress: client[kLocalAddress] }, @@ -1284,6 +1286,7 @@ async function connect (client) { hostname, protocol, port, + version: client[kHTTPConnVersion], servername: client[kServerName], localAddress: client[kLocalAddress] }, diff --git a/lib/core/request.js b/lib/core/request.js index fe63434ea98..dc706fc1981 100644 --- a/lib/core/request.js +++ b/lib/core/request.js @@ -7,6 +7,7 @@ const { const assert = require('assert') const { kHTTP2BuildRequest, kHTTP2CopyHeaders, kHTTP1BuildRequest } = require('./symbols') const util = require('./util') +const { channels } = require('./diagnostics.js') const { headerNameLowerCasedRecord } = require('./constants') // headerCharRegex have been lifted from @@ -25,24 +26,24 @@ const invalidPathRegex = /[^\u0021-\u00ff]/ const kHandler = Symbol('handler') -const channels = {} +// const channels = {} let extractBody -try { - const diagnosticsChannel = require('diagnostics_channel') - channels.create = diagnosticsChannel.channel('undici:request:create') - channels.bodySent = diagnosticsChannel.channel('undici:request:bodySent') - channels.headers = diagnosticsChannel.channel('undici:request:headers') - channels.trailers = diagnosticsChannel.channel('undici:request:trailers') - channels.error = diagnosticsChannel.channel('undici:request:error') -} catch { - channels.create = { hasSubscribers: false } - channels.bodySent = { hasSubscribers: false } - channels.headers = { hasSubscribers: false } - channels.trailers = { hasSubscribers: false } - channels.error = { hasSubscribers: false } -} +// try { +// const diagnosticsChannel = require('diagnostics_channel') +// channels.create = diagnosticsChannel.channel('undici:request:create') +// channels.bodySent = diagnosticsChannel.channel('undici:request:bodySent') +// channels.headers = diagnosticsChannel.channel('undici:request:headers') +// channels.trailers = diagnosticsChannel.channel('undici:request:trailers') +// channels.error = diagnosticsChannel.channel('undici:request:error') +// } catch { +// channels.create = { hasSubscribers: false } +// channels.bodySent = { hasSubscribers: false } +// channels.headers = { hasSubscribers: false } +// channels.trailers = { hasSubscribers: false } +// channels.error = { hasSubscribers: false } +// } class Request { constructor (origin, { diff --git a/lib/websocket/connection.js b/lib/websocket/connection.js index 4bc60b3b90b..7ca9b176ed5 100644 --- a/lib/websocket/connection.js +++ b/lib/websocket/connection.js @@ -1,6 +1,5 @@ 'use strict' -const diagnosticsChannel = require('diagnostics_channel') const { uid, states } = require('./constants') const { kReadyState, @@ -9,6 +8,7 @@ const { kReceivedClose } = require('./symbols') const { fireEvent, failWebsocketConnection } = require('./util') +const { channels } = require('../core/diagnostics') const { CloseEvent } = require('./events') const { makeRequest } = require('../fetch/request') const { fetching } = require('../fetch/index') @@ -16,10 +16,10 @@ const { Headers } = require('../fetch/headers') const { getGlobalDispatcher } = require('../global') const { kHeadersList } = require('../core/symbols') -const channels = {} -channels.open = diagnosticsChannel.channel('undici:websocket:open') -channels.close = diagnosticsChannel.channel('undici:websocket:close') -channels.socketError = diagnosticsChannel.channel('undici:websocket:socket_error') +// const channels = {} +// channels.open = diagnosticsChannel.channel('undici:websocket:open') +// channels.close = diagnosticsChannel.channel('undici:websocket:close') +// channels.socketError = diagnosticsChannel.channel('undici:websocket:socket_error') /** @type {import('crypto')} */ let crypto diff --git a/lib/websocket/receiver.js b/lib/websocket/receiver.js index bdd2031b418..4822bcf9531 100644 --- a/lib/websocket/receiver.js +++ b/lib/websocket/receiver.js @@ -1,9 +1,9 @@ 'use strict' const { Writable } = require('stream') -const diagnosticsChannel = require('diagnostics_channel') const { parserStates, opcodes, states, emptyBuffer } = require('./constants') const { kReadyState, kSentClose, kResponse, kReceivedClose } = require('./symbols') +const { channels } = require('../core/diagnostics') const { isValidStatusCode, failWebsocketConnection, websocketMessageReceived } = require('./util') const { WebsocketFrameSend } = require('./frame') @@ -12,9 +12,9 @@ const { WebsocketFrameSend } = require('./frame') // Copyright (c) 2013 Arnout Kazemier and contributors // Copyright (c) 2016 Luigi Pinca and contributors -const channels = {} -channels.ping = diagnosticsChannel.channel('undici:websocket:ping') -channels.pong = diagnosticsChannel.channel('undici:websocket:pong') +// const channels = {} +// channels.ping = diagnosticsChannel.channel('undici:websocket:ping') +// channels.pong = diagnosticsChannel.channel('undici:websocket:pong') class ByteParser extends Writable { #buffers = [] From 5750b6e340e04545ac7ce6fbe6c10437913314a7 Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Fri, 5 Jan 2024 10:36:16 +0100 Subject: [PATCH 03/10] refactor: handle diagnostics simpler --- lib/core/diagnostics.js | 300 ++++++++++++++++++---------------------- 1 file changed, 136 insertions(+), 164 deletions(-) diff --git a/lib/core/diagnostics.js b/lib/core/diagnostics.js index e97207c6108..16c3c8e1dc2 100644 --- a/lib/core/diagnostics.js +++ b/lib/core/diagnostics.js @@ -1,29 +1,106 @@ -let channels -try { - const diagnosticsChannel = require('diagnostics_channel') - let isClientSet = false - channels = { - // Client - beforeConnect: diagnosticsChannel.channel('undici:client:beforeConnect'), - connected: diagnosticsChannel.channel('undici:client:connected'), - connectError: diagnosticsChannel.channel('undici:client:connectError'), - sendHeaders: diagnosticsChannel.channel('undici:client:sendHeaders'), - // Request - create: diagnosticsChannel.channel('undici:request:create'), - bodySent: diagnosticsChannel.channel('undici:request:bodySent'), - headers: diagnosticsChannel.channel('undici:request:headers'), - trailers: diagnosticsChannel.channel('undici:request:trailers'), - error: diagnosticsChannel.channel('undici:request:error'), - // WebSocket - open: diagnosticsChannel.channel('undici:websocket:open'), - close: diagnosticsChannel.channel('undici:websocket:close'), - socketError: diagnosticsChannel.channel('undici:websocket:socket_error'), - ping: diagnosticsChannel.channel('undici:websocket:ping'), - pong: diagnosticsChannel.channel('undici:websocket:pong') - } +const diagnosticsChannel = require('diagnostics_channel') + +let isClientSet = false +const channels = { + // Client + beforeConnect: diagnosticsChannel.channel('undici:client:beforeConnect'), + connected: diagnosticsChannel.channel('undici:client:connected'), + connectError: diagnosticsChannel.channel('undici:client:connectError'), + sendHeaders: diagnosticsChannel.channel('undici:client:sendHeaders'), + // Request + create: diagnosticsChannel.channel('undici:request:create'), + bodySent: diagnosticsChannel.channel('undici:request:bodySent'), + headers: diagnosticsChannel.channel('undici:request:headers'), + trailers: diagnosticsChannel.channel('undici:request:trailers'), + error: diagnosticsChannel.channel('undici:request:error'), + // WebSocket + open: diagnosticsChannel.channel('undici:websocket:open'), + close: diagnosticsChannel.channel('undici:websocket:close'), + socketError: diagnosticsChannel.channel('undici:websocket:socket_error'), + ping: diagnosticsChannel.channel('undici:websocket:ping'), + pong: diagnosticsChannel.channel('undici:websocket:pong') +} + +if (process.env.NODE_DEBUG?.match(/(fetch|undici)/) != null) { + // Track all Client events + diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => { + const { + connectParams: { version, protocol, port, host } + } = evt + console.log( + `HTTP:undici ${process.pid}: connecting to ${host}${ + port ? `:${port}` : '' + } using ${protocol}${version}` + ) + }) + + diagnosticsChannel.channel('undici:client:connected').subscribe(evt => { + const { + connectParams: { version, protocol, port, host } + } = evt + console.log( + `HTTP:undici ${process.pid}: connected to ${host}${ + port ? `:${port}` : '' + } using ${protocol}${version}` + ) + }) + + diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => { + const { + connectParams: { version, protocol, port, host }, + error + } = evt + console.log( + `HTTP:undici ${process.pid}: connection to ${host}${ + port ? `:${port}` : '' + } using ${protocol}${version} errored - ${error.message}` + ) + }) + + diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => { + const { + request: { method, path, origin } + } = evt + console.log( + `HTTP:undici ${process.pid}: sending request to ${method} ${origin}/${path}` + ) + }) + + // Track Request events + diagnosticsChannel.channel('undici:request:headers').subscribe(evt => { + const { + request: { method, path, origin }, + response: { statusCode } + } = evt + console.log( + `HTTP:undici ${process.pid}: received response ${method} ${origin}/${path} - HTTP ${statusCode}` + ) + }) + + diagnosticsChannel.channel('undici:request:trailers').subscribe(evt => { + const { + request: { method, path, origin } + } = evt + console.log( + `HTTP:undici ${process.pid}: trailers received from ${method} ${origin}/${path}` + ) + }) + + diagnosticsChannel.channel('undici:request:error').subscribe(evt => { + const { + request: { method, path, origin }, + error + } = evt + console.log( + `HTTP:undici ${process.pid}: request errored ${method} ${origin}/${path} - ${error.message}` + ) + }) + + isClientSet = true +} - if (process.env.NODE_DEBUG.match(/(fetch|undici)/) != null) { - // Track all Client events +if (process.env.NODE_DEBUG?.match(/websocket/) != null) { + if (!isClientSet) { diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => { const { connectParams: { version, protocol, port, host } @@ -66,147 +143,42 @@ try { `HTTP:undici ${process.pid}: sending request to ${method} ${origin}/${path}` ) }) - - // Track Request events - diagnosticsChannel.channel('undici:request:headers').subscribe(evt => { - const { - request: { method, path, origin }, - response: { statusCode } - } = evt - console.log( - `HTTP:undici ${process.pid}: received response ${method} ${origin}/${path} - HTTP ${statusCode}` - ) - }) - - diagnosticsChannel.channel('undici:request:trailers').subscribe(evt => { - const { - request: { method, path, origin } - } = evt - console.log( - `HTTP:undici ${process.pid}: trailers received from ${method} ${origin}/${path}` - ) - }) - - diagnosticsChannel.channel('undici:request:error').subscribe(evt => { - const { - request: { method, path, origin }, - error - } = evt - console.log( - `HTTP:undici ${process.pid}: request errored ${method} ${origin}/${path} - ${error.message}` - ) - }) - - isClientSet = true } - if (process.env.NODE_DEBUG.match(/websocket/) != null) { - if (!isClientSet) { - diagnosticsChannel - .channel('undici:client:beforeConnect') - .subscribe(evt => { - const { - connectParams: { version, protocol, port, host } - } = evt - console.log( - `HTTP:undici ${process.pid}: connecting to ${host}${ - port ? `:${port}` : '' - } using ${protocol}${version}` - ) - }) - - diagnosticsChannel.channel('undici:client:connected').subscribe(evt => { - const { - connectParams: { version, protocol, port, host } - } = evt - console.log( - `HTTP:undici ${process.pid}: connected to ${host}${ - port ? `:${port}` : '' - } using ${protocol}${version}` - ) - }) - - diagnosticsChannel - .channel('undici:client:connectError') - .subscribe(evt => { - const { - connectParams: { version, protocol, port, host }, - error - } = evt - console.log( - `HTTP:undici ${process.pid}: connection to ${host}${ - port ? `:${port}` : '' - } using ${protocol}${version} errored - ${error.message}` - ) - }) - - diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => { - const { - request: { method, path, origin } - } = evt - console.log( - `HTTP:undici ${process.pid}: sending request to ${method} ${origin}/${path}` - ) - }) - } - - // Track all Client events - diagnosticsChannel.channel('undici:websocket:open').subscribe(evt => { - const { - address: { address, port }, - protocol, - extensions - } = evt - console.log( - `WebSocket:undici ${process.pid}: connection opened ${address}${ - port ? `:${port}` : '' - } using ${protocol}-${extensions}` - ) - }) - - diagnosticsChannel.channel('undici:websocket:close').subscribe(evt => { - const { websocket, code, reason } = evt - console.log( - `WebSocket:undici ${process.pid}: closed connection to ${websocket.url} - ${code} ${reason}` - ) - }) - - diagnosticsChannel - .channel('undici:websocket:socket_error') - .subscribe(err => { - console.log( - `WebSocket:undici ${process.pid}: connection errored - ${err.message}` - ) - }) - - diagnosticsChannel.channel('undici:websocket:ping').subscribe(evt => { - console.log(`WebSocket:undici ${process.pid}: ping received`) - }) - - diagnosticsChannel.channel('undici:websocket:pong').subscribe(evt => { - console.log(`WebSocket:undici ${process.pid}: pong received`) - }) - } -} catch (error) { - channels = { - // Client - sendHeaders: { hasSubcribers: false }, - beforeConnect: { hasSubcribers: false }, - connectError: { hasSubcribers: false }, - connected: { hasSubcribers: false }, - // Request - create: { hasSubcribers: false }, - bodySent: { hasSubcribers: false }, - headers: { hasSubcribers: false }, - trailers: { hasSubcribers: false }, - error: { hasSubcribers: false }, - // WebSocket - open: { hasSubcribers: false }, - close: { hasSubcribers: false }, - socketError: { hasSubcribers: false }, - ping: { hasSubcribers: false }, - pong: { hasSubcribers: false } - } + // Track all WebSocket events + diagnosticsChannel.channel('undici:websocket:open').subscribe(evt => { + const { + address: { address, port }, + protocol, + extensions + } = evt + console.log( + `WebSocket:undici ${process.pid}: connection opened ${address}${ + port ? `:${port}` : '' + } using ${protocol}-${extensions}` + ) + }) + + diagnosticsChannel.channel('undici:websocket:close').subscribe(evt => { + const { websocket, code, reason } = evt + console.log( + `WebSocket:undici ${process.pid}: closed connection to ${websocket.url} - ${code} ${reason}` + ) + }) + + diagnosticsChannel.channel('undici:websocket:socket_error').subscribe(err => { + console.log( + `WebSocket:undici ${process.pid}: connection errored - ${err.message}` + ) + }) + + diagnosticsChannel.channel('undici:websocket:ping').subscribe(evt => { + console.log(`WebSocket:undici ${process.pid}: ping received`) + }) + + diagnosticsChannel.channel('undici:websocket:pong').subscribe(evt => { + console.log(`WebSocket:undici ${process.pid}: pong received`) + }) } module.exports = { From f0c25e89f510740601362de890015cfe4af4ff51 Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Fri, 5 Jan 2024 10:43:27 +0100 Subject: [PATCH 04/10] test: move tests to 'right' path --- test/{ => node-test}/diagnostics-channel/connect-error.js | 2 +- test/{ => node-test}/diagnostics-channel/error.js | 0 test/{ => node-test}/diagnostics-channel/get.js | 0 test/{ => node-test}/diagnostics-channel/post-stream.js | 0 test/{ => node-test}/diagnostics-channel/post.js | 2 +- 5 files changed, 2 insertions(+), 2 deletions(-) rename test/{ => node-test}/diagnostics-channel/connect-error.js (97%) rename test/{ => node-test}/diagnostics-channel/error.js (100%) rename test/{ => node-test}/diagnostics-channel/get.js (100%) rename test/{ => node-test}/diagnostics-channel/post-stream.js (100%) rename test/{ => node-test}/diagnostics-channel/post.js (99%) diff --git a/test/diagnostics-channel/connect-error.js b/test/node-test/diagnostics-channel/connect-error.js similarity index 97% rename from test/diagnostics-channel/connect-error.js rename to test/node-test/diagnostics-channel/connect-error.js index a3bf2a45de7..35559fab86a 100644 --- a/test/diagnostics-channel/connect-error.js +++ b/test/node-test/diagnostics-channel/connect-error.js @@ -12,7 +12,7 @@ try { process.exit(0) } -const { Client } = require('../..') +const { Client } = require('../../..') test('Diagnostics channel - connect error', (t) => { const connectError = new Error('custom error') diff --git a/test/diagnostics-channel/error.js b/test/node-test/diagnostics-channel/error.js similarity index 100% rename from test/diagnostics-channel/error.js rename to test/node-test/diagnostics-channel/error.js diff --git a/test/diagnostics-channel/get.js b/test/node-test/diagnostics-channel/get.js similarity index 100% rename from test/diagnostics-channel/get.js rename to test/node-test/diagnostics-channel/get.js diff --git a/test/diagnostics-channel/post-stream.js b/test/node-test/diagnostics-channel/post-stream.js similarity index 100% rename from test/diagnostics-channel/post-stream.js rename to test/node-test/diagnostics-channel/post-stream.js diff --git a/test/diagnostics-channel/post.js b/test/node-test/diagnostics-channel/post.js similarity index 99% rename from test/diagnostics-channel/post.js rename to test/node-test/diagnostics-channel/post.js index 30203a7e7c7..1f0475bd556 100644 --- a/test/diagnostics-channel/post.js +++ b/test/node-test/diagnostics-channel/post.js @@ -12,7 +12,7 @@ try { process.exit(0) } -const { Client } = require('../..') +const { Client } = require('../../..') const { createServer } = require('http') test('Diagnostics channel - post', (t) => { From 97ddbc3d8c979969b9b9202e98da88529bc0a67e Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Fri, 5 Jan 2024 11:14:46 +0100 Subject: [PATCH 05/10] fix: smaller tweaks --- lib/client.js | 16 +--------------- lib/core/request.js | 17 ----------------- lib/websocket/connection.js | 5 ----- lib/websocket/receiver.js | 4 ---- package.json | 7 ++++--- .../diagnostics-channel/connect-error.js | 4 ++-- test/node-test/diagnostics-channel/error.js | 2 +- test/node-test/diagnostics-channel/get.js | 6 +++--- .../diagnostics-channel/post-stream.js | 6 +++--- test/node-test/diagnostics-channel/post.js | 6 +++--- 10 files changed, 17 insertions(+), 56 deletions(-) diff --git a/lib/client.js b/lib/client.js index 377e2e4d52f..cc5c4890552 100644 --- a/lib/client.js +++ b/lib/client.js @@ -109,21 +109,6 @@ const FastBuffer = Buffer[Symbol.species] const kClosedResolve = Symbol('kClosedResolve') -// const channels = {} - -// try { -// const diagnosticsChannel = require('diagnostics_channel') -// channels.sendHeaders = diagnosticsChannel.channel('undici:client:sendHeaders') -// channels.beforeConnect = diagnosticsChannel.channel('undici:client:beforeConnect') -// channels.connectError = diagnosticsChannel.channel('undici:client:connectError') -// channels.connected = diagnosticsChannel.channel('undici:client:connected') -// } catch { -// channels.sendHeaders = { hasSubscribers: false } -// channels.beforeConnect = { hasSubscribers: false } -// channels.connectError = { hasSubscribers: false } -// channels.connected = { hasSubscribers: false } -// } - /** * @type {import('../types/client').default} */ @@ -1309,6 +1294,7 @@ async function connect (client) { hostname, protocol, port, + version: client[kHTTPConnVersion], servername: client[kServerName], localAddress: client[kLocalAddress] }, diff --git a/lib/core/request.js b/lib/core/request.js index dc706fc1981..4a61da0e454 100644 --- a/lib/core/request.js +++ b/lib/core/request.js @@ -26,25 +26,8 @@ const invalidPathRegex = /[^\u0021-\u00ff]/ const kHandler = Symbol('handler') -// const channels = {} - let extractBody -// try { -// const diagnosticsChannel = require('diagnostics_channel') -// channels.create = diagnosticsChannel.channel('undici:request:create') -// channels.bodySent = diagnosticsChannel.channel('undici:request:bodySent') -// channels.headers = diagnosticsChannel.channel('undici:request:headers') -// channels.trailers = diagnosticsChannel.channel('undici:request:trailers') -// channels.error = diagnosticsChannel.channel('undici:request:error') -// } catch { -// channels.create = { hasSubscribers: false } -// channels.bodySent = { hasSubscribers: false } -// channels.headers = { hasSubscribers: false } -// channels.trailers = { hasSubscribers: false } -// channels.error = { hasSubscribers: false } -// } - class Request { constructor (origin, { path, diff --git a/lib/websocket/connection.js b/lib/websocket/connection.js index 7ca9b176ed5..d8a4f04f637 100644 --- a/lib/websocket/connection.js +++ b/lib/websocket/connection.js @@ -16,11 +16,6 @@ const { Headers } = require('../fetch/headers') const { getGlobalDispatcher } = require('../global') const { kHeadersList } = require('../core/symbols') -// const channels = {} -// channels.open = diagnosticsChannel.channel('undici:websocket:open') -// channels.close = diagnosticsChannel.channel('undici:websocket:close') -// channels.socketError = diagnosticsChannel.channel('undici:websocket:socket_error') - /** @type {import('crypto')} */ let crypto try { diff --git a/lib/websocket/receiver.js b/lib/websocket/receiver.js index 4822bcf9531..512ef42a06b 100644 --- a/lib/websocket/receiver.js +++ b/lib/websocket/receiver.js @@ -12,10 +12,6 @@ const { WebsocketFrameSend } = require('./frame') // Copyright (c) 2013 Arnout Kazemier and contributors // Copyright (c) 2016 Luigi Pinca and contributors -// const channels = {} -// channels.ping = diagnosticsChannel.channel('undici:websocket:ping') -// channels.pong = diagnosticsChannel.channel('undici:websocket:pong') - class ByteParser extends Writable { #buffers = [] #byteOffset = 0 diff --git a/package.json b/package.json index 17015f7b1b8..3d5f7ed20c5 100644 --- a/package.json +++ b/package.json @@ -80,9 +80,10 @@ "test:node-fetch": "mocha --exit test/node-fetch", "test:fetch": "npm run build:node && borp --expose-gc --coverage -p \"test/fetch/*.js\" && borp --coverage -p \"test/webidl/*.js\"", "test:jest": "jest", - "test:tap": "tap test/*.js test/diagnostics-channel/*.js", - "test:node-test": "borp --coverage -p \"test/node-test/*.js\"", - "test:tdd": "tap test/*.js test/diagnostics-channel/*.js -w", + "test:tap": "tap test/*.js", + "test:node-test": "borp --coverage -p \"test/node-test/**/*.js\"", + "test:tdd": "tap test/*.js --coverage -w", + "test:tdd:node-test": "borp -p \"test/node-test/**/*.js\" -w", "test:typescript": "tsd && tsc --skipLibCheck test/imports/undici-import.ts", "test:websocket": "borp --coverage -p \"test/websocket/*.js\"", "test:wpt": "node test/wpt/start-fetch.mjs && node test/wpt/start-FileAPI.mjs && node test/wpt/start-mimesniff.mjs && node test/wpt/start-xhr.mjs && node test/wpt/start-websockets.mjs", diff --git a/test/node-test/diagnostics-channel/connect-error.js b/test/node-test/diagnostics-channel/connect-error.js index 35559fab86a..1cc255c8d46 100644 --- a/test/node-test/diagnostics-channel/connect-error.js +++ b/test/node-test/diagnostics-channel/connect-error.js @@ -23,7 +23,7 @@ test('Diagnostics channel - connect error', (t) => { _connector = connector assert.equal(typeof _connector, 'function') - assert.equal(Object.keys(connectParams).length, 6) + assert.equal(Object.keys(connectParams).length, 7) const { host, hostname, protocol, port, servername } = connectParams @@ -35,7 +35,7 @@ test('Diagnostics channel - connect error', (t) => { }) diagnosticsChannel.channel('undici:client:connectError').subscribe(({ error, connectParams, connector }) => { - assert.equal(Object.keys(connectParams).length, 6) + assert.equal(Object.keys(connectParams).length, 7) assert.equal(_connector, connector) const { host, hostname, protocol, port, servername } = connectParams diff --git a/test/node-test/diagnostics-channel/error.js b/test/node-test/diagnostics-channel/error.js index 2a737d70b33..9b320b59824 100644 --- a/test/node-test/diagnostics-channel/error.js +++ b/test/node-test/diagnostics-channel/error.js @@ -12,7 +12,7 @@ try { process.exit(0) } -const { Client } = require('../..') +const { Client } = require('../../..') const { createServer } = require('http') test('Diagnostics channel - error', (t) => { diff --git a/test/node-test/diagnostics-channel/get.js b/test/node-test/diagnostics-channel/get.js index e0feeb2fe56..a41df9d2563 100644 --- a/test/node-test/diagnostics-channel/get.js +++ b/test/node-test/diagnostics-channel/get.js @@ -12,7 +12,7 @@ try { process.exit(0) } -const { Client } = require('../..') +const { Client } = require('../../..') const { createServer } = require('http') test('Diagnostics channel - get', (t) => { @@ -51,7 +51,7 @@ test('Diagnostics channel - get', (t) => { _connector = connector assert.equal(typeof _connector, 'function') - assert.equal(Object.keys(connectParams).length, 6) + assert.equal(Object.keys(connectParams).length, 7) const { host, hostname, protocol, port, servername } = connectParams @@ -67,7 +67,7 @@ test('Diagnostics channel - get', (t) => { _socket = socket assert.equal(_connector, connector) - assert.equal(Object.keys(connectParams).length, 6) + assert.equal(Object.keys(connectParams).length, 7) const { host, hostname, protocol, port, servername } = connectParams diff --git a/test/node-test/diagnostics-channel/post-stream.js b/test/node-test/diagnostics-channel/post-stream.js index 3510e74993b..aa2792a2732 100644 --- a/test/node-test/diagnostics-channel/post-stream.js +++ b/test/node-test/diagnostics-channel/post-stream.js @@ -13,7 +13,7 @@ try { process.exit(0) } -const { Client } = require('../..') +const { Client } = require('../../..') const { createServer } = require('http') test('Diagnostics channel - post stream', (t) => { @@ -53,7 +53,7 @@ test('Diagnostics channel - post stream', (t) => { _connector = connector assert.equal(typeof _connector, 'function') - assert.equal(Object.keys(connectParams).length, 6) + assert.equal(Object.keys(connectParams).length, 7) const { host, hostname, protocol, port, servername } = connectParams @@ -68,7 +68,7 @@ test('Diagnostics channel - post stream', (t) => { diagnosticsChannel.channel('undici:client:connected').subscribe(({ connectParams, socket, connector }) => { _socket = socket - assert.equal(Object.keys(connectParams).length, 6) + assert.equal(Object.keys(connectParams).length, 7) assert.equal(_connector, connector) const { host, hostname, protocol, port, servername } = connectParams diff --git a/test/node-test/diagnostics-channel/post.js b/test/node-test/diagnostics-channel/post.js index 1f0475bd556..427853b66ea 100644 --- a/test/node-test/diagnostics-channel/post.js +++ b/test/node-test/diagnostics-channel/post.js @@ -12,7 +12,7 @@ try { process.exit(0) } -const { Client } = require('../../..') +const { Client } = require('../../../') const { createServer } = require('http') test('Diagnostics channel - post', (t) => { @@ -51,7 +51,7 @@ test('Diagnostics channel - post', (t) => { _connector = connector assert.equal(typeof _connector, 'function') - assert.equal(Object.keys(connectParams).length, 6) + assert.equal(Object.keys(connectParams).length, 7) const { host, hostname, protocol, port, servername } = connectParams @@ -66,7 +66,7 @@ test('Diagnostics channel - post', (t) => { diagnosticsChannel.channel('undici:client:connected').subscribe(({ connectParams, socket, connector }) => { _socket = socket - assert.equal(Object.keys(connectParams).length, 6) + assert.equal(Object.keys(connectParams).length, 7) assert.equal(_connector, connector) const { host, hostname, protocol, port, servername } = connectParams From 4a1617470d7128d573f9572e5e24321904e7b55f Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Fri, 5 Jan 2024 12:12:42 +0100 Subject: [PATCH 06/10] refactor: use debuglog instead --- lib/core/diagnostics.js | 123 ++++++++++++++++++++++++---------------- 1 file changed, 73 insertions(+), 50 deletions(-) diff --git a/lib/core/diagnostics.js b/lib/core/diagnostics.js index 16c3c8e1dc2..c6bad94f050 100644 --- a/lib/core/diagnostics.js +++ b/lib/core/diagnostics.js @@ -1,5 +1,9 @@ const diagnosticsChannel = require('diagnostics_channel') +const util = require('util') +const undiciDebugLog = util.debuglog('undici') +const fetchDebuglog = util.debuglog('fetch') +const websocketDebuglog = util.debuglog('websocket') let isClientSet = false const channels = { // Client @@ -21,16 +25,19 @@ const channels = { pong: diagnosticsChannel.channel('undici:websocket:pong') } -if (process.env.NODE_DEBUG?.match(/(fetch|undici)/) != null) { +if (undiciDebugLog.enabled || fetchDebuglog.enabled) { + const debuglog = fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog + // Track all Client events diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => { const { connectParams: { version, protocol, port, host } } = evt - console.log( - `HTTP:undici ${process.pid}: connecting to ${host}${ - port ? `:${port}` : '' - } using ${protocol}${version}` + debuglog( + 'connecting to %s using %s%s', + `${host}${port ? `:${port}` : ''}`, + protocol, + version ) }) @@ -38,10 +45,11 @@ if (process.env.NODE_DEBUG?.match(/(fetch|undici)/) != null) { const { connectParams: { version, protocol, port, host } } = evt - console.log( - `HTTP:undici ${process.pid}: connected to ${host}${ - port ? `:${port}` : '' - } using ${protocol}${version}` + debuglog( + 'connected to %s using %s%s', + `${host}${port ? `:${port}` : ''}`, + protocol, + version ) }) @@ -50,10 +58,12 @@ if (process.env.NODE_DEBUG?.match(/(fetch|undici)/) != null) { connectParams: { version, protocol, port, host }, error } = evt - console.log( - `HTTP:undici ${process.pid}: connection to ${host}${ - port ? `:${port}` : '' - } using ${protocol}${version} errored - ${error.message}` + debuglog( + 'connection to %s using %s%s errored - %s', + `${host}${port ? `:${port}` : ''}`, + protocol, + version, + error.message ) }) @@ -61,9 +71,7 @@ if (process.env.NODE_DEBUG?.match(/(fetch|undici)/) != null) { const { request: { method, path, origin } } = evt - console.log( - `HTTP:undici ${process.pid}: sending request to ${method} ${origin}/${path}` - ) + debuglog('sending request to %s %s/%s', method, origin, path) }) // Track Request events @@ -72,8 +80,12 @@ if (process.env.NODE_DEBUG?.match(/(fetch|undici)/) != null) { request: { method, path, origin }, response: { statusCode } } = evt - console.log( - `HTTP:undici ${process.pid}: received response ${method} ${origin}/${path} - HTTP ${statusCode}` + debuglog( + 'received response to %s %s/%s - HTTP %d', + method, + origin, + path, + statusCode ) }) @@ -81,9 +93,7 @@ if (process.env.NODE_DEBUG?.match(/(fetch|undici)/) != null) { const { request: { method, path, origin } } = evt - console.log( - `HTTP:undici ${process.pid}: trailers received from ${method} ${origin}/${path}` - ) + debuglog('trailers received from %s %s/%s', method, origin, path) }) diagnosticsChannel.channel('undici:request:error').subscribe(evt => { @@ -91,24 +101,31 @@ if (process.env.NODE_DEBUG?.match(/(fetch|undici)/) != null) { request: { method, path, origin }, error } = evt - console.log( - `HTTP:undici ${process.pid}: request errored ${method} ${origin}/${path} - ${error.message}` + debuglog( + 'request to %s %s/%s errored - %s', + method, + origin, + path, + error.message ) }) isClientSet = true } -if (process.env.NODE_DEBUG?.match(/websocket/) != null) { +if (websocketDebuglog.enabled) { if (!isClientSet) { + const debuglog = undiciDebugLog.enabled ? undiciDebugLog : websocketDebuglog diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => { const { connectParams: { version, protocol, port, host } } = evt - console.log( - `HTTP:undici ${process.pid}: connecting to ${host}${ - port ? `:${port}` : '' - } using ${protocol}${version}` + debuglog( + 'connecting to %s%s using %s%s', + host, + port ? `:${port}` : '', + protocol, + version ) }) @@ -116,10 +133,12 @@ if (process.env.NODE_DEBUG?.match(/websocket/) != null) { const { connectParams: { version, protocol, port, host } } = evt - console.log( - `HTTP:undici ${process.pid}: connected to ${host}${ - port ? `:${port}` : '' - } using ${protocol}${version}` + debuglog( + 'connected to %s%s using %s%s', + host, + port ? `:${port}` : '', + protocol, + version ) }) @@ -128,10 +147,13 @@ if (process.env.NODE_DEBUG?.match(/websocket/) != null) { connectParams: { version, protocol, port, host }, error } = evt - console.log( - `HTTP:undici ${process.pid}: connection to ${host}${ - port ? `:${port}` : '' - } using ${protocol}${version} errored - ${error.message}` + debuglog( + 'connection to %s%s using %s%s errored - %s', + host, + port ? `:${port}` : '', + protocol, + version, + error.message ) }) @@ -139,9 +161,7 @@ if (process.env.NODE_DEBUG?.match(/websocket/) != null) { const { request: { method, path, origin } } = evt - console.log( - `HTTP:undici ${process.pid}: sending request to ${method} ${origin}/${path}` - ) + debuglog('sending request to %s %s/%s', method, origin, path) }) } @@ -152,32 +172,35 @@ if (process.env.NODE_DEBUG?.match(/websocket/) != null) { protocol, extensions } = evt - console.log( - `WebSocket:undici ${process.pid}: connection opened ${address}${ - port ? `:${port}` : '' - } using ${protocol}-${extensions}` + websocketDebuglog( + 'connection opened %s%s using %s-%s', + address, + port ? `:${port}` : '', + protocol, + extensions ) }) diagnosticsChannel.channel('undici:websocket:close').subscribe(evt => { const { websocket, code, reason } = evt - console.log( - `WebSocket:undici ${process.pid}: closed connection to ${websocket.url} - ${code} ${reason}` + websocketDebuglog( + 'closed connection to %s - %s %s', + websocket.url, + code, + reason ) }) diagnosticsChannel.channel('undici:websocket:socket_error').subscribe(err => { - console.log( - `WebSocket:undici ${process.pid}: connection errored - ${err.message}` - ) + websocketDebuglog('connection errored - %s', err.message) }) diagnosticsChannel.channel('undici:websocket:ping').subscribe(evt => { - console.log(`WebSocket:undici ${process.pid}: ping received`) + websocketDebuglog('ping received') }) diagnosticsChannel.channel('undici:websocket:pong').subscribe(evt => { - console.log(`WebSocket:undici ${process.pid}: pong received`) + websocketDebuglog('pong received') }) } From 3c60f7ab270678a015febacc4be1465a57e1f0fc Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Fri, 5 Jan 2024 12:33:52 +0100 Subject: [PATCH 07/10] docs: add documentation --- docs/api/Debug.md | 62 ++++++++++++++++++++++++++++++++++ docs/api/DiagnosticsChannel.md | 6 ++-- lib/core/diagnostics.js | 12 ++----- 3 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 docs/api/Debug.md diff --git a/docs/api/Debug.md b/docs/api/Debug.md new file mode 100644 index 00000000000..1a1794c0ad9 --- /dev/null +++ b/docs/api/Debug.md @@ -0,0 +1,62 @@ +# Debug + +Undici (and subsenquently `fetch` and `websocket`) exposes a debug statement that can be enabled by setting `NODE_DEBUG` within the environment. + +The flags availabile are: + +## `undici` + +This flag enables debug statements for the core undici library. + +```sh +NODE_DEBUG=undici node script.js + +UNDICI 16241: connecting to nodejs.org using https:h1 +UNDICI 16241: connecting to nodejs.org using https:h1 +UNDICI 16241: connected to nodejs.org using https:h1 +UNDICI 16241: sending request to GET https://nodejs.org// +UNDICI 16241: received response to GET https://nodejs.org// - HTTP 307 +UNDICI 16241: connecting to nodejs.org using https:h1 +UNDICI 16241: trailers received from GET https://nodejs.org// +UNDICI 16241: connected to nodejs.org using https:h1 +UNDICI 16241: sending request to GET https://nodejs.org//en +UNDICI 16241: received response to GET https://nodejs.org//en - HTTP 200 +UNDICI 16241: trailers received from GET https://nodejs.org//en +``` + +## `fetch` + +This flag enables debug statements for the `fetch` API. + +> **Note**: statements are pretty similar to the ones in the `undici` flag, but scoped to `fetch` + +```sh +NODE_DEBUG=fetch node script.js + +FETCH 16241: connecting to nodejs.org using https:h1 +FETCH 16241: connecting to nodejs.org using https:h1 +FETCH 16241: connected to nodejs.org using https:h1 +FETCH 16241: sending request to GET https://nodejs.org// +FETCH 16241: received response to GET https://nodejs.org// - HTTP 307 +FETCH 16241: connecting to nodejs.org using https:h1 +FETCH 16241: trailers received from GET https://nodejs.org// +FETCH 16241: connected to nodejs.org using https:h1 +FETCH 16241: sending request to GET https://nodejs.org//en +FETCH 16241: received response to GET https://nodejs.org//en - HTTP 200 +FETCH 16241: trailers received from GET https://nodejs.org//en +``` + +## `websocket` + +This flag enables debug statements for the `Websocket` API. + +> **Note**: statements can overlap with `UNDICI` ones if `undici` or `fetch` flag has been enabled as well. + +```sh +NODE_DEBUG=fetch node script.js + +WEBSOCKET 18309: connecting to echo.websocket.org using https:h1 +WEBSOCKET 18309: connected to echo.websocket.org using https:h1 +WEBSOCKET 18309: sending request to GET https://echo.websocket.org// +WEBSOCKET 18309: connection opened +``` \ No newline at end of file diff --git a/docs/api/DiagnosticsChannel.md b/docs/api/DiagnosticsChannel.md index 0aa0b9a0783..6e6ad6e4de8 100644 --- a/docs/api/DiagnosticsChannel.md +++ b/docs/api/DiagnosticsChannel.md @@ -105,7 +105,7 @@ You can not assume that this event is related to any specific request. import diagnosticsChannel from 'diagnostics_channel' diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(({ connectParams, connector }) => { - // const { host, hostname, protocol, port, servername } = connectParams + // const { host, hostname, protocol, port, servername, version } = connectParams // connector is a function that creates the socket }) ``` @@ -118,7 +118,7 @@ This message is published after a connection is established. import diagnosticsChannel from 'diagnostics_channel' diagnosticsChannel.channel('undici:client:connected').subscribe(({ socket, connectParams, connector }) => { - // const { host, hostname, protocol, port, servername } = connectParams + // const { host, hostname, protocol, port, servername, version } = connectParams // connector is a function that creates the socket }) ``` @@ -131,7 +131,7 @@ This message is published if it did not succeed to create new connection import diagnosticsChannel from 'diagnostics_channel' diagnosticsChannel.channel('undici:client:connectError').subscribe(({ error, socket, connectParams, connector }) => { - // const { host, hostname, protocol, port, servername } = connectParams + // const { host, hostname, protocol, port, servername, version } = connectParams // connector is a function that creates the socket console.log(`Connect failed with ${error.message}`) }) diff --git a/lib/core/diagnostics.js b/lib/core/diagnostics.js index c6bad94f050..fd9b3db4195 100644 --- a/lib/core/diagnostics.js +++ b/lib/core/diagnostics.js @@ -168,17 +168,9 @@ if (websocketDebuglog.enabled) { // Track all WebSocket events diagnosticsChannel.channel('undici:websocket:open').subscribe(evt => { const { - address: { address, port }, - protocol, - extensions + address: { address, port } } = evt - websocketDebuglog( - 'connection opened %s%s using %s-%s', - address, - port ? `:${port}` : '', - protocol, - extensions - ) + websocketDebuglog('connection opened %s%s', address, port ? `:${port}` : '') }) diagnosticsChannel.channel('undici:websocket:close').subscribe(evt => { From e13d7a15a6b4c08898610222641d3e6557a5d4b0 Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Sun, 7 Jan 2024 11:28:54 +0100 Subject: [PATCH 08/10] fix: code review --- docsify/sidebar.md | 1 + lib/core/diagnostics.js | 1 + 2 files changed, 2 insertions(+) diff --git a/docsify/sidebar.md b/docsify/sidebar.md index 35d5c614ce5..d5bd69a219c 100644 --- a/docsify/sidebar.md +++ b/docsify/sidebar.md @@ -18,6 +18,7 @@ * [MockErrors](/docs/api/MockErrors.md "Undici API - MockErrors") * [API Lifecycle](/docs/api/api-lifecycle.md "Undici API - Lifecycle") * [Diagnostics Channel Support](/docs/api/DiagnosticsChannel.md "Diagnostics Channel Support") + * [Debug](/docs/api/Debug.md.md "Undici API - Debugging Undici") * [WebSocket](/docs/api/WebSocket.md "Undici API - WebSocket") * [MIME Type Parsing](/docs/api/ContentType.md "Undici API - MIME Type Parsing") * [CacheStorage](/docs/api/CacheStorage.md "Undici API - CacheStorage") diff --git a/lib/core/diagnostics.js b/lib/core/diagnostics.js index fd9b3db4195..e76f73a8c3a 100644 --- a/lib/core/diagnostics.js +++ b/lib/core/diagnostics.js @@ -1,3 +1,4 @@ +'use strict' const diagnosticsChannel = require('diagnostics_channel') const util = require('util') From 8515e0b468154f38855dcac1ddbcc87fde68589a Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Sun, 7 Jan 2024 11:29:13 +0100 Subject: [PATCH 09/10] test: add testing coverage --- test/debug.js | 94 ++++++++++++++++++++++++++++++++++++++ test/fixtures/fetch.js | 6 +++ test/fixtures/undici.js | 6 +++ test/fixtures/websocket.js | 16 +++++++ 4 files changed, 122 insertions(+) create mode 100644 test/debug.js create mode 100644 test/fixtures/fetch.js create mode 100644 test/fixtures/undici.js create mode 100644 test/fixtures/websocket.js diff --git a/test/debug.js b/test/debug.js new file mode 100644 index 00000000000..dd07a87289f --- /dev/null +++ b/test/debug.js @@ -0,0 +1,94 @@ +'use strict' + +const { test } = require('node:test') +const { spawn } = require('node:child_process') +const { tspl } = require('@matteo.collina/tspl') +const { join } = require('node:path') + +test('debug#websocket', async t => { + const assert = tspl(t, { plan: 5 }) + const child = spawn( + process.execPath, + [join(__dirname, 'fixtures/websocket.js')], + { + env: { + NODE_DEBUG: 'websocket' + } + } + ) + + t.after(() => { + child.kill() + }) + + child.stderr.setEncoding('utf8') + + for await (const chunk of child.stderr) { + if (chunk.includes('[UNDICI-WS] Warning')) { + continue + } + + assert.match( + chunk, + /(WEBSOCKET [0-9]+:) (connecting to|connected to|sending request|connection opened|closed connection)/ + ) + } +}) + +test('debug#fetch', async t => { + // Due to Node.js webpage redirect + const assert = tspl(t, { plan: 10 }) + const child = spawn( + process.execPath, + [join(__dirname, 'fixtures/fetch.js')], + { + env: { + NODE_DEBUG: 'fetch' + } + } + ) + + t.after(() => { + child.kill() + }) + + child.stderr.setEncoding('utf8') + + for await (const chunk of child.stderr) { + if (chunk.includes('[UNDICI-WS] Warning')) { + continue + } + + assert.match( + chunk, + /(FETCH [0-9]+:) (connecting to|connected to|sending request|received response|trailers received|request to)/ + ) + } +}) + +test('debug#undici', async t => { + // Due to Node.js webpage redirect + const assert = tspl(t, { plan: 10 }) + const child = spawn( + process.execPath, + [join(__dirname, 'fixtures/undici.js')], + { + env: { + NODE_DEBUG: 'undici' + } + } + ) + + t.after(() => { + child.kill() + }) + + child.stderr.setEncoding('utf8') + + for await (const chunk of child.stderr) { + assert.match( + chunk, + /(UNDICI [0-9]+:) (connecting to|connected to|sending request|received response|trailers received|request to)/ + ) + } +}) diff --git a/test/fixtures/fetch.js b/test/fixtures/fetch.js new file mode 100644 index 00000000000..ef2ea7b6e98 --- /dev/null +++ b/test/fixtures/fetch.js @@ -0,0 +1,6 @@ +const { fetch } = require('../..') + +fetch('https://nodejs.org').then( + res => res.body.cancel(), + () => {} +) diff --git a/test/fixtures/undici.js b/test/fixtures/undici.js new file mode 100644 index 00000000000..51aac6bf943 --- /dev/null +++ b/test/fixtures/undici.js @@ -0,0 +1,6 @@ +const { request } = require('../..') + +request('https://nodejs.org', { maxRedirections: 1 }).then( + res => res.body.dump(), + () => {} +) diff --git a/test/fixtures/websocket.js b/test/fixtures/websocket.js new file mode 100644 index 00000000000..ca8c83513fc --- /dev/null +++ b/test/fixtures/websocket.js @@ -0,0 +1,16 @@ +const { WebSocketServer } = require('ws') +const { WebSocket } = require('../..') + +const server = new WebSocketServer({ port: 0 }) + +server.on('connection', ws => { + ws.close(1000, 'goodbye') +}) + +const { port } = server.address() + +const ws = new WebSocket(`ws://localhost:${port}`, 'chat') + +ws.addEventListener('close', () => { + server.close() +}) From b4c8883362d3ffd08d02c11b409df3086a31ed32 Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Sun, 7 Jan 2024 11:30:05 +0100 Subject: [PATCH 10/10] refactor: remove leftover --- test/debug.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/debug.js b/test/debug.js index dd07a87289f..61930e75843 100644 --- a/test/debug.js +++ b/test/debug.js @@ -55,10 +55,6 @@ test('debug#fetch', async t => { child.stderr.setEncoding('utf8') for await (const chunk of child.stderr) { - if (chunk.includes('[UNDICI-WS] Warning')) { - continue - } - assert.match( chunk, /(FETCH [0-9]+:) (connecting to|connected to|sending request|received response|trailers received|request to)/