3 * Copyright(c) 2009-2013 TJ Holowaychuk
4 * Copyright(c) 2013 Roman Shtylman
5 * Copyright(c) 2014-2015 Douglas Christopher Wilson
12 * Module dependencies.
16 var pathRegexp = require('path-to-regexp');
17 var debug = require('debug')('express:router:layer');
24 var hasOwnProperty = Object.prototype.hasOwnProperty;
31 module.exports = Layer;
33 function Layer(path, options, fn) {
34 if (!(this instanceof Layer)) {
35 return new Layer(path, options, fn);
39 var opts = options || {};
42 this.name = fn.name || '<anonymous>';
43 this.params = undefined;
44 this.path = undefined;
45 this.regexp = pathRegexp(path, this.keys = [], opts);
47 // set fast path flags
48 this.regexp.fast_star = path === '*'
49 this.regexp.fast_slash = path === '/' && opts.end === false
53 * Handle the error for the layer.
55 * @param {Error} error
56 * @param {Request} req
57 * @param {Response} res
58 * @param {function} next
62 Layer.prototype.handle_error = function handle_error(error, req, res, next) {
65 if (fn.length !== 4) {
66 // not a standard error handler
71 fn(error, req, res, next);
78 * Handle the request for the layer.
80 * @param {Request} req
81 * @param {Response} res
82 * @param {function} next
86 Layer.prototype.handle_request = function handle(req, res, next) {
90 // not a standard request handler
102 * Check if this route matches `path`, if so
103 * populate `.params`.
105 * @param {String} path
110 Layer.prototype.match = function match(path) {
114 // fast path non-ending match for / (any path matches)
115 if (this.regexp.fast_slash) {
121 // fast path for * (everything matched in a param)
122 if (this.regexp.fast_star) {
123 this.params = {'0': decode_param(path)}
129 match = this.regexp.exec(path)
133 this.params = undefined;
134 this.path = undefined;
142 var keys = this.keys;
143 var params = this.params;
145 for (var i = 1; i < match.length; i++) {
146 var key = keys[i - 1];
148 var val = decode_param(match[i])
150 if (val !== undefined || !(hasOwnProperty.call(params, prop))) {
159 * Decode param value.
161 * @param {string} val
166 function decode_param(val) {
167 if (typeof val !== 'string' || val.length === 0) {
172 return decodeURIComponent(val);
174 if (err instanceof URIError) {
175 err.message = 'Failed to decode param \'' + val + '\'';
176 err.status = err.statusCode = 400;