Mikael's blog

A developers sixth time trying to maintain a blog

Source Code - Root / router.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*****************************************
 *   Router
 *****************************************
 *   Author:  mikael.lofjard@gmail.com
 *   Website: http://lofjard.se
 *   License: MIT License
 ****************************************/
  
var Router = (function() {
  var url = require('url');
  var path = require('path');
  var querystring = require('querystring');
  
  var env = require('./environmentManager').EnvironmentManager;
  var cm = require('./cacheManager').CacheManager;
  var responseManager = require('./responseManager').ResponseManager;
  
  var trimSlashRegEx = new RegExp('[/]+, 'g');
  var resolveExcludes = ['.html', '.js', '.css', '.png', '.jpg', '.gif', '.ico', '.txt'];
  var routeTable = {};
  
  function buildRouteTable(routes) {
    for (var route in routes) {
      console.log('Router: Building route table entry for: ' + route);
  
      var handle = routes[route];
      var routeSplit = route.split('/\{');
      var pathName = routeSplit[0];
      var regexRoute = new RegExp(route.replace(/{\w+}/g, '{(\\w+)}') + ', '');
      var regexPath = new RegExp('^' + route.replace(/{\w+}/g, '([^\/]+)') + ', '');
      routeTable[route] = {
        handle : handle,
        pathName : pathName,
        regexRoute : regexRoute,
        regexPath : regexPath
      }
    }
    return;
  }
  
  return {
  
    init: function(routes) {
      buildRouteTable(routes);
    },
  
    route: function(request, response) {
      var pathName = url.parse(request.url).pathname;
  
      if (resolveExcludes.indexOf(path.extname(pathName)) === -1) {
        var lastSlashPos = pathName.lastIndexOf("/");
        if ((lastSlashPos > 0) && (lastSlashPos === pathName.length - 1)) {
          pathName = pathName.replace(trimSlashRegEx, '');
        }
  
        env.info('Router: About to route a request for ' + pathName);
  
        var cachedResponse = cm.fetch(pathName);
  
        if (cachedResponse !== null) {
          responseManager.writeCachedResponse(response, pathName);
          return;
        } else {
          for(var route in routeTable) {
            if (routeTable[route].regexPath.test(pathName)) {
  
              var attributes = routeTable[route].regexRoute.exec(route);
              var values = routeTable[route].regexPath.exec(pathName);
  
              request.params = {};
  
              if (attributes.length > 1) {
                for (var i = 1; i < attributes.length; i++){
                  request.params[attributes[i]] = decodeURIComponent(values[i]);
                }
              }
  
              routeTable[route].handle(request, response);
              return;
            }
          }
        }
      }
  
      env.info('Router: Unhandled request for ' + pathName);
      // default 404
      response.writeHead(404);
      response.write("404 Not found.")
      response.end();
      return;
      //routeTable.defaultFileRoute.handle(request, response);
    }
  };
  
}());
  
  
typeof(exports) != 'undefined' ? exports.Router = Router : null;