diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index f0d86f3d870f09..fe3e6edd152d7e 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -308,10 +308,12 @@ function TLSSocket(socket, opts) { // Wrap plain JS Stream into StreamWrap var wrap; - if ((socket instanceof net.Socket && socket._handle) || !socket) + if ((socket instanceof net.Socket && socket._handle) || !socket) { wrap = socket; - else + } else { wrap = new StreamWrap(socket); + wrap.once('close', () => this.destroy()); + } // Just a documented property to make secure sockets // distinguishable from regular ones. diff --git a/lib/internal/wrap_js_stream.js b/lib/internal/wrap_js_stream.js index 7ca7ff8bf49d25..cf8f45aa4505ff 100644 --- a/lib/internal/wrap_js_stream.js +++ b/lib/internal/wrap_js_stream.js @@ -11,6 +11,7 @@ const { ERR_STREAM_WRAP } = require('internal/errors').codes; const kCurrentWriteRequest = Symbol('kCurrentWriteRequest'); const kCurrentShutdownRequest = Symbol('kCurrentShutdownRequest'); +const kPendingShutdownRequest = Symbol('kPendingShutdownRequest'); function isClosing() { return this[owner_symbol].isClosing(); } function onreadstart() { return this[owner_symbol].readStart(); } @@ -79,6 +80,7 @@ class JSStreamWrap extends Socket { this.stream = stream; this[kCurrentWriteRequest] = null; this[kCurrentShutdownRequest] = null; + this[kPendingShutdownRequest] = null; this.readable = stream.readable; this.writable = stream.writable; @@ -115,8 +117,10 @@ class JSStreamWrap extends Socket { // Working around that on the native side is not quite trivial (yet?), // so for now that is supported here. - if (this[kCurrentWriteRequest] !== null) - return this.once('drain', () => this.doShutdown(req)); + if (this[kCurrentWriteRequest] !== null) { + this[kPendingShutdownRequest] = req; + return 0; + } assert.strictEqual(this[kCurrentWriteRequest], null); assert.strictEqual(this[kCurrentShutdownRequest], null); this[kCurrentShutdownRequest] = req; @@ -189,6 +193,11 @@ class JSStreamWrap extends Socket { this[kCurrentWriteRequest] = null; handle.finishWrite(req, errCode); + if (this[kPendingShutdownRequest]) { + const req = this[kPendingShutdownRequest]; + this[kPendingShutdownRequest] = null; + this.doShutdown(req); + } } doClose(cb) { diff --git a/lib/net.js b/lib/net.js index 99dc76c8f3baf5..5d332d9e1d30d7 100644 --- a/lib/net.js +++ b/lib/net.js @@ -345,12 +345,6 @@ Socket.prototype._final = function(cb) { return this.once('connect', () => this._final(cb)); } - // TODO(addaleax): This should not be necessary. - if (!this.readable || this._readableState.ended) { - cb(); - return this.destroy(); - } - if (!this._handle) return cb();