summaryrefslogtreecommitdiffhomepage
path: root/src/nodejs
diff options
context:
space:
mode:
authorOisin Canty <o.canty@f5.com>2021-05-12 09:26:55 +0000
committerOisin Canty <o.canty@f5.com>2021-05-12 09:26:55 +0000
commita0c083af208cd9f676bb56762b4e27a3174a773d (patch)
tree77542c99f13352ea9317a27e456ddde8f50ae5ef /src/nodejs
parent07c6bf165d0e414da3827c7b2aebf5044a7e6093 (diff)
downloadunit-a0c083af208cd9f676bb56762b4e27a3174a773d.tar.gz
unit-a0c083af208cd9f676bb56762b4e27a3174a773d.tar.bz2
Node.js: a shim for overriding "http" and "websocket" modules.
Also added stubs for Server.address() This was done to prevent crashes in some popular frameworks like express Supports both CommonJS and the new ES Modules system syntax e.g: app.js: const http = require('http') app.mjs: import http from "http" Usage on Node 14.16.x and higher: { "type": "external", "processes": {"spare": 0}, "working_directory": '/project', "executable": "/usr/bin/env", "arguments": [ "node", "--loader", "unit-http/require_shim.mjs" "--require", "unit-http/require_shim", "app.js" ] } Usage on Node 14.15.x and lower: { "type": "external", "processes": {"spare": 0}, "working_directory": '/project', "executable": "/usr/bin/env", "arguments": [ "node", "--require", "unit-http/require_shim", "app.js" ] }
Diffstat (limited to 'src/nodejs')
-rw-r--r--src/nodejs/unit-http/http.js15
-rw-r--r--src/nodejs/unit-http/http_server.js24
-rw-r--r--src/nodejs/unit-http/require_shim.js27
-rw-r--r--src/nodejs/unit-http/require_shim.mjs18
4 files changed, 72 insertions, 12 deletions
diff --git a/src/nodejs/unit-http/http.js b/src/nodejs/unit-http/http.js
index 3a25fa2f..d298a35f 100644
--- a/src/nodejs/unit-http/http.js
+++ b/src/nodejs/unit-http/http.js
@@ -5,19 +5,22 @@
'use strict';
-const server = require('unit-http/http_server');
-
-const { Server } = server;
+const {
+ Server,
+ ServerRequest,
+ ServerResponse,
+} = require('./http_server');
function createServer (requestHandler) {
return new Server(requestHandler);
}
+const http = require("http")
module.exports = {
+ ...http,
Server,
- STATUS_CODES: server.STATUS_CODES,
createServer,
- IncomingMessage: server.ServerRequest,
- ServerResponse: server.ServerResponse
+ IncomingMessage: ServerRequest,
+ ServerResponse,
};
diff --git a/src/nodejs/unit-http/http_server.js b/src/nodejs/unit-http/http_server.js
index e59296ae..89964ec3 100644
--- a/src/nodejs/unit-http/http_server.js
+++ b/src/nodejs/unit-http/http_server.js
@@ -444,17 +444,30 @@ Server.prototype.setTimeout = function setTimeout(msecs, callback) {
Server.prototype.listen = function (...args) {
this.unit.listen();
- const cb = args.pop();
-
- if (typeof cb === 'function') {
- this.once('listening', cb);
+ if (typeof args[args.length - 1] === 'function') {
+ this.once('listening', args[args.length - 1]);
}
- this.emit('listening');
+ /*
+ * Some express.js apps use the returned server object inside the listening
+ * callback, so we timeout the listening event to occur after this function
+ * returns.
+ */
+ setImmediate(function() {
+ this.emit('listening')
+ }.bind(this))
return this;
};
+Server.prototype.address = function () {
+ return {
+ family: "IPv4",
+ address: "127.0.0.1",
+ port: 80
+ }
+}
+
Server.prototype.emit_request = function (req, res) {
if (req._websocket_handshake && this._upgradeListenerCount > 0) {
this.emit('upgrade', req, req.socket);
@@ -530,7 +543,6 @@ function connectionListener(socket) {
}
module.exports = {
- STATUS_CODES: http.STATUS_CODES,
Server,
ServerResponse,
ServerRequest,
diff --git a/src/nodejs/unit-http/require_shim.js b/src/nodejs/unit-http/require_shim.js
new file mode 100644
index 00000000..2b307629
--- /dev/null
+++ b/src/nodejs/unit-http/require_shim.js
@@ -0,0 +1,27 @@
+// can only be ran as part of a --require param on the node process
+if (module.parent && module.parent.id === "internal/preload") {
+ const { Module } = require("module")
+
+ if (!Module.prototype.require.__unit_shim) {
+ const http = require("./http")
+ const websocket = require("./websocket")
+
+ const original = Module.prototype.require;
+
+ Module.prototype.require = function (id) {
+ switch(id) {
+ case "http":
+ case "unit-http":
+ return http
+
+ case "websocket":
+ case "unit-http/websocket":
+ return websocket
+ }
+
+ return original.apply(this, arguments);
+ }
+
+ Module.prototype.require.__unit_shim = true;
+ }
+}
diff --git a/src/nodejs/unit-http/require_shim.mjs b/src/nodejs/unit-http/require_shim.mjs
new file mode 100644
index 00000000..067d63d4
--- /dev/null
+++ b/src/nodejs/unit-http/require_shim.mjs
@@ -0,0 +1,18 @@
+// must be ran as part of a --loader or --experimental-loader param
+export async function resolve(specifier, context, defaultResolver) {
+ switch (specifier) {
+ case "websocket":
+ return {
+ url: new URL("./websocket.js", import.meta.url).href,
+ format: "cjs"
+ }
+
+ case "http":
+ return {
+ url: new URL("./http.js", import.meta.url).href,
+ format: "cjs"
+ }
+ }
+
+ return defaultResolver(specifier, context, defaultResolver)
+}