socketioMEANseed/server/node_modules/express/lib/router/route.js
server/node_modules/express/lib/router/route.jsRaw
1/**
2 * Module dependencies.
3 */
4
5var debug = require('debug')('express:router:route');
6var Layer = require('./layer');
7var methods = require('methods');
8var utils = require('../utils');
9
10/**
11 * Expose `Route`.
12 */
13
14module.exports = Route;
15
16/**
17 * Initialize `Route` with the given `path`,
18 *
19 * @param {String} path
20 * @api private
21 */
22
23function 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
36Route.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
55Route.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
67Route.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
133Route.prototype.all = function(){
134 var callbacks = utils.flatten([].slice.call(arguments));
135 callbacks.forEach(function(fn) {
136 if (typeof fn !== 'function') {
137 var type = {}.toString.call(fn);
138 var msg = 'Route.all() requires callback functions but got a ' + type;
139 throw new Error(msg);
140 }
141
142 var layer = Layer('/', {}, fn);
143 layer.method = undefined;
144
145 this.methods._all = true;
146 this.stack.push(layer);
147 }, this);
148
149 return this;
150};
151
152methods.forEach(function(method){
153 Route.prototype[method] = function(){
154 var callbacks = utils.flatten([].slice.call(arguments));
155
156 callbacks.forEach(function(fn) {
157 if (typeof fn !== 'function') {
158 var type = {}.toString.call(fn);
159 var msg = 'Route.' + method + '() requires callback functions but got a ' + type;
160 throw new Error(msg);
161 }
162
163 debug('%s %s', method, this.path);
164
165 var layer = Layer('/', {}, fn);
166 layer.method = method;
167
168 this.methods[method] = true;
169 this.stack.push(layer);
170 }, this);
171 return this;
172 };
173});