blob: 17a7420d976f965ef55f0fa5ea145a1f90ad58cd [file] [log] [blame]
// requires
var http = require('http');
var path = require('path');
var url = require('url');
var fs = require('fs');
var child_process = require('child_process');
// constants
var PORT = +process.env.PORT || 9292;
var HOST = process.env.HOST || '0.0.0.0';
// main
http.createServer(serveRequest).listen(PORT, HOST);
console.log('listening on '+HOST+':'+PORT);
run_make_test();
'src test Makefile package.json'.split(' ').forEach(function(filename) {
recursivelyWatch(filename, run_make_test);
});
// functions
function serveRequest(req, res) {
var reqTime = new Date;
enqueueOrDo(function() {
var filepath = path.normalize(url.parse(req.url).pathname).slice(1);
fs.readFile(filepath, function(err, data) {
if (err) {
if (err.code === 'ENOENT' || err.code === 'EISDIR') {
res.statusCode = 404;
res.end('404 Not Found: /' + filepath + '\n');
}
else {
console.log(err);
res.statusCode = 500;
res.end('500 Internal Server Error: ' + err.code + '\n');
}
}
else {
var ext = filepath.match(/\.[^.]+$/);
if (ext) res.setHeader('Content-Type', 'text/' + ext[0].slice(1));
res.end(data);
}
console.log('[%s] %s %s /%s - %s%sms',
reqTime.toISOString(), res.statusCode, req.method, filepath,
(data ? (data.length >> 10) + 'kb, ' : ''), Date.now() - reqTime);
});
});
}
function recursivelyWatch(watchee, cb) {
fs.readdir(watchee, function(err, files) {
if (err) { // not a directory, just watch it
fs.watch(watchee, cb);
}
else { // a directory, recurse, also watch for files being added or deleted
files.forEach(recurse);
fs.watch(watchee, function() {
fs.readdir(watchee, function(err, filesNew) {
if (err) return; // watchee may have been deleted
// filesNew - files = new files or dirs to watch
filesNew.filter(function(file) { return files.indexOf(file) < 0; })
.forEach(recurse);
files = filesNew;
});
cb();
});
}
function recurse(file) { recursivelyWatch(path.join(watchee, file), cb); }
});
}
var q;
function enqueueOrDo(cb) { q ? q.push(cb) : cb(); }
function run_make_test() {
if (q) return;
q = [];
console.log('[%s]\nmake test', (new Date).toISOString());
var make_test = child_process.exec('make test', { env: process.env });
make_test.stdout.pipe(process.stdout, { end: false });
make_test.stderr.pipe(process.stderr, { end: false });
make_test.on('exit', function(code) {
if (code) {
console.error('Exit Code ' + code);
} else {
console.log('\nMathQuill is now running on localhost:9292');
console.log('Open http://localhost:9292/test/demo.html\n');
}
for (var i = 0; i < q.length; i += 1) q[i]();
q = undefined;
});
}