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"
]
}
This commit is contained in:
Executable → Regular
+1
-2
@@ -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);
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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);
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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);
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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());
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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();
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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);
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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);
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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');
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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();
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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);
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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();
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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();
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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(() => {
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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']) {
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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());
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -0,0 +1 @@
|
||||
import("./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);
|
||||
@@ -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) {});
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
import("./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) {});
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
require("./transitive_http")
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
Executable → Regular
+1
-2
@@ -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);
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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);
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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();
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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();
|
||||
|
||||
Executable → Regular
+2
-5
@@ -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() {});
|
||||
|
||||
|
||||
Executable → Regular
+2
-5
@@ -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() {});
|
||||
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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);
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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);
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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() {
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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');
|
||||
|
||||
Executable → Regular
+1
-2
@@ -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);
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
+11
-2
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user