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  }