Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,11 @@ proto.handle = function handle(req, res, out) {
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);
}
Expand Down Expand Up @@ -323,7 +328,7 @@ proto.process_params = function process_params(layer, called, req, res, done) {
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) {
Expand Down
36 changes: 27 additions & 9 deletions lib/router/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,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 || '<anonymous>';
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;
});
}

/**
Expand Down Expand Up @@ -115,14 +124,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;
Expand All @@ -138,7 +156,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]);

Expand Down
21 changes: 21 additions & 0 deletions test/Router.js
Original file line number Diff line number Diff line change
Expand Up @@ -502,4 +502,25 @@ describe('Router', function(){
});
});
});

describe('matchedRoutes', function() {
it('should store matchedRoutes in request', function(done) {
var req = { url: '/foo/10/bar/baz/30', method: 'get' };
var fooRouter = new Router();
var barRouter = new Router();
var bazRouter = new Router();

bazRouter.get(['/bez', '/baz/:subId'], function(req, res, next) {
next();
});

fooRouter.use(['/foo/:id', '/foe'], barRouter);
barRouter.use(['/bar'], bazRouter);

fooRouter.handle(req, {}, function(err) {
assert.deepEqual(req.matchedRoutes, ['/foo/:id', '/bar', '/baz/:subId']);
done();
});
});
});
})