Skip to content

Commit

Permalink
Allow multiple routes to be matched
Browse files Browse the repository at this point in the history
Only keep looping matching routes if they yield next
  • Loading branch information
ilkkao committed Feb 4, 2014
1 parent ff86959 commit ba2669c
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 2 deletions.
19 changes: 17 additions & 2 deletions lib/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
var debug = require('debug')('koa-router')
, methods = require('methods')
, parse = require('url').parse
, compose = require('koa-compose')
, Route = require('./route');

/**
Expand Down Expand Up @@ -66,6 +67,7 @@ router.middleware = function() {
// Find routes matching requested path
if (matchedRoutes = router.match(this.path, this.params)) {
var methodsAvailable = {};
var matchedMiddlewares = [];

// Find matched route for requested method
for (var len = matchedRoutes.length, i=0; i<len; i++) {
Expand All @@ -78,12 +80,25 @@ router.middleware = function() {

// if method and path match, dispatch route middleware
if (method === this.method) {
debug('dispatch "%s" %s', route.path, route.regexp);
return yield route.middleware.call(this, next);
debug('queue "%s" %s', route.path, route.regexp);
var wrapper = function(ctx, myRoute, params) {
return function *(next) {
ctx.params = params;
yield myRoute.middleware.call(ctx, next);
}
}(this, route, this.params);

matchedMiddlewares.push(wrapper);
}
}
}

if (matchedMiddlewares.length > 0) {
var fn = compose(matchedMiddlewares);
debug('dispatch %d', matchedMiddlewares.length);
return yield fn(next);
}

// matches path but not method, so return 405 Method Not Allowed
// unless this is an OPTIONS request.
this.status = (this.method === 'OPTIONS' ? 204 : 405);
Expand Down
60 changes: 60 additions & 0 deletions test/lib/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,66 @@ describe('Router', function() {
});
});

it('matches multiple routes', function(done) {
var app = koa();
var counter = 0;
app.use(Router(app));
app.get('/:lastname', function *(next) {
this.should.have.property('params');
this.params.should.have.property('lastname', 'smith');
this.status = 204;
counter++;

yield next;
});
app.get('/:surname', function *(next) {
this.should.have.property('params');
this.params.should.have.property('surname', 'smith');
this.status = 204;
counter++;

yield next;
});
var server = http.createServer(app.callback());
request(server)
.get('/smith')
.expect(204)
.end(function(err, res) {
if (err) return done(err);
counter.should.equal(2);
done();
});
});

it('matches only first route if it doesn\'t yield', function(done) {
var app = koa();
var counter = 0;
app.use(Router(app));
app.get('/:lastname', function *(next) {
this.should.have.property('params');
this.params.should.have.property('lastname', 'smith');
this.status = 204;
counter++;
});
app.get('/:surname', function *(next) {
this.should.have.property('params');
this.params.should.have.property('surname', 'smith');
this.status = 204;
counter++;

yield next;
});
var server = http.createServer(app.callback());
request(server)
.get('/smith')
.expect(204)
.end(function(err, res) {
if (err) return done(err);
counter.should.equal(1);
done();
});
});

it('does not match after ctx.throw()', function(done) {
var app = koa();
var counter = 0;
Expand Down

0 comments on commit ba2669c

Please sign in to comment.