aboutsummaryrefslogtreecommitdiffhomepage
path: root/node_modules/express/lib/router
diff options
context:
space:
mode:
authorYaroslav De La Peña Smirnov <yaros.rus_89@live.com.mx>2017-11-29 11:44:34 +0300
committerYaroslav De La Peña Smirnov <yaros.rus_89@live.com.mx>2017-11-29 11:44:34 +0300
commit67fdec20726e48ba3a934cb25bb30d47ec4a4f29 (patch)
tree37fd9f4f0b0c20103e1646fc83021e4765de3680 /node_modules/express/lib/router
downloadspanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.tar.gz
spanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.zip
Initial commit, version 0.5.3
Diffstat (limited to 'node_modules/express/lib/router')
-rw-r--r--node_modules/express/lib/router/index.js662
-rw-r--r--node_modules/express/lib/router/layer.js181
-rw-r--r--node_modules/express/lib/router/route.js216
3 files changed, 1059 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..60727ed
--- /dev/null
+++ b/node_modules/express/lib/router/index.js
@@ -0,0 +1,662 @@
+/*!
+ * express
+ * Copyright(c) 2009-2013 TJ Holowaychuk
+ * Copyright(c) 2013 Roman Shtylman
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict';
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var Route = require('./route');
+var Layer = require('./layer');
+var methods = require('methods');
+var mixin = require('utils-merge');
+var debug = require('debug')('express:router');
+var deprecate = require('depd')('express');
+var flatten = require('array-flatten');
+var parseUrl = require('parseurl');
+var setPrototypeOf = require('setprototypeof')
+
+/**
+ * Module variables.
+ * @private
+ */
+
+var objectRegExp = /^\[object (\S+)\]$/;
+var slice = Array.prototype.slice;
+var toString = Object.prototype.toString;
+
+/**
+ * Initialize a new `Router` with the given `options`.
+ *
+ * @param {Object} options
+ * @return {Router} which is an callable function
+ * @public
+ */
+
+var proto = module.exports = function(options) {
+ var opts = options || {};
+
+ function router(req, res, next) {
+ router.handle(req, res, next);
+ }
+
+ // mixin Router class functions
+ setPrototypeOf(router, proto)
+
+ router.params = {};
+ router._params = [];
+ router.caseSensitive = opts.caseSensitive;
+ router.mergeParams = opts.mergeParams;
+ router.strict = opts.strict;
+ router.stack = [];
+
+ return router;
+};
+
+/**
+ * Map the given param placeholder `name`(s) to the given callback.
+ *
+ * Parameter mapping is used to provide pre-conditions to routes
+ * which use normalized placeholders. For example a _:user_id_ parameter
+ * could automatically load a user's information from the database without
+ * any additional code,
+ *
+ * The callback uses the same signature as middleware, the only difference
+ * being that the value of the placeholder is passed, in this case the _id_
+ * of the user. Once the `next()` function is invoked, just like middleware
+ * it will continue on to execute the route, or subsequent parameter functions.
+ *
+ * Just like in middleware, you must either respond to the request or call next
+ * to avoid stalling the request.
+ *
+ * app.param('user_id', function(req, res, next, id){
+ * User.find(id, function(err, user){
+ * if (err) {
+ * return next(err);
+ * } else if (!user) {
+ * return next(new Error('failed to load user'));
+ * }
+ * req.user = user;
+ * next();
+ * });
+ * });
+ *
+ * @param {String} name
+ * @param {Function} fn
+ * @return {app} for chaining
+ * @public
+ */
+
+proto.param = function param(name, fn) {
+ // param logic
+ if (typeof name === 'function') {
+ deprecate('router.param(fn): Refactor to use path params');
+ this._params.push(name);
+ return;
+ }
+
+ // apply param functions
+ var params = this._params;
+ var len = params.length;
+ var ret;
+
+ if (name[0] === ':') {
+ deprecate('router.param(' + JSON.stringify(name) + ', fn): Use router.param(' + JSON.stringify(name.substr(1)) + ', fn) instead');
+ name = name.substr(1);
+ }
+
+ 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;
+};
+
+/**
+ * Dispatch a req, res into the router.
+ * @private
+ */
+
+proto.handle = function handle(req, res, out) {
+ var self = this;
+
+ debug('dispatching %s %s', req.method, req.url);
+
+ var idx = 0;
+ var protohost = getProtohost(req.url) || ''
+ var removed = '';
+ var slashAdded = false;
+ var paramcalled = {};
+
+ // store options for OPTIONS request
+ // only used if OPTIONS request
+ var options = [];
+
+ // middleware and routes
+ var stack = self.stack;
+
+ // manage inter-router variables
+ var parentParams = req.params;
+ var parentUrl = req.baseUrl || '';
+ var done = restore(out, req, 'baseUrl', 'next', 'params');
+
+ // setup next layer
+ req.next = next;
+
+ // for options requests, respond with a default if nothing else responds
+ if (req.method === 'OPTIONS') {
+ done = wrap(done, function(old, err) {
+ if (err || options.length === 0) return old(err);
+ sendOptionsResponse(res, options, old);
+ });
+ }
+
+ // setup basic req values
+ req.baseUrl = parentUrl;
+ req.originalUrl = req.originalUrl || req.url;
+
+ next();
+
+ function next(err) {
+ var layerError = err === 'route'
+ ? null
+ : err;
+
+ // remove added slash
+ if (slashAdded) {
+ req.url = req.url.substr(1);
+ slashAdded = false;
+ }
+
+ // restore altered req.url
+ if (removed.length !== 0) {
+ req.baseUrl = parentUrl;
+ req.url = protohost + removed + req.url.substr(protohost.length);
+ removed = '';
+ }
+
+ // signal to exit router
+ if (layerError === 'router') {
+ setImmediate(done, null)
+ return
+ }
+
+ // no more matching layers
+ if (idx >= stack.length) {
+ setImmediate(done, layerError);
+ return;
+ }
+
+ // get pathname of request
+ var path = getPathname(req);
+
+ if (path == null) {
+ return done(layerError);
+ }
+
+ // find next matching layer
+ var layer;
+ var match;
+ var route;
+
+ while (match !== true && idx < stack.length) {
+ layer = stack[idx++];
+ match = matchLayer(layer, path);
+ route = layer.route;
+
+ if (typeof match !== 'boolean') {
+ // hold on to layerError
+ layerError = layerError || match;
+ }
+
+ if (match !== true) {
+ continue;
+ }
+
+ if (!route) {
+ // process non-route handlers normally
+ continue;
+ }
+
+ if (layerError) {
+ // routes do not match with a pending error
+ match = false;
+ continue;
+ }
+
+ var method = req.method;
+ var has_method = route._handles_method(method);
+
+ // build up automatic options response
+ if (!has_method && method === 'OPTIONS') {
+ appendMethods(options, route._options());
+ }
+
+ // don't even bother matching route
+ if (!has_method && method !== 'HEAD') {
+ match = false;
+ continue;
+ }
+ }
+
+ // no match
+ if (match !== true) {
+ return done(layerError);
+ }
+
+ // store route for dispatch on change
+ if (route) {
+ req.route = route;
+ }
+
+ // Capture one-time layer values
+ req.params = self.mergeParams
+ ? mergeParams(layer.params, parentParams)
+ : layer.params;
+ var layerPath = layer.path;
+
+ // this should be done for the layer
+ self.process_params(layer, paramcalled, req, res, function (err) {
+ if (err) {
+ return next(layerError || err);
+ }
+
+ if (route) {
+ return layer.handle_request(req, res, next);
+ }
+
+ trim_prefix(layer, layerError, layerPath, path);
+ });
+ }
+
+ function trim_prefix(layer, layerError, layerPath, path) {
+ if (layerPath.length !== 0) {
+ // Validate path breaks on a path separator
+ var c = path[layerPath.length]
+ if (c && c !== '/' && c !== '.') return next(layerError)
+
+ // Trim off the part of the url that matches the route
+ // middleware (.use stuff) needs to have the path stripped
+ debug('trim prefix (%s) from url %s', layerPath, req.url);
+ removed = layerPath;
+ req.url = protohost + req.url.substr(protohost.length + removed.length);
+
+ // Ensure leading slash
+ if (!protohost && req.url[0] !== '/') {
+ req.url = '/' + req.url;
+ slashAdded = true;
+ }
+
+ // Setup base URL (no trailing slash)
+ req.baseUrl = parentUrl + (removed[removed.length - 1] === '/'
+ ? removed.substring(0, removed.length - 1)
+ : removed);
+ }
+
+ debug('%s %s : %s', layer.name, layerPath, req.originalUrl);
+
+ if (layerError) {
+ layer.handle_error(layerError, req, res, next);
+ } else {
+ layer.handle_request(req, res, next);
+ }
+ }
+};
+
+/**
+ * Process any parameters for the layer.
+ * @private
+ */
+
+proto.process_params = function process_params(layer, called, req, res, done) {
+ var params = this.params;
+
+ // captured parameters from the layer, keys and values
+ var keys = layer.keys;
+
+ // fast track
+ if (!keys || keys.length === 0) {
+ return done();
+ }
+
+ var i = 0;
+ var name;
+ var paramIndex = 0;
+ var key;
+ var paramVal;
+ var paramCallbacks;
+ var paramCalled;
+
+ // process params in order
+ // param callbacks can be async
+ function param(err) {
+ if (err) {
+ return done(err);
+ }
+
+ if (i >= keys.length ) {
+ return done();
+ }
+
+ paramIndex = 0;
+ key = keys[i++];
+ name = key.name;
+ paramVal = req.params[name];
+ paramCallbacks = params[name];
+ paramCalled = called[name];
+
+ if (paramVal === undefined || !paramCallbacks) {
+ return param();
+ }
+
+ // param previously called with same value or error occurred
+ if (paramCalled && (paramCalled.match === paramVal
+ || (paramCalled.error && paramCalled.error !== 'route'))) {
+ // restore value
+ req.params[name] = paramCalled.value;
+
+ // next param
+ return param(paramCalled.error);
+ }
+
+ called[name] = paramCalled = {
+ error: null,
+ match: paramVal,
+ value: paramVal
+ };
+
+ paramCallback();
+ }
+
+ // single param callbacks
+ function paramCallback(err) {
+ var fn = paramCallbacks[paramIndex++];
+
+ // store updated value
+ paramCalled.value = req.params[key.name];
+
+ if (err) {
+ // store error
+ paramCalled.error = err;
+ param(err);
+ return;
+ }
+
+ if (!fn) return param();
+
+ try {
+ fn(req, res, paramCallback, paramVal, key.name);
+ } catch (e) {
+ paramCallback(e);
+ }
+ }
+
+ param();
+};
+
+/**
+ * Use the given middleware function, with optional path, defaulting to "/".
+ *
+ * Use (like `.all`) will run for any http METHOD, but it will not add
+ * handlers for those methods so OPTIONS requests will not consider `.use`
+ * functions even if they could respond.
+ *
+ * The other difference is that _route_ path is stripped and not visible
+ * to the handler function. The main effect of this feature is that mounted
+ * handlers can operate without any code changes regardless of the "prefix"
+ * pathname.
+ *
+ * @public
+ */
+
+proto.use = function use(fn) {
+ var offset = 0;
+ var path = '/';
+
+ // default path to '/'
+ // disambiguate router.use([fn])
+ if (typeof fn !== 'function') {
+ var arg = fn;
+
+ while (Array.isArray(arg) && arg.length !== 0) {
+ arg = arg[0];
+ }
+
+ // first arg is the path
+ if (typeof arg !== 'function') {
+ offset = 1;
+ path = fn;
+ }
+ }
+
+ var callbacks = flatten(slice.call(arguments, offset));
+
+ if (callbacks.length === 0) {
+ throw new TypeError('Router.use() requires a middleware function')
+ }
+
+ for (var i = 0; i < callbacks.length; i++) {
+ var fn = callbacks[i];
+
+ if (typeof fn !== 'function') {
+ throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
+ }
+
+ // add the middleware
+ debug('use %o %s', path, fn.name || '<anonymous>')
+
+ var layer = new Layer(path, {
+ sensitive: this.caseSensitive,
+ strict: false,
+ end: false
+ }, fn);
+
+ layer.route = undefined;
+
+ this.stack.push(layer);
+ }
+
+ return this;
+};
+
+/**
+ * Create a new Route for the given path.
+ *
+ * Each route contains a separate middleware stack and VERB handlers.
+ *
+ * See the Route api documentation for details on adding handlers
+ * and middleware to routes.
+ *
+ * @param {String} path
+ * @return {Route}
+ * @public
+ */
+
+proto.route = function route(path) {
+ var route = new Route(path);
+
+ var layer = new Layer(path, {
+ sensitive: this.caseSensitive,
+ strict: this.strict,
+ end: true
+ }, route.dispatch.bind(route));
+
+ layer.route = route;
+
+ this.stack.push(layer);
+ return route;
+};
+
+// create Router#VERB functions
+methods.concat('all').forEach(function(method){
+ proto[method] = function(path){
+ var route = this.route(path)
+ route[method].apply(route, slice.call(arguments, 1));
+ return this;
+ };
+});
+
+// append methods to a list of methods
+function appendMethods(list, addition) {
+ for (var i = 0; i < addition.length; i++) {
+ var method = addition[i];
+ if (list.indexOf(method) === -1) {
+ list.push(method);
+ }
+ }
+}
+
+// get pathname of request
+function getPathname(req) {
+ try {
+ return parseUrl(req).pathname;
+ } catch (err) {
+ return undefined;
+ }
+}
+
+// Get get protocol + host for a URL
+function getProtohost(url) {
+ if (typeof url !== 'string' || url.length === 0 || url[0] === '/') {
+ return undefined
+ }
+
+ var searchIndex = url.indexOf('?')
+ var pathLength = searchIndex !== -1
+ ? searchIndex
+ : url.length
+ var fqdnIndex = url.substr(0, pathLength).indexOf('://')
+
+ return fqdnIndex !== -1
+ ? url.substr(0, url.indexOf('/', 3 + fqdnIndex))
+ : undefined
+}
+
+// get type for error message
+function gettype(obj) {
+ var type = typeof obj;
+
+ if (type !== 'object') {
+ return type;
+ }
+
+ // inspect [[Class]] for objects
+ return toString.call(obj)
+ .replace(objectRegExp, '$1');
+}
+
+/**
+ * Match path to a layer.
+ *
+ * @param {Layer} layer
+ * @param {string} path
+ * @private
+ */
+
+function matchLayer(layer, path) {
+ try {
+ return layer.match(path);
+ } catch (err) {
+ return err;
+ }
+}
+
+// merge params with parent params
+function mergeParams(params, parent) {
+ if (typeof parent !== 'object' || !parent) {
+ return params;
+ }
+
+ // make copy of parent for base
+ var obj = mixin({}, parent);
+
+ // simple non-numeric merging
+ if (!(0 in params) || !(0 in parent)) {
+ return mixin(obj, params);
+ }
+
+ var i = 0;
+ var o = 0;
+
+ // determine numeric gaps
+ while (i in params) {
+ i++;
+ }
+
+ while (o in parent) {
+ o++;
+ }
+
+ // offset numeric indices in params before merge
+ for (i--; i >= 0; i--) {
+ params[i + o] = params[i];
+
+ // create holes for the merge when necessary
+ if (i < o) {
+ delete params[i];
+ }
+ }
+
+ return mixin(obj, params);
+}
+
+// restore obj props after function
+function restore(fn, obj) {
+ var props = new Array(arguments.length - 2);
+ var vals = new Array(arguments.length - 2);
+
+ for (var i = 0; i < props.length; i++) {
+ props[i] = arguments[i + 2];
+ vals[i] = obj[props[i]];
+ }
+
+ return function () {
+ // restore vals
+ for (var i = 0; i < props.length; i++) {
+ obj[props[i]] = vals[i];
+ }
+
+ return fn.apply(this, arguments);
+ };
+}
+
+// send an OPTIONS response
+function sendOptionsResponse(res, options, next) {
+ try {
+ var body = options.join(',');
+ res.set('Allow', body);
+ res.send(body);
+ } catch (err) {
+ next(err);
+ }
+}
+
+// wrap a function
+function wrap(old, fn) {
+ return function proxy() {
+ var args = new Array(arguments.length + 1);
+
+ args[0] = old;
+ for (var i = 0, len = arguments.length; i < len; i++) {
+ args[i + 1] = arguments[i];
+ }
+
+ fn.apply(this, args);
+ };
+}
diff --git a/node_modules/express/lib/router/layer.js b/node_modules/express/lib/router/layer.js
new file mode 100644
index 0000000..4dc8e86
--- /dev/null
+++ b/node_modules/express/lib/router/layer.js
@@ -0,0 +1,181 @@
+/*!
+ * express
+ * Copyright(c) 2009-2013 TJ Holowaychuk
+ * Copyright(c) 2013 Roman Shtylman
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict';
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var pathRegexp = require('path-to-regexp');
+var debug = require('debug')('express:router:layer');
+
+/**
+ * Module variables.
+ * @private
+ */
+
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = Layer;
+
+function Layer(path, options, fn) {
+ if (!(this instanceof Layer)) {
+ return new Layer(path, options, fn);
+ }
+
+ debug('new %o', path)
+ var opts = options || {};
+
+ this.handle = fn;
+ this.name = fn.name || '<anonymous>';
+ this.params = undefined;
+ this.path = undefined;
+ this.regexp = pathRegexp(path, this.keys = [], opts);
+
+ // set fast path flags
+ this.regexp.fast_star = path === '*'
+ this.regexp.fast_slash = path === '/' && opts.end === false
+}
+
+/**
+ * Handle the error for the layer.
+ *
+ * @param {Error} error
+ * @param {Request} req
+ * @param {Response} res
+ * @param {function} next
+ * @api private
+ */
+
+Layer.prototype.handle_error = function handle_error(error, req, res, next) {
+ var fn = this.handle;
+
+ if (fn.length !== 4) {
+ // not a standard error handler
+ return next(error);
+ }
+
+ try {
+ fn(error, req, res, next);
+ } catch (err) {
+ next(err);
+ }
+};
+
+/**
+ * Handle the request for the layer.
+ *
+ * @param {Request} req
+ * @param {Response} res
+ * @param {function} next
+ * @api private
+ */
+
+Layer.prototype.handle_request = function handle(req, res, next) {
+ var fn = this.handle;
+
+ if (fn.length > 3) {
+ // not a standard request handler
+ return next();
+ }
+
+ try {
+ fn(req, res, next);
+ } catch (err) {
+ next(err);
+ }
+};
+
+/**
+ * Check if this route matches `path`, if so
+ * populate `.params`.
+ *
+ * @param {String} path
+ * @return {Boolean}
+ * @api private
+ */
+
+Layer.prototype.match = function match(path) {
+ var match
+
+ if (path != null) {
+ // fast path non-ending match for / (any path matches)
+ if (this.regexp.fast_slash) {
+ this.params = {}
+ this.path = ''
+ return true
+ }
+
+ // fast path for * (everything matched in a param)
+ if (this.regexp.fast_star) {
+ this.params = {'0': decode_param(path)}
+ this.path = path
+ return true
+ }
+
+ // match the path
+ match = this.regexp.exec(path)
+ }
+
+ if (!match) {
+ this.params = undefined;
+ this.path = undefined;
+ return false;
+ }
+
+ // store values
+ this.params = {};
+ this.path = match[0]
+
+ var keys = this.keys;
+ var params = this.params;
+
+ for (var i = 1; i < match.length; i++) {
+ var key = keys[i - 1];
+ var prop = key.name;
+ var val = decode_param(match[i])
+
+ if (val !== undefined || !(hasOwnProperty.call(params, prop))) {
+ params[prop] = val;
+ }
+ }
+
+ return true;
+};
+
+/**
+ * Decode param value.
+ *
+ * @param {string} val
+ * @return {string}
+ * @private
+ */
+
+function decode_param(val) {
+ if (typeof val !== 'string' || val.length === 0) {
+ return val;
+ }
+
+ try {
+ return decodeURIComponent(val);
+ } catch (err) {
+ if (err instanceof URIError) {
+ err.message = 'Failed to decode param \'' + val + '\'';
+ err.status = err.statusCode = 400;
+ }
+
+ throw err;
+ }
+}
diff --git a/node_modules/express/lib/router/route.js b/node_modules/express/lib/router/route.js
new file mode 100644
index 0000000..178df0d
--- /dev/null
+++ b/node_modules/express/lib/router/route.js
@@ -0,0 +1,216 @@
+/*!
+ * express
+ * Copyright(c) 2009-2013 TJ Holowaychuk
+ * Copyright(c) 2013 Roman Shtylman
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict';
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var debug = require('debug')('express:router:route');
+var flatten = require('array-flatten');
+var Layer = require('./layer');
+var methods = require('methods');
+
+/**
+ * Module variables.
+ * @private
+ */
+
+var slice = Array.prototype.slice;
+var toString = Object.prototype.toString;
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = Route;
+
+/**
+ * Initialize `Route` with the given `path`,
+ *
+ * @param {String} path
+ * @public
+ */
+
+function Route(path) {
+ this.path = path;
+ this.stack = [];
+
+ debug('new %o', path)
+
+ // route handlers for various http methods
+ this.methods = {};
+}
+
+/**
+ * Determine if the route handles a given method.
+ * @private
+ */
+
+Route.prototype._handles_method = function _handles_method(method) {
+ if (this.methods._all) {
+ return true;
+ }
+
+ var name = method.toLowerCase();
+
+ if (name === 'head' && !this.methods['head']) {
+ name = 'get';
+ }
+
+ return Boolean(this.methods[name]);
+};
+
+/**
+ * @return {Array} supported HTTP methods
+ * @private
+ */
+
+Route.prototype._options = function _options() {
+ var methods = Object.keys(this.methods);
+
+ // append automatic head
+ if (this.methods.get && !this.methods.head) {
+ methods.push('head');
+ }
+
+ for (var i = 0; i < methods.length; i++) {
+ // make upper case
+ methods[i] = methods[i].toUpperCase();
+ }
+
+ return methods;
+};
+
+/**
+ * dispatch req, res into this route
+ * @private
+ */
+
+Route.prototype.dispatch = function dispatch(req, res, done) {
+ var idx = 0;
+ var stack = this.stack;
+ if (stack.length === 0) {
+ return done();
+ }
+
+ var method = req.method.toLowerCase();
+ if (method === 'head' && !this.methods['head']) {
+ method = 'get';
+ }
+
+ req.route = this;
+
+ next();
+
+ function next(err) {
+ // signal to exit route
+ if (err && err === 'route') {
+ return done();
+ }
+
+ // signal to exit router
+ if (err && err === 'router') {
+ return done(err)
+ }
+
+ var layer = stack[idx++];
+ if (!layer) {
+ return done(err);
+ }
+
+ if (layer.method && layer.method !== method) {
+ return next(err);
+ }
+
+ if (err) {
+ layer.handle_error(err, req, res, next);
+ } else {
+ layer.handle_request(req, res, next);
+ }
+ }
+};
+
+/**
+ * Add a handler for all HTTP verbs to this route.
+ *
+ * Behaves just like middleware and can respond or call `next`
+ * to continue processing.
+ *
+ * You can use multiple `.all` call to add multiple handlers.
+ *
+ * function check_something(req, res, next){
+ * next();
+ * };
+ *
+ * function validate_user(req, res, next){
+ * next();
+ * };
+ *
+ * route
+ * .all(validate_user)
+ * .all(check_something)
+ * .get(function(req, res, next){
+ * res.send('hello world');
+ * });
+ *
+ * @param {function} handler
+ * @return {Route} for chaining
+ * @api public
+ */
+
+Route.prototype.all = function all() {
+ var handles = flatten(slice.call(arguments));
+
+ for (var i = 0; i < handles.length; i++) {
+ var handle = handles[i];
+
+ if (typeof handle !== 'function') {
+ var type = toString.call(handle);
+ var msg = 'Route.all() requires a callback function but got a ' + type
+ throw new TypeError(msg);
+ }
+
+ var layer = Layer('/', {}, handle);
+ layer.method = undefined;
+
+ this.methods._all = true;
+ this.stack.push(layer);
+ }
+
+ return this;
+};
+
+methods.forEach(function(method){
+ Route.prototype[method] = function(){
+ var handles = flatten(slice.call(arguments));
+
+ for (var i = 0; i < handles.length; i++) {
+ var handle = handles[i];
+
+ if (typeof handle !== 'function') {
+ var type = toString.call(handle);
+ var msg = 'Route.' + method + '() requires a callback function but got a ' + type
+ throw new Error(msg);
+ }
+
+ debug('%s %o', method, this.path)
+
+ var layer = Layer('/', {}, handle);
+ layer.method = method;
+
+ this.methods[method] = true;
+ this.stack.push(layer);
+ }
+
+ return this;
+ };
+});