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:
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
27
src/nodejs/unit-http/require_shim.js
Normal file
27
src/nodejs/unit-http/require_shim.js
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
18
src/nodejs/unit-http/require_shim.mjs
Normal file
18
src/nodejs/unit-http/require_shim.mjs
Normal file
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user