Spaces:
Runtime error
Runtime error
| /*! | |
| * express | |
| * Copyright(c) 2009-2013 TJ Holowaychuk | |
| * Copyright(c) 2013 Roman Shtylman | |
| * Copyright(c) 2014-2015 Douglas Christopher Wilson | |
| * MIT Licensed | |
| */ | |
| ; | |
| /** | |
| * 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; | |
| } | |
| // normalize name | |
| var name = typeof method === 'string' | |
| ? method.toLowerCase() | |
| : method | |
| 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; | |
| var sync = 0 | |
| if (stack.length === 0) { | |
| return done(); | |
| } | |
| var method = typeof req.method === 'string' | |
| ? req.method.toLowerCase() | |
| : req.method | |
| 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) | |
| } | |
| // max sync stack | |
| if (++sync > 100) { | |
| return setImmediate(next, err) | |
| } | |
| var layer = stack[idx++] | |
| // end of layers | |
| if (!layer) { | |
| return done(err) | |
| } | |
| if (layer.method && layer.method !== method) { | |
| next(err) | |
| } else if (err) { | |
| layer.handle_error(err, req, res, next); | |
| } else { | |
| layer.handle_request(req, res, next); | |
| } | |
| sync = 0 | |
| } | |
| }; | |
| /** | |
| * 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; | |
| }; | |
| }); | |