| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 | /*! * 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;  var sync = 0  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)    }    // 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;  };});
 |