From c47898e2b1660f5bb6fe0e522b0f02e87cfaae4d Mon Sep 17 00:00:00 2001 From: Yoshiya Hinosawa Date: Fri, 25 Oct 2024 00:17:16 +0900 Subject: [PATCH] A potential fix for `@npmcli/agent` issue If there's no listener for reading events to socket, then do not eagerly start reading the TcpConn. --- ext/node/polyfills/http.ts | 11 +++++++---- ext/node/polyfills/net.ts | 10 ++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ext/node/polyfills/http.ts b/ext/node/polyfills/http.ts index dce0eeb65e..ef1a090f03 100644 --- a/ext/node/polyfills/http.ts +++ b/ext/node/polyfills/http.ts @@ -615,7 +615,7 @@ class ClientRequest extends OutgoingMessage { _destroy(req, err || req[kError]); } else { // Note: this code is specific to deno to initiate a request. - socket.on("connect", () => { + const onConnect = () => { // Flush the internal buffers once socket is ready. // Note: the order is important, as the headers flush // sets up the request. @@ -623,11 +623,14 @@ class ClientRequest extends OutgoingMessage { this.once("requestReady", () => { this._flushBuffer(); }); - }); + }; this.socket = socket; this.emit("socket", socket); - // tickOnSocket(req, socket); - // req._flush(); + if (socket.readyState === "opening") { + socket.on("connect", onConnect); + } else { + onConnect(); + } } }); } diff --git a/ext/node/polyfills/net.ts b/ext/node/polyfills/net.ts index 9c9191a943..d91d4bf534 100644 --- a/ext/node/polyfills/net.ts +++ b/ext/node/polyfills/net.ts @@ -363,6 +363,16 @@ function _afterConnect( socket.emit("connect"); socket.emit("ready"); + // Note: This is Deno specific logic + // If there's no listener for the connect, ready, data event, + // we delay the first read. This is necessary for http.request to work properly. + const connectListeners = socket.listenerCount("connect"); + const readyListeners = socket.listenerCount("ready"); + const dataListeners = socket.listenerCount("data"); + if (connectListeners === 0 && readyListeners === 0 && dataListeners === 0) { + return; + } + // Start the first read, or get an immediate EOF. // this doesn't actually consume any bytes, because len=0. if (readable && !socket.isPaused()) {