From 0c77b8808ef475370b407cfa6378eaeadc2d613f Mon Sep 17 00:00:00 2001 From: Augusto Franzoia Date: Sat, 13 Feb 2016 17:10:07 -0300 Subject: [PATCH] Store matched routes in request --- index.js | 7 ++++++- lib/layer.js | 36 +++++++++++++++++++++++++++--------- test/router.js | 25 +++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index b488e58..d5b671e 100644 --- a/index.js +++ b/index.js @@ -286,6 +286,11 @@ Router.prototype.handle = function handle(req, res, callback) { return next(layerError || err) } + // store matched routes + if (layer.path) { + req.matchedRoutes = (req.matchedRoutes || []).concat(layer.matchedPath.path) + } + if (route) { return layer.handle_request(req, res, next) } @@ -341,7 +346,7 @@ Router.prototype.process_params = function process_params(layer, called, req, re var params = this.params // captured parameters from the layer, keys and values - var keys = layer.keys + var keys = layer.matchedPath ? layer.matchedPath.keys : [] // fast track if (!keys || keys.length === 0) { diff --git a/lib/layer.js b/lib/layer.js index 99b25d2..ac1c684 100644 --- a/lib/layer.js +++ b/lib/layer.js @@ -28,23 +28,32 @@ var hasOwnProperty = Object.prototype.hasOwnProperty module.exports = Layer -function Layer(path, options, fn) { +function Layer(paths, options, fn) { if (!(this instanceof Layer)) { - return new Layer(path, options, fn) + return new Layer(paths, options, fn) } - debug('new %s', path) + debug('new %s', paths) var opts = options || {} this.handle = fn this.name = fn.name || '' this.params = undefined this.path = undefined - this.regexp = pathRegexp(path, this.keys = [], opts) - if (path === '/' && opts.end === false) { - this.regexp.fast_slash = true + if (paths === '/' && opts.end === false) { + this.fastSlash = true } + + this.paths = !Array.isArray(paths) ? [paths] : paths + this.paths = this.paths.map(function (path) { + var pathObj = { + path: path, + keys: [] + } + pathObj.regexp = pathRegexp(path, pathObj.keys, opts) + return pathObj + }) } /** @@ -113,14 +122,23 @@ Layer.prototype.match = function match(path) { return false } - if (this.regexp.fast_slash) { + if (this.fastSlash) { // fast path non-ending match for / (everything matches) this.params = {} this.path = '' + this.matchedPath = this.paths[0] return true } - var m = this.regexp.exec(path) + var checkPath, m; + + for (var i = 0; i < this.paths.length; i++) { + checkPath = this.paths[i] + if (m = checkPath.regexp.exec(path)) { + this.matchedPath = checkPath + break + } + } if (!m) { this.params = undefined @@ -137,7 +155,7 @@ Layer.prototype.match = function match(path) { var params = this.params for (var i = 1; i < m.length; i++) { - var key = keys[i - 1] + var key = this.matchedPath.keys[i - 1] var prop = key.name var val = decode_param(m[i]) diff --git a/test/router.js b/test/router.js index 046bd32..e079dd0 100644 --- a/test/router.js +++ b/test/router.js @@ -985,6 +985,31 @@ describe('Router', function () { }) }) +describe('req.matchedRoutes', function() { + it('should store matchedRoutes in request', function(done) { + var router = new Router() + var barRouter = new Router() + var bazRouter = new Router() + var server = createServer(router) + var matchedRoutes + + router.use(['/foo/:id', '/foe'], barRouter) + barRouter.use(['/bar'], bazRouter) + bazRouter.get(['/bez', '/baz/:subId'], function(req, res, next) { + matchedRoutes = req.matchedRoutes + next() + }) + router.use(saw) + + request(server) + .get('/foo/10/bar/baz/30') + .expect(200, 'saw GET /foo/10/bar/baz/30', function(err, res) { + assert.deepEqual(matchedRoutes, ['/foo/:id', '/bar', '/baz/:subId']) + done(err) + }) + }) +}) + function helloWorld(req, res) { res.statusCode = 200 res.setHeader('Content-Type', 'text/plain')