annotate node_modules/express/lib/router/route.js @ 101:52e44ee1c791 tip master

enabled all scores in autostart script
author Rob Canning <rc@kiben.net>
date Tue, 21 Apr 2015 16:20:57 +0100
parents 0c3a2942ddee
children
rev   line source
rc@73 1 /**
rc@73 2 * Module dependencies.
rc@73 3 */
rc@73 4
rc@73 5 var debug = require('debug')('express:router:route');
rc@73 6 var methods = require('methods');
rc@73 7 var utils = require('../utils');
rc@73 8
rc@73 9 /**
rc@73 10 * Expose `Route`.
rc@73 11 */
rc@73 12
rc@73 13 module.exports = Route;
rc@73 14
rc@73 15 /**
rc@73 16 * Initialize `Route` with the given `path`,
rc@73 17 *
rc@73 18 * @param {String} path
rc@73 19 * @api private
rc@73 20 */
rc@73 21
rc@73 22 function Route(path) {
rc@73 23 debug('new %s', path);
rc@73 24 this.path = path;
rc@73 25 this.stack = undefined;
rc@73 26
rc@73 27 // route handlers for various http methods
rc@73 28 this.methods = {};
rc@73 29 }
rc@73 30
rc@73 31 /**
rc@73 32 * @return {Array} supported HTTP methods
rc@73 33 * @api private
rc@73 34 */
rc@73 35
rc@73 36 Route.prototype._options = function(){
rc@73 37 return Object.keys(this.methods).map(function(method) {
rc@73 38 return method.toUpperCase();
rc@73 39 });
rc@73 40 };
rc@73 41
rc@73 42 /**
rc@73 43 * dispatch req, res into this route
rc@73 44 *
rc@73 45 * @api private
rc@73 46 */
rc@73 47
rc@73 48 Route.prototype.dispatch = function(req, res, done){
rc@73 49 var self = this;
rc@73 50 var method = req.method.toLowerCase();
rc@73 51
rc@73 52 if (method === 'head' && !this.methods['head']) {
rc@73 53 method = 'get';
rc@73 54 }
rc@73 55
rc@73 56 req.route = self;
rc@73 57
rc@73 58 // single middleware route case
rc@73 59 if (typeof this.stack === 'function') {
rc@73 60 this.stack(req, res, done);
rc@73 61 return;
rc@73 62 }
rc@73 63
rc@73 64 var stack = self.stack;
rc@73 65 if (!stack) {
rc@73 66 return done();
rc@73 67 }
rc@73 68
rc@73 69 var idx = 0;
rc@73 70 (function next_layer(err) {
rc@73 71 if (err && err === 'route') {
rc@73 72 return done();
rc@73 73 }
rc@73 74
rc@73 75 var layer = stack[idx++];
rc@73 76 if (!layer) {
rc@73 77 return done(err);
rc@73 78 }
rc@73 79
rc@73 80 if (layer.method && layer.method !== method) {
rc@73 81 return next_layer(err);
rc@73 82 }
rc@73 83
rc@73 84 var arity = layer.handle.length;
rc@73 85 if (err) {
rc@73 86 if (arity < 4) {
rc@73 87 return next_layer(err);
rc@73 88 }
rc@73 89
rc@73 90 try {
rc@73 91 layer.handle(err, req, res, next_layer);
rc@73 92 } catch (err) {
rc@73 93 next_layer(err);
rc@73 94 }
rc@73 95 return;
rc@73 96 }
rc@73 97
rc@73 98 if (arity > 3) {
rc@73 99 return next_layer();
rc@73 100 }
rc@73 101
rc@73 102 try {
rc@73 103 layer.handle(req, res, next_layer);
rc@73 104 } catch (err) {
rc@73 105 next_layer(err);
rc@73 106 }
rc@73 107 })();
rc@73 108 };
rc@73 109
rc@73 110 /**
rc@73 111 * Add a handler for all HTTP verbs to this route.
rc@73 112 *
rc@73 113 * Behaves just like middleware and can respond or call `next`
rc@73 114 * to continue processing.
rc@73 115 *
rc@73 116 * You can use multiple `.all` call to add multiple handlers.
rc@73 117 *
rc@73 118 * function check_something(req, res, next){
rc@73 119 * next();
rc@73 120 * };
rc@73 121 *
rc@73 122 * function validate_user(req, res, next){
rc@73 123 * next();
rc@73 124 * };
rc@73 125 *
rc@73 126 * route
rc@73 127 * .all(validate_user)
rc@73 128 * .all(check_something)
rc@73 129 * .get(function(req, res, next){
rc@73 130 * res.send('hello world');
rc@73 131 * });
rc@73 132 *
rc@73 133 * @param {function} handler
rc@73 134 * @return {Route} for chaining
rc@73 135 * @api public
rc@73 136 */
rc@73 137
rc@73 138 Route.prototype.all = function(){
rc@73 139 var self = this;
rc@73 140 var callbacks = utils.flatten([].slice.call(arguments));
rc@73 141 callbacks.forEach(function(fn) {
rc@73 142 if (typeof fn !== 'function') {
rc@73 143 var type = {}.toString.call(fn);
rc@73 144 var msg = 'Route.all() requires callback functions but got a ' + type;
rc@73 145 throw new Error(msg);
rc@73 146 }
rc@73 147
rc@73 148 if (!self.stack) {
rc@73 149 self.stack = fn;
rc@73 150 }
rc@73 151 else if (typeof self.stack === 'function') {
rc@73 152 self.stack = [{ handle: self.stack }, { handle: fn }];
rc@73 153 }
rc@73 154 else {
rc@73 155 self.stack.push({ handle: fn });
rc@73 156 }
rc@73 157 });
rc@73 158
rc@73 159 return self;
rc@73 160 };
rc@73 161
rc@73 162 methods.forEach(function(method){
rc@73 163 Route.prototype[method] = function(){
rc@73 164 var self = this;
rc@73 165 var callbacks = utils.flatten([].slice.call(arguments));
rc@73 166
rc@73 167 callbacks.forEach(function(fn) {
rc@73 168 if (typeof fn !== 'function') {
rc@73 169 var type = {}.toString.call(fn);
rc@73 170 var msg = 'Route.' + method + '() requires callback functions but got a ' + type;
rc@73 171 throw new Error(msg);
rc@73 172 }
rc@73 173
rc@73 174 debug('%s %s', method, self.path);
rc@73 175
rc@73 176 if (!self.methods[method]) {
rc@73 177 self.methods[method] = true;
rc@73 178 }
rc@73 179
rc@73 180 if (!self.stack) {
rc@73 181 self.stack = [];
rc@73 182 }
rc@73 183 else if (typeof self.stack === 'function') {
rc@73 184 self.stack = [{ handle: self.stack }];
rc@73 185 }
rc@73 186
rc@73 187 self.stack.push({ method: method, handle: fn });
rc@73 188 });
rc@73 189 return self;
rc@73 190 };
rc@73 191 });