2015/03/14

Simple NodeJS front controller with static file supporting

This is a simple HTTP server that calls controller actions and serves static files.
GET and POST are supported.
Default controller/action is http://localhost:3000/home/index or just http://localhost:3000
No frameworks needed.
Use it as a bootstrap for a more complex MVC application.

server.js :

#!/usr/bin/nodejs
var http = require('http');
var fs = require('fs');
var qs = require('querystring');
var url = require('url');
var mimeTypes = {
    "html": "text/html",
    "jpeg": "image/jpeg",
    "jpg": "image/jpeg",
    "png": "image/png",
    "js": "text/javascript",
    "css": "text/css"};

server = http.createServer( function(request, response) {
 var body = '';
 if (request.method == 'POST') {
  request.on('data', function (data) {
   body += data;
   // Too much POST data, kill the connection!
   if (body.length > 1e6)
    request.connection.destroy();
  });
  request.on('end', function () {
   execute();
  });
 } else {
  execute();
  //console.log(request);
 }
 
 function execute() {
  var urlData = url.parse(request.url,true,true);
  var bodyData;
  if (body != '') {
   bodyData = qs.parse(body);
  }
  
  var fileName = "./static" + urlData.path;
  fs.stat(fileName, function(err, stats) {
   var found = false;
   if (!err && stats.isFile()) {
    found = true;
    var ext = fileName.substring(fileName.lastIndexOf(".") + 1);
    var mimeType = mimeTypes[ext];
    response.writeHead(200, {"Content-Type": mimeType || "application/octet-stream"});
    var fileStream = fs.createReadStream(fileName);
    fileStream.pipe(response);
   } else {
    var pathSplit = urlData.path.substring(1).split("/");
    var controllerName = (pathSplit[0] ? pathSplit[0] : "home") + "_controller";
    var controllerFound = false;
    try {
     require.resolve(controllerName);
     controllerFound = true;
    } catch (e) {
    }
    if (controllerFound) {
     var controller = require(controllerName);
     var actionName = pathSplit[1] || "index";
     if (typeof(controller) == "object") {
      var action = controller[actionName];
      if (typeof(action) == "function") {
       found = true;
       action(request, response);
      }
     }
    }
    if (!found) {
     response.writeHead(404, {"Content-Type": "text/html"});
     response.end("<h1>Not found</h1>
");
    }
   }
  });  
 }
});

port = process.env.OPENSHIFT_NODEJS_PORT || 3000;
host = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1';
server.listen(port, host);
console.log('Listening at http://' + host + ':' + port);

node_modules/home_controller.js :


module.exports = {
 "index" : function(request, response) {
  response.writeHead(200, {"Content-Type": "text/html"});
  response.end("<h1>Index on Home Controller</h1>
");
 }
}

2015/03/07

How to use a USB stick to boot Hiren's Boot CD directly from ISO

First install GRUB2 on USB by following these instructions (using linux).

Put this on USB_PATH/boot/grub/grub.cfg

menuentry "Hiren's BootCD 15.2" {
loopback loop "/Hirens.BootCD.15.2.iso"
set root=(loop)
ntldr (loop)/HBCD/grldr
}

Extract menu.lst from the ISO file and put it on USB root directory.
Insert these three map instructions before the first title:

map --set-root /Hirens.BootCD.15.2.iso
map /Hirens.BootCD.15.2.iso (fd0)
map --hook

title Boot From Hard Drive (Windows Vista/7/2008 or Xp)\n

Not all stuffs are going to work but that's the colosest we can do.
The best solution is still extracting HBCD folder to USB root directory. I this case your grub.cfg file needs only this:

menuentry "Hiren's BootCD 15.2" {
  ntldr /HBCD/grldr
}
And you don't need a custom menu.lst file.