The LM Control website. Simple yet efficient.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

route.js 4.1KB

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