diff options
author | Oisin Canty <o.canty@f5.com> | 2021-05-12 09:26:55 +0000 |
---|---|---|
committer | Oisin Canty <o.canty@f5.com> | 2021-05-12 09:26:55 +0000 |
commit | a0c083af208cd9f676bb56762b4e27a3174a773d (patch) | |
tree | 77542c99f13352ea9317a27e456ddde8f50ae5ef | |
parent | 07c6bf165d0e414da3827c7b2aebf5044a7e6093 (diff) | |
download | unit-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"
]
}
44 files changed, 288 insertions, 78 deletions
diff --git a/docs/changes.xml b/docs/changes.xml index e2cb4f1d..c69523f9 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -33,6 +33,12 @@ NGINX Unit updated to 1.24.0. <change type="feature"> <para> +a shim for automatic overriding "http" and "websocket" modules in Node.js. +</para> +</change> + +<change type="feature"> +<para> ability to limit serving of static files by MIME types. </para> </change> 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) +} diff --git a/test/node/404/app.js b/test/node/404/app.js index 587c432d..ba15c104 100755..100644 --- a/test/node/404/app.js +++ b/test/node/404/app.js @@ -1,7 +1,6 @@ -#!/usr/bin/env node var fs = require('fs'); -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.writeHead(404, {}).end(fs.readFileSync('404.html')); }).listen(7080); diff --git a/test/node/basic/app.js b/test/node/basic/app.js index 7820c474..9092022c 100755..100644 --- a/test/node/basic/app.js +++ b/test/node/basic/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.writeHead(200, {'Content-Length': 12, 'Content-Type': 'text/plain'}) .end('Hello World\n'); }).listen(7080); diff --git a/test/node/double_end/app.js b/test/node/double_end/app.js index 63912097..653e33b1 100755..100644 --- a/test/node/double_end/app.js +++ b/test/node/double_end/app.js @@ -1,5 +1,4 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.end().end(); }).listen(7080); diff --git a/test/node/get_header_names/app.js b/test/node/get_header_names/app.js index 4cbccc16..a938b762 100755..100644 --- a/test/node/get_header_names/app.js +++ b/test/node/get_header_names/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.setHeader('DATE', ['date1', 'date2']); res.setHeader('X-Header', 'blah'); res.setHeader('X-Names', res.getHeaderNames()); diff --git a/test/node/get_header_type/app.js b/test/node/get_header_type/app.js index b606f142..6e45b71f 100755..100644 --- a/test/node/get_header_type/app.js +++ b/test/node/get_header_type/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.setHeader('X-Number', 100); res.setHeader('X-Type', typeof(res.getHeader('X-Number'))); res.end(); diff --git a/test/node/get_variables/app.js b/test/node/get_variables/app.js index 5c1faf41..cded43d2 100755..100644 --- a/test/node/get_variables/app.js +++ b/test/node/get_variables/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { let query = require('url').parse(req.url, true).query; res.setHeader('X-Var-1', query.var1); res.setHeader('X-Var-2', query.var2); diff --git a/test/node/has_header/app.js b/test/node/has_header/app.js index eff7f4ff..04b13916 100755..100644 --- a/test/node/has_header/app.js +++ b/test/node/has_header/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.setHeader('X-Has-Header', res.hasHeader(req.headers['x-header']) + ''); res.end(); }).listen(7080); diff --git a/test/node/header_name_case/app.js b/test/node/header_name_case/app.js index 490bd4d5..af157547 100755..100644 --- a/test/node/header_name_case/app.js +++ b/test/node/header_name_case/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.setHeader('X-Header', '1'); res.setHeader('X-header', '2'); res.setHeader('X-HEADER', '3'); diff --git a/test/node/header_name_valid/app.js b/test/node/header_name_valid/app.js index 425f026f..c0c36098 100755..100644 --- a/test/node/header_name_valid/app.js +++ b/test/node/header_name_valid/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.writeHead(200, {}); res.setHeader('@$', 'test'); res.end(); diff --git a/test/node/header_value_object/app.js b/test/node/header_value_object/app.js index ff4e2bb0..bacdc7d5 100755..100644 --- a/test/node/header_value_object/app.js +++ b/test/node/header_value_object/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.setHeader('X-Header', {}); res.end(); }).listen(7080); diff --git a/test/node/mirror/app.js b/test/node/mirror/app.js index 1488917e..bdefe1cd 100755..100644 --- a/test/node/mirror/app.js +++ b/test/node/mirror/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { let body = ''; req.on('data', chunk => { body += chunk.toString(); diff --git a/test/node/post_variables/app.js b/test/node/post_variables/app.js index 928a38cf..12b867cb 100755..100644 --- a/test/node/post_variables/app.js +++ b/test/node/post_variables/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { let body = ''; req.on('data', chunk => { body += chunk.toString(); diff --git a/test/node/promise_end/app.js b/test/node/promise_end/app.js index ed22464c..373c3bc6 100755..100644 --- a/test/node/promise_end/app.js +++ b/test/node/promise_end/app.js @@ -1,8 +1,7 @@ -#!/usr/bin/env node var fs = require('fs'); -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.write('blah'); Promise.resolve().then(() => { diff --git a/test/node/promise_handler/app.js b/test/node/promise_handler/app.js index 51c3666b..32d7d7b9 100755..100644 --- a/test/node/promise_handler/app.js +++ b/test/node/promise_handler/app.js @@ -1,8 +1,7 @@ -#!/usr/bin/env node var fs = require('fs'); -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.end(); if (req.headers['x-write-call']) { diff --git a/test/node/remove_header/app.js b/test/node/remove_header/app.js index cd7b80c3..2a591235 100755..100644 --- a/test/node/remove_header/app.js +++ b/test/node/remove_header/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.setHeader('X-Header', 'test'); res.setHeader('Was-Header', res.hasHeader('X-Header').toString()); diff --git a/test/node/require_shim/es_modules_http/app.mjs b/test/node/require_shim/es_modules_http/app.mjs new file mode 100644 index 00000000..c7bcfe49 --- /dev/null +++ b/test/node/require_shim/es_modules_http/app.mjs @@ -0,0 +1,6 @@ +import http from "http" + +http.createServer(function (req, res) { + res.writeHead(200, {'Content-Length': 12, 'Content-Type': 'text/plain'}) + .end('Hello World\n'); +}).listen(7080); diff --git a/test/node/require_shim/es_modules_http_indirect/app.js b/test/node/require_shim/es_modules_http_indirect/app.js new file mode 100644 index 00000000..535befba --- /dev/null +++ b/test/node/require_shim/es_modules_http_indirect/app.js @@ -0,0 +1 @@ +import("./module.mjs") diff --git a/test/node/require_shim/es_modules_http_indirect/module.mjs b/test/node/require_shim/es_modules_http_indirect/module.mjs new file mode 100644 index 00000000..c7bcfe49 --- /dev/null +++ b/test/node/require_shim/es_modules_http_indirect/module.mjs @@ -0,0 +1,6 @@ +import http from "http" + +http.createServer(function (req, res) { + res.writeHead(200, {'Content-Length': 12, 'Content-Type': 'text/plain'}) + .end('Hello World\n'); +}).listen(7080); diff --git a/test/node/require_shim/es_modules_websocket/app.mjs b/test/node/require_shim/es_modules_websocket/app.mjs new file mode 100644 index 00000000..a71ffa9d --- /dev/null +++ b/test/node/require_shim/es_modules_websocket/app.mjs @@ -0,0 +1,30 @@ +import http from "http" +import websocket from "websocket" + +let server = http.createServer(function() {}); +let webSocketServer = websocket.server; + +server.listen(7080, function() {}); + +var wsServer = new webSocketServer({ + maxReceivedMessageSize: 0x1000000000, + maxReceivedFrameSize: 0x1000000000, + fragmentOutgoingMessages: false, + fragmentationThreshold: 0x1000000000, + httpServer: server, +}); + +wsServer.on('request', function(request) { + var connection = request.accept(null); + + connection.on('message', function(message) { + if (message.type === 'utf8') { + connection.send(message.utf8Data); + } else if (message.type === 'binary') { + connection.send(message.binaryData); + } + + }); + + connection.on('close', function(r) {}); +}); diff --git a/test/node/require_shim/es_modules_websocket_indirect/app.js b/test/node/require_shim/es_modules_websocket_indirect/app.js new file mode 100644 index 00000000..535befba --- /dev/null +++ b/test/node/require_shim/es_modules_websocket_indirect/app.js @@ -0,0 +1 @@ +import("./module.mjs") diff --git a/test/node/require_shim/es_modules_websocket_indirect/module.mjs b/test/node/require_shim/es_modules_websocket_indirect/module.mjs new file mode 100644 index 00000000..a71ffa9d --- /dev/null +++ b/test/node/require_shim/es_modules_websocket_indirect/module.mjs @@ -0,0 +1,30 @@ +import http from "http" +import websocket from "websocket" + +let server = http.createServer(function() {}); +let webSocketServer = websocket.server; + +server.listen(7080, function() {}); + +var wsServer = new webSocketServer({ + maxReceivedMessageSize: 0x1000000000, + maxReceivedFrameSize: 0x1000000000, + fragmentOutgoingMessages: false, + fragmentationThreshold: 0x1000000000, + httpServer: server, +}); + +wsServer.on('request', function(request) { + var connection = request.accept(null); + + connection.on('message', function(message) { + if (message.type === 'utf8') { + connection.send(message.utf8Data); + } else if (message.type === 'binary') { + connection.send(message.binaryData); + } + + }); + + connection.on('close', function(r) {}); +}); diff --git a/test/node/require_shim/transitive_dependency/app.js b/test/node/require_shim/transitive_dependency/app.js new file mode 100644 index 00000000..aaca5216 --- /dev/null +++ b/test/node/require_shim/transitive_dependency/app.js @@ -0,0 +1 @@ +require("./transitive_http") diff --git a/test/node/require_shim/transitive_dependency/transitive_http.js b/test/node/require_shim/transitive_dependency/transitive_http.js new file mode 100644 index 00000000..f1eb98e5 --- /dev/null +++ b/test/node/require_shim/transitive_dependency/transitive_http.js @@ -0,0 +1,8 @@ +const http = require("http"); + +http.createServer(function (req, res) { + res.writeHead(200, {'Content-Length': 12, 'Content-Type': 'text/plain'}) + .end('Hello World\n'); +}).listen(7080); + +module.exports = http; diff --git a/test/node/require_shim/unit_http/app.js b/test/node/require_shim/unit_http/app.js new file mode 100644 index 00000000..9172e44f --- /dev/null +++ b/test/node/require_shim/unit_http/app.js @@ -0,0 +1,4 @@ +require("unit-http").createServer(function (req, res) { + res.writeHead(200, {'Content-Length': 12, 'Content-Type': 'text/plain'}) + .end('Hello World\n'); +}).listen(7080); diff --git a/test/node/set_header_array/app.js b/test/node/set_header_array/app.js index faac45c7..965330e2 100755..100644 --- a/test/node/set_header_array/app.js +++ b/test/node/set_header_array/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.setHeader('Set-Cookie', ['tc=one,two,three', 'tc=four,five,six']); res.end(); }).listen(7080); diff --git a/test/node/status_message/app.js b/test/node/status_message/app.js index e8a798dd..ba51d35b 100755..100644 --- a/test/node/status_message/app.js +++ b/test/node/status_message/app.js @@ -1,5 +1,4 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.writeHead(200, 'blah', {'Content-Type': 'text/plain'}).end(); }).listen(7080); diff --git a/test/node/update_header/app.js b/test/node/update_header/app.js index 0c5cd237..905ac294 100755..100644 --- a/test/node/update_header/app.js +++ b/test/node/update_header/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.setHeader('X-Header', 'test'); res.setHeader('X-Header', 'new'); res.end(); diff --git a/test/node/variables/app.js b/test/node/variables/app.js index d8cdc20c..a569dddd 100755..100644 --- a/test/node/variables/app.js +++ b/test/node/variables/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { let body = ''; req.on('data', chunk => { body += chunk.toString(); diff --git a/test/node/websockets/mirror/app.js b/test/node/websockets/mirror/app.js index 23746465..0443adb2 100755..100644 --- a/test/node/websockets/mirror/app.js +++ b/test/node/websockets/mirror/app.js @@ -1,9 +1,6 @@ -#!/usr/bin/env node -server = require('unit-http').createServer(function() {}); -webSocketServer = require('unit-http/websocket').server; -//server = require('http').createServer(function() {}); -//webSocketServer = require('websocket').server; +server = require('http').createServer(function() {}); +webSocketServer = require('websocket').server; server.listen(7080, function() {}); diff --git a/test/node/websockets/mirror_fragmentation/app.js b/test/node/websockets/mirror_fragmentation/app.js index 7024252a..ea580ac2 100755..100644 --- a/test/node/websockets/mirror_fragmentation/app.js +++ b/test/node/websockets/mirror_fragmentation/app.js @@ -1,9 +1,6 @@ -#!/usr/bin/env node -server = require('unit-http').createServer(function() {}); -webSocketServer = require('unit-http/websocket').server; -//server = require('http').createServer(function() {}); -//webSocketServer = require('websocket').server; +server = require('http').createServer(function() {}); +webSocketServer = require('websocket').server; server.listen(7080, function() {}); diff --git a/test/node/write_before_write_head/app.js b/test/node/write_before_write_head/app.js index 724b0efb..2293111a 100755..100644 --- a/test/node/write_before_write_head/app.js +++ b/test/node/write_before_write_head/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.write('blah'); res.writeHead(200, {'Content-Type': 'text/plain'}).end(); }).listen(7080); diff --git a/test/node/write_buffer/app.js b/test/node/write_buffer/app.js index a7623523..506e8613 100755..100644 --- a/test/node/write_buffer/app.js +++ b/test/node/write_buffer/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}) .end(new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72])); }).listen(7080); diff --git a/test/node/write_callback/app.js b/test/node/write_callback/app.js index 3a9e51e8..71eb4116 100755..100644 --- a/test/node/write_callback/app.js +++ b/test/node/write_callback/app.js @@ -1,8 +1,7 @@ -#!/usr/bin/env node var fs = require('fs'); -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); var a = 'world'; res.write('hello', 'utf8', function() { diff --git a/test/node/write_multiple/app.js b/test/node/write_multiple/app.js index 3cbb3b86..e9c51ae0 100755..100644 --- a/test/node/write_multiple/app.js +++ b/test/node/write_multiple/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain', 'Content-Length': 14}); res.write('write'); res.write('write2'); diff --git a/test/node/write_return/app.js b/test/node/write_return/app.js index 82dfbc6e..345b6c4b 100755..100644 --- a/test/node/write_return/app.js +++ b/test/node/write_return/app.js @@ -1,6 +1,5 @@ -#!/usr/bin/env node -require('unit-http').createServer(function (req, res) { +require('http').createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}) .end(res.write('body').toString()); }).listen(7080); diff --git a/test/test_node_application.py b/test/test_node_application.py index 52ad72ee..59601ff0 100644 --- a/test/test_node_application.py +++ b/test/test_node_application.py @@ -9,13 +9,26 @@ from unit.utils import waitforfiles class TestNodeApplication(TestApplicationNode): prerequisites = {'modules': {'node': 'all'}} - def test_node_application_basic(self): - self.load('basic') - + def assert_basic_application(self): resp = self.get() assert resp['headers']['Content-Type'] == 'text/plain', 'basic header' assert resp['body'] == 'Hello World\n', 'basic body' + def test_node_application_basic(self): + self.load('basic') + + self.assert_basic_application() + + def test_node_application_require_shim_unit_http(self): + self.load('require_shim/unit_http') + + self.assert_basic_application() + + def test_node_application_require_shim_transitive_dependency(self): + self.load('require_shim/transitive_dependency') + + self.assert_basic_application() + def test_node_application_seq(self): self.load('basic') diff --git a/test/test_node_es_modules.py b/test/test_node_es_modules.py new file mode 100644 index 00000000..ce27e474 --- /dev/null +++ b/test/test_node_es_modules.py @@ -0,0 +1,50 @@ +import pytest + +from distutils.version import LooseVersion +from unit.applications.lang.node import TestApplicationNode +from unit.applications.websockets import TestApplicationWebsocket + + +class TestNodeESModules(TestApplicationNode): + prerequisites = { + 'modules': { + 'node': lambda v: LooseVersion(v) >= LooseVersion("14.16.0") + } + } + + es_modules = True + ws = TestApplicationWebsocket() + + def assert_basic_application(self): + resp = self.get() + assert resp['headers']['Content-Type'] == 'text/plain', 'basic header' + assert resp['body'] == 'Hello World\n', 'basic body' + + def test_node_es_modules_require_shim_http(self): + self.load('require_shim/es_modules_http', name="app.mjs") + + self.assert_basic_application() + + def test_node_es_modules_require_shim_http_indirect(self): + self.load('require_shim/es_modules_http_indirect', name="app.js") + + self.assert_basic_application() + + def test_node_es_modules_require_shim_websockets(self): + self.load('require_shim/es_modules_websocket', name="app.mjs") + + message = 'blah' + + _, sock, _ = self.ws.upgrade() + + self.ws.frame_write(sock, self.ws.OP_TEXT, message) + frame = self.ws.frame_read(sock) + + assert message == frame['data'].decode('utf-8'), 'mirror' + + self.ws.frame_write(sock, self.ws.OP_TEXT, message) + frame = self.ws.frame_read(sock) + + assert message == frame['data'].decode('utf-8'), 'mirror 2' + + sock.close() diff --git a/test/unit/applications/lang/node.py b/test/unit/applications/lang/node.py index cc6d06ef..3254f3d4 100644 --- a/test/unit/applications/lang/node.py +++ b/test/unit/applications/lang/node.py @@ -7,15 +7,16 @@ from unit.utils import public_dir class TestApplicationNode(TestApplicationProto): + application_type = "node" + es_modules = False + def prepare_env(self, script): # copy application - shutil.copytree( option.test_dir + '/node/' + script, option.temp_dir + '/node' ) # copy modules - shutil.copytree( option.current_dir + '/node/node_modules', option.temp_dir + '/node/node_modules', @@ -26,6 +27,19 @@ class TestApplicationNode(TestApplicationProto): def load(self, script, name='app.js', **kwargs): self.prepare_env(script) + if self.es_modules: + arguments = [ + "node", + "--loader", + "unit-http/require_shim.mjs", + "--require", + "unit-http/require_shim", + name, + ] + + else: + arguments = ["node", "--require", "unit-http/require_shim", name] + self._load_conf( { "listeners": { @@ -36,7 +50,8 @@ class TestApplicationNode(TestApplicationProto): "type": "external", "processes": {"spare": 0}, "working_directory": option.temp_dir + '/node', - "executable": name, + "executable": '/usr/bin/env', + "arguments": arguments, } }, }, diff --git a/test/unit/check/node.py b/test/unit/check/node.py index 236ba7b5..e053a749 100644 --- a/test/unit/check/node.py +++ b/test/unit/check/node.py @@ -1,6 +1,15 @@ import os +import subprocess def check_node(current_dir): - if os.path.exists(current_dir + '/node/node_modules'): - return True + if not os.path.exists(current_dir + '/node/node_modules'): + return None + + try: + v_bytes = subprocess.check_output(['/usr/bin/env', 'node', '-v']) + + return [str(v_bytes, 'utf-8').lstrip('v').rstrip()] + + except subprocess.CalledProcessError: + return None |