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