Files
kirbe/model/KirbeServer.js
David Ralph c768ebc41f Improvements
2019-04-06 17:56:51 +01:00

85 lines
2.8 KiB
JavaScript

const { createServer } = require('http');
const KirbeRequest = require('./KirbeRequest.js');
const KirbeResponse = require('./KirbeResponse.js');
const Collection = require('../fake_node_modules/Collection');
const methods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'];
const isUrl = (c) => (typeof c === 'string' && !methods.includes(c)) || c instanceof RegExp;
module.exports = class KirbeServer {
constructor() {
this.internalServer = createServer(( req, res) => this.handler.apply(this, [req, res]));
this.externalHandler = (req, res) => this.handler(req, res);
this.stack = new Collection();
this.routes = [];
this.extensions = [];
methods.forEach((v) => this[v.toLowerCase()] = (a, b) => this.route(v, a, b ));
}
use(middleware) {
const o = typeof middleware === 'object';
const m = {
name : this.stack.size,
args : o && typeof Array.isArray(o.args) ? o.args : [],
function : o && typeof o.function === 'function' ? o.function : middleware,
constructor: !!(o && o.constructor)
};
this.stack.set(m.name, m);
}
route(a, b, c) {
this.routes.push({
'target': {
'path' : isUrl(a) ? a : (isUrl(b) ? b : null),
'method': methods.includes(a) ? a : null
},
'handler': c || b || a
});
}
handler(req, res) {
let body = Buffer.alloc(0);
req.on('data', (c) => body = Buffer.concat([body, c]));
req.on('end', () => {
const request = new KirbeRequest(req, body);
const response = new KirbeResponse(res);
const start = () => {
for(let i = 0; i < this.routes.length; i++) {
const current = this.routes[i];
if (current.target.method && request.method !== current.target.method) continue;
if (current.target.path) {
if (current.target.path instanceof RegExp && !request.parsedUrl.pathname.match(current.target.path)) continue;
else if (current.target.path !== request.parsedUrl.pathname) continue;
}
current.handler( request, response );
break;
}
};
let currentMiddleware = 0;
const renderMiddleware = () => {
if (this.stack.size >= currentMiddleware +1) {
currentMiddleware++;
const middleware = this.stack.get(currentMiddleware - 1);
if (middleware.constructor) new middleware.function(request, response, renderMiddleware);
else middleware.function(request, response, renderMiddleware);
} else start();
};
renderMiddleware();
});
}
listen(a, b, c) {
this.internalServer.listen(typeof a === 'number' ? a : 80, typeof b === 'string' ? b : null, typeof b === 'function' ? b : null);
}
};