hostr
Version:
A simple web server for the current working directory. Used for hello world style web sites hosting only files in current directory structure. Watches files and integrates with LiveReload.
123 lines (103 loc) • 2.94 kB
JavaScript
;
import http from 'node:http';
import Debug from './debug.js';
import Router from './router.js';
const debug = Debug(process.env.QUIET === 'true');
/**
* Server
*
* @param {Object} options An options data Object
* @return {Server} A instance of Server
*/
export default (options = {}) => {
const _cache = {};
let _server;
let _httpServer;
const _stack = [];
let _handle, _use;
/**
* Instance
*/
_server = {
/**
* Handle request and generate response according to middleware stack
*
* @param {http.incomingMessage} req A request Object
* @param {http.ServerResponse} res A response Object
* @param {Function} callback A callback, function(err)
*/
handle: _handle = function (req, res, callback) {
const stack = _stack.slice(0);
let execute;
execute = (err) => {
if (err) {
return execute();
}
const router = stack.shift();
// Empty
if (!router) {
if (callback) callback.call(null);
return;
}
// Handle
if (router.match(req)) {
process.nextTick(router.handle.bind(null, req, res, execute));
// Continue
} else {
execute();
}
};
// Start
execute();
},
/**
* Queue a middleware
*
* @param {String} [path] An optional RegEx or String to match against path
* @param {Function} callback A callback to handle requests, function(req, res, next)
* @return {Server} Itself; chainable
*/
use: _use = function (path, callback) {
if (!callback) {
callback = path;
path = '/';
}
const router = Router(path, callback);
_stack.push(router);
return this;
},
/**
* Close server
*/
stop: function () {
if (_httpServer) _httpServer.close();
},
/**
* Start listening
*
* @param {http.Server} [httpServer] An optional server to use
* @return {http.Server} An instance of http.Server used for listening to requests
*/
start: function (httpServer) {
this.stop();
const port = isNaN(options.port) ? 3000 : +options.port;
_httpServer = httpServer || http.createServer((req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
res.setHeader('Access-Control-Allow-Headers', '*');
if (req.method === 'OPTIONS') {
res.writeHead(200);
res.end();
return;
}
});
_httpServer.on('request', _handle);
_httpServer.listen(port, () => {
debug.log(`Listening on http://localhost:${port}`);
});
return _server;
}
};
return _server;
};