Super simple connect

Published on:

I was curious what it would take to write a super simple implementation of the Node.js connect library: https://github.com/senchalabs/connect.

// This should be compatible with https://github.com/senchalabs/connect
// Allows you to stick a stack of middleware in to process the request
// and response in a pipeline fashion.
var url = require('url');

var handlers = [];
var errHandlers = [];

// Not sure if this is exactly the same workflow that connect uses but . . .
//
// Loop over all the handlers in order. Each one will process the
// request and/or reponse in some way (or not). As long as the handler
// calls next() we keep going. If one of the handlers doesn't call next()
// we are done (we assume at that point the handler called res.end() or
// something similar).
//
// If one of the handlers calls next(err) we are done with
// handlers and we start looping over the errHandlers. As long as the
// errHandlers call next we keep going. If one of the errHandlers doesn't
// call next we are done.
function handleRequest(req, res) {
  var hI = 0;
  var eI = 0;
  var pf;
  var next = function next(err) {
    if (err) {
      pf = errHandlers[eI++];
    } else {
      pf = handlers[hI++];
    }
    if (!pf) {
      return res.end('not found', 404);
    }
    if (!pf.path || url.parse(req.url).pathname.indexOf(pf.path) === 0) {
      if (pf.fn.length > 3) {
        pf.fn(req, res, err, next);
      } else {
        pf.fn(req, res, next);
      }
    } else {
      next(err);
    }
  };
  next();
}

handleRequest.use = function use(path, fn) {
  if ((typeof path) !== 'string') {
    fn = path;
    path = null;
  }
  if (fn.length > 3) {
    errHandlers.push({
      path: path,
      fn: fn
    });
  } else {
    handlers.push({
      path: path,
      fn: fn
    });
  }
};

module.exports = handleRequest;

Here's how you would use it. Pretty much the same as connect.

var http = require('http');
var serveStatic = require('serve-static');
var send = require('send');
var session = require('cookie-session');
var middleman = require('./app/middleman');
var api = require('./app/api');

middleman.use(session({
  keys: ['#KDIEkd@%vv11', 'xidk4%d']
}));

middleman.use(serveStatic('web'));

api(middleman);

middleman.use(function(req, res, next) {
  send(req, 'web/index.html').pipe(res);
});

var server = http.createServer(middleman);

server.listen(9494);
server.timeout = 2000;

console.log('listening on 9494');