From c52cf5591a2e28cc7e3d2788d7465fb728c9e5a2 Mon Sep 17 00:00:00 2001 From: Jelle De Loecker Date: Thu, 14 Dec 2023 17:20:37 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Allow=20ending=20a=20non-file-serve?= =?UTF-8?q?=20`Conduit`=20response=20with=20a=20stream?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 +++ lib/class/conduit.js | 68 ++++++++++++++++++++++++++++++++++---------- package.json | 2 +- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a71c0f94..2e77d251 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.22 (WIP) + +* Allow ending a non-file-serve `Conduit` response with a stream + ## 1.3.21 (2023-11-27) * Add `Schema#addComputedField()` method diff --git a/lib/class/conduit.js b/lib/class/conduit.js index 6af5605a..baea6683 100644 --- a/lib/class/conduit.js +++ b/lib/class/conduit.js @@ -1806,6 +1806,10 @@ Conduit.setMethod(function end(message) { if (typeof message !== 'string') { + if (message && message instanceof Classes.Stream.Stream) { + return this._endWithStream(message); + } + // Use regular JSON if DRY has been disabled in settings if (alchemy.settings.json_dry_response === false || this.json_dry === false) { json_type = 'json'; @@ -1878,12 +1882,29 @@ Conduit.setMethod(function end(message) { this._end(message, 'utf-8'); }); +/** + * End with a stream + * + * @author Jelle De Loecker + * @since 1.3.22 + * @version 1.3.22 + */ +Conduit.setMethod(function _endWithStream(stream) { + + this.ended = new Date(); + this.emit('ending'); + + this.flushHeaders(); + + stream.pipe(this.response); +}); + /** * Call the actual end method * * @author Jelle De Loecker * @since 0.2.0 - * @version 1.3.14 + * @version 1.3.22 */ Conduit.setMethod(function _end(message, encoding = 'utf-8') { @@ -1906,18 +1927,42 @@ Conduit.setMethod(function _end(message, encoding = 'utf-8') { return; } - let headers = [], - value, - key; + // Set the content-length if it hasn't been set yet + if (arguments.length > 0 && !this.response_headers['content-length']) { + this.response_headers['content-length'] = Buffer.byteLength(message); + } + + this.flushHeaders(); + + if (arguments.length === 0) { + return this.response.end(); + } + + // End the response + return this.response.end(message, encoding); +}); + +/** + * Flush the headers + * + * @author Jelle De Loecker + * @since 1.3.22 + * @version 1.3.22 + */ +Conduit.setMethod(function flushHeaders() { + + if (this._flushed) { + return; + } + + this._flushed = true; if (this.status) { this.response.statusCode = this.status; } - // Set the content-length if it hasn't been set yet - if (arguments.length > 0 && !this.response_headers['content-length']) { - this.response_headers['content-length'] = Buffer.byteLength(message); - } + let value, + key; for (key in this.response_headers) { value = this.response_headers[key]; @@ -1935,13 +1980,6 @@ Conduit.setMethod(function _end(message, encoding = 'utf-8') { // Write the actual headers this.response.writeHead(this.status); - - if (arguments.length === 0) { - return this.response.end(); - } - - // End the response - return this.response.end(message, encoding); }); /** diff --git a/package.json b/package.json index 583d51c0..d782407a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "alchemymvc", "description": "MVC framework for Node.js", - "version": "1.3.21", + "version": "1.3.22-alpha", "author": "Jelle De Loecker ", "keywords": [ "alchemy",