github.com/cloudcredo/cloudrocker@v0.0.0-20160108110610-1320f8cc2dfd/sample-apps/node/node_modules/express/lib/router/layer.js (about) 1 /** 2 * Module dependencies. 3 */ 4 5 var pathRegexp = require('path-to-regexp'); 6 var debug = require('debug')('express:router:layer'); 7 8 /** 9 * Expose `Layer`. 10 */ 11 12 module.exports = Layer; 13 14 function Layer(path, options, fn) { 15 if (!(this instanceof Layer)) { 16 return new Layer(path, options, fn); 17 } 18 19 debug('new %s', path); 20 options = options || {}; 21 22 this.handle = fn; 23 this.name = fn.name || '<anonymous>'; 24 this.params = undefined; 25 this.path = undefined; 26 this.regexp = pathRegexp(path, this.keys = [], options); 27 28 if (path === '/' && options.end === false) { 29 this.regexp.fast_slash = true; 30 } 31 } 32 33 /** 34 * Handle the error for the layer. 35 * 36 * @param {Error} error 37 * @param {Request} req 38 * @param {Response} res 39 * @param {function} next 40 * @api private 41 */ 42 43 Layer.prototype.handle_error = function handle_error(error, req, res, next) { 44 var fn = this.handle; 45 46 if (fn.length !== 4) { 47 // not a standard error handler 48 return next(error); 49 } 50 51 try { 52 fn(error, req, res, next); 53 } catch (err) { 54 next(err); 55 } 56 }; 57 58 /** 59 * Handle the request for the layer. 60 * 61 * @param {Request} req 62 * @param {Response} res 63 * @param {function} next 64 * @api private 65 */ 66 67 Layer.prototype.handle_request = function handle(req, res, next) { 68 var fn = this.handle; 69 70 if (fn.length > 3) { 71 // not a standard request handler 72 return next(); 73 } 74 75 try { 76 fn(req, res, next); 77 } catch (err) { 78 next(err); 79 } 80 }; 81 82 /** 83 * Check if this route matches `path`, if so 84 * populate `.params`. 85 * 86 * @param {String} path 87 * @return {Boolean} 88 * @api private 89 */ 90 91 Layer.prototype.match = function match(path) { 92 if (this.regexp.fast_slash) { 93 // fast path non-ending match for / (everything matches) 94 this.params = {}; 95 this.path = ''; 96 return true; 97 } 98 99 var m = this.regexp.exec(path); 100 101 if (!m) { 102 this.params = undefined; 103 this.path = undefined; 104 return false; 105 } 106 107 // store values 108 this.params = {}; 109 this.path = m[0]; 110 111 var keys = this.keys; 112 var params = this.params; 113 var n = 0; 114 var key; 115 var val; 116 117 for (var i = 1, len = m.length; i < len; ++i) { 118 key = keys[i - 1]; 119 val = decode_param(m[i]); 120 121 if (key) { 122 params[key.name] = val; 123 } else { 124 params[n++] = val; 125 } 126 } 127 128 return true; 129 }; 130 131 /** 132 * Decode param value. 133 * 134 * @param {string} val 135 * @return {string} 136 * @api private 137 */ 138 139 function decode_param(val){ 140 if (typeof val !== 'string') { 141 return val; 142 } 143 144 try { 145 return decodeURIComponent(val); 146 } catch (e) { 147 var err = new TypeError("Failed to decode param '" + val + "'"); 148 err.status = 400; 149 throw err; 150 } 151 }