diff --git a/src/js/internal/http.ts b/src/js/internal/http.ts index 1ad9622989..7311ad3fbd 100644 --- a/src/js/internal/http.ts +++ b/src/js/internal/http.ts @@ -166,6 +166,9 @@ function callCloseCallback(self) { } function emitCloseNT(self) { if (!self._closed) { + if (self._ended !== undefined) { + self._ended = true; + } self.destroyed = true; self._closed = true; callCloseCallback(self); diff --git a/src/js/node/_http_server.ts b/src/js/node/_http_server.ts index edd958d037..ed1801ce77 100644 --- a/src/js/node/_http_server.ts +++ b/src/js/node/_http_server.ts @@ -272,9 +272,7 @@ const ServerResponsePrototype = { } this.detachSocket(socket); this.finished = true; - process.nextTick(self => { - self._ended = true; - }, this); + // Marking _ended happens on 'close' to align with Node.js behavior this.emit("prefinish"); this._callPendingCallbacks(); diff --git a/test/js/node/test/parallel/test-http-writable-true-after-close.js b/test/js/node/test/parallel/test-http-writable-true-after-close.js new file mode 100644 index 0000000000..fff1b536ec --- /dev/null +++ b/test/js/node/test/parallel/test-http-writable-true-after-close.js @@ -0,0 +1,41 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { get, createServer } = require('http'); + +// res.writable should not be set to false after it has finished sending +// Ref: https://github.com/nodejs/node/issues/15029 + +let internal; +let external; + +// Proxy server +const server = createServer(common.mustCall((req, res) => { + const listener = common.mustCall(() => { + assert.strictEqual(res.writable, true); + }); + + // on CentOS 5, 'finish' is emitted + res.on('finish', listener); + // Everywhere else, 'close' is emitted + res.on('close', listener); + + get(`http://127.0.0.1:${internal.address().port}`, common.mustCall((inner) => { + inner.pipe(res); + })); +})).listen(0, () => { + // Http server + internal = createServer((req, res) => { + res.writeHead(200); + setImmediate(common.mustCall(() => { + external.abort(); + res.end('Hello World\n'); + })); + }).listen(0, () => { + external = get(`http://127.0.0.1:${server.address().port}`); + external.on('error', common.mustCall(() => { + server.close(); + internal.close(); + })); + }); +});