aboutsummaryrefslogtreecommitdiffstats
path: root/node_modules/express/lib/router
diff options
context:
space:
mode:
authorTeddy Wing2013-04-27 18:20:41 -0400
committerTeddy Wing2013-04-27 18:20:41 -0400
commit4b14305623d5ddc59f435fc5e35c54c0def1d392 (patch)
treeef780015587343a48c46a59a7ccd0263308d062a /node_modules/express/lib/router
parent52127aee97d0d16be652d2063c9aefbbef234f43 (diff)
downloadWho-am-I-4b14305623d5ddc59f435fc5e35c54c0def1d392.tar.bz2
Change to node/express app
Diffstat (limited to 'node_modules/express/lib/router')
-rw-r--r--node_modules/express/lib/router/index.js273
-rw-r--r--node_modules/express/lib/router/route.js72
2 files changed, 345 insertions, 0 deletions
diff --git a/node_modules/express/lib/router/index.js b/node_modules/express/lib/router/index.js
new file mode 100644
index 0000000..662dc29
--- /dev/null
+++ b/node_modules/express/lib/router/index.js
@@ -0,0 +1,273 @@
+/**
+ * Module dependencies.
+ */
+
+var Route = require('./route')
+ , utils = require('../utils')
+ , methods = require('methods')
+ , debug = require('debug')('express:router')
+ , parse = require('connect').utils.parseUrl;
+
+/**
+ * Expose `Router` constructor.
+ */
+
+exports = module.exports = Router;
+
+/**
+ * Initialize a new `Router` with the given `options`.
+ *
+ * @param {Object} options
+ * @api private
+ */
+
+function Router(options) {
+ options = options || {};
+ var self = this;
+ this.map = {};
+ this.params = {};
+ this._params = [];
+ this.caseSensitive = options.caseSensitive;
+ this.strict = options.strict;
+ this.middleware = function router(req, res, next){
+ self._dispatch(req, res, next);
+ };
+}
+
+/**
+ * Register a param callback `fn` for the given `name`.
+ *
+ * @param {String|Function} name
+ * @param {Function} fn
+ * @return {Router} for chaining
+ * @api public
+ */
+
+Router.prototype.param = function(name, fn){
+ // param logic
+ if ('function' == typeof name) {
+ this._params.push(name);
+ return;
+ }
+
+ // apply param functions
+ var params = this._params
+ , len = params.length
+ , ret;
+
+ for (var i = 0; i < len; ++i) {
+ if (ret = params[i](name, fn)) {
+ fn = ret;
+ }
+ }
+
+ // ensure we end up with a
+ // middleware function
+ if ('function' != typeof fn) {
+ throw new Error('invalid param() call for ' + name + ', got ' + fn);
+ }
+
+ (this.params[name] = this.params[name] || []).push(fn);
+ return this;
+};
+
+/**
+ * Route dispatcher aka the route "middleware".
+ *
+ * @param {IncomingMessage} req
+ * @param {ServerResponse} res
+ * @param {Function} next
+ * @api private
+ */
+
+Router.prototype._dispatch = function(req, res, next){
+ var params = this.params
+ , self = this;
+
+ debug('dispatching %s %s (%s)', req.method, req.url, req.originalUrl);
+
+ // route dispatch
+ (function pass(i, err){
+ var paramCallbacks
+ , paramIndex = 0
+ , paramVal
+ , route
+ , keys
+ , key;
+
+ // match next route
+ function nextRoute(err) {
+ pass(req._route_index + 1, err);
+ }
+
+ // match route
+ req.route = route = self.matchRequest(req, i);
+
+ // no route
+ if (!route) return next(err);
+ debug('matched %s %s', route.method, route.path);
+
+ // we have a route
+ // start at param 0
+ req.params = route.params;
+ keys = route.keys;
+ i = 0;
+
+ // param callbacks
+ function param(err) {
+ paramIndex = 0;
+ key = keys[i++];
+ paramVal = key && req.params[key.name];
+ paramCallbacks = key && params[key.name];
+
+ try {
+ if ('route' == err) {
+ nextRoute();
+ } else if (err) {
+ i = 0;
+ callbacks(err);
+ } else if (paramCallbacks && undefined !== paramVal) {
+ paramCallback();
+ } else if (key) {
+ param();
+ } else {
+ i = 0;
+ callbacks();
+ }
+ } catch (err) {
+ param(err);
+ }
+ };
+
+ param(err);
+
+ // single param callbacks
+ function paramCallback(err) {
+ var fn = paramCallbacks[paramIndex++];
+ if (err || !fn) return param(err);
+ fn(req, res, paramCallback, paramVal, key.name);
+ }
+
+ // invoke route callbacks
+ function callbacks(err) {
+ var fn = route.callbacks[i++];
+ try {
+ if ('route' == err) {
+ nextRoute();
+ } else if (err && fn) {
+ if (fn.length < 4) return callbacks(err);
+ fn(err, req, res, callbacks);
+ } else if (fn) {
+ if (fn.length < 4) return fn(req, res, callbacks);
+ callbacks();
+ } else {
+ nextRoute(err);
+ }
+ } catch (err) {
+ callbacks(err);
+ }
+ }
+ })(0);
+};
+
+/**
+ * Attempt to match a route for `req`
+ * with optional starting index of `i`
+ * defaulting to 0.
+ *
+ * @param {IncomingMessage} req
+ * @param {Number} i
+ * @return {Route}
+ * @api private
+ */
+
+Router.prototype.matchRequest = function(req, i, head){
+ var method = req.method.toLowerCase()
+ , url = parse(req)
+ , path = url.pathname
+ , routes = this.map
+ , i = i || 0
+ , route;
+
+ // HEAD support
+ if (!head && 'head' == method) {
+ route = this.matchRequest(req, i, true);
+ if (route) return route;
+ method = 'get';
+ }
+
+ // routes for this method
+ if (routes = routes[method]) {
+
+ // matching routes
+ for (var len = routes.length; i < len; ++i) {
+ route = routes[i];
+ if (route.match(path)) {
+ req._route_index = i;
+ return route;
+ }
+ }
+ }
+};
+
+/**
+ * Attempt to match a route for `method`
+ * and `url` with optional starting
+ * index of `i` defaulting to 0.
+ *
+ * @param {String} method
+ * @param {String} url
+ * @param {Number} i
+ * @return {Route}
+ * @api private
+ */
+
+Router.prototype.match = function(method, url, i, head){
+ var req = { method: method, url: url };
+ return this.matchRequest(req, i, head);
+};
+
+/**
+ * Route `method`, `path`, and one or more callbacks.
+ *
+ * @param {String} method
+ * @param {String} path
+ * @param {Function} callback...
+ * @return {Router} for chaining
+ * @api private
+ */
+
+Router.prototype.route = function(method, path, callbacks){
+ var method = method.toLowerCase()
+ , callbacks = utils.flatten([].slice.call(arguments, 2));
+
+ // ensure path was given
+ if (!path) throw new Error('Router#' + method + '() requires a path');
+
+ // ensure all callbacks are functions
+ callbacks.forEach(function(fn, i){
+ if ('function' == typeof fn) return;
+ var type = {}.toString.call(fn);
+ var msg = '.' + method + '() requires callback functions but got a ' + type;
+ throw new Error(msg);
+ });
+
+ // create the route
+ debug('defined %s %s', method, path);
+ var route = new Route(method, path, callbacks, {
+ sensitive: this.caseSensitive,
+ strict: this.strict
+ });
+
+ // add it
+ (this.map[method] = this.map[method] || []).push(route);
+ return this;
+};
+
+methods.forEach(function(method){
+ Router.prototype[method] = function(path){
+ var args = [method].concat([].slice.call(arguments));
+ this.route.apply(this, args);
+ return this;
+ };
+});
diff --git a/node_modules/express/lib/router/route.js b/node_modules/express/lib/router/route.js
new file mode 100644
index 0000000..c1a0b5e
--- /dev/null
+++ b/node_modules/express/lib/router/route.js
@@ -0,0 +1,72 @@
+
+/**
+ * Module dependencies.
+ */
+
+var utils = require('../utils');
+
+/**
+ * Expose `Route`.
+ */
+
+module.exports = Route;
+
+/**
+ * Initialize `Route` with the given HTTP `method`, `path`,
+ * and an array of `callbacks` and `options`.
+ *
+ * Options:
+ *
+ * - `sensitive` enable case-sensitive routes
+ * - `strict` enable strict matching for trailing slashes
+ *
+ * @param {String} method
+ * @param {String} path
+ * @param {Array} callbacks
+ * @param {Object} options.
+ * @api private
+ */
+
+function Route(method, path, callbacks, options) {
+ options = options || {};
+ this.path = path;
+ this.method = method;
+ this.callbacks = callbacks;
+ this.regexp = utils.pathRegexp(path
+ , this.keys = []
+ , options.sensitive
+ , options.strict);
+}
+
+/**
+ * Check if this route matches `path`, if so
+ * populate `.params`.
+ *
+ * @param {String} path
+ * @return {Boolean}
+ * @api private
+ */
+
+Route.prototype.match = function(path){
+ var keys = this.keys
+ , params = this.params = []
+ , m = this.regexp.exec(path);
+
+ if (!m) return false;
+
+ for (var i = 1, len = m.length; i < len; ++i) {
+ var key = keys[i - 1];
+
+ var val = 'string' == typeof m[i]
+ ? decodeURIComponent(m[i])
+ : m[i];
+
+ if (key) {
+ params[key.name] = val;
+ } else {
+ params.push(val);
+ }
+ }
+
+ return true;
+};