From 3c54220a3495a7a2cdf580c3289ee37e835c0190 Mon Sep 17 00:00:00 2001 From: Hamza Date: Sun, 31 Jul 2016 13:14:05 +0100 Subject: [PATCH 1/3] Use node's `path.join` in examples (#3046) closes #3046 --- examples/static-files/index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/static-files/index.js b/examples/static-files/index.js index c3b1659d861..04ad8693546 100644 --- a/examples/static-files/index.js +++ b/examples/static-files/index.js @@ -3,6 +3,7 @@ */ var express = require('../..'); +var path = require('path'); var logger = require('morgan'); var app = express(); @@ -16,7 +17,7 @@ app.use(logger('dev')); // that you pass it. In this case "GET /js/app.js" // will look for "./public/js/app.js". -app.use(express.static(__dirname + '/public')); +app.use(express.static(path.join(__dirname, 'public'))); // if you wanted to "prefix" you may use // the mounting feature of Connect, for example @@ -24,17 +25,17 @@ app.use(express.static(__dirname + '/public')); // The mount-path "/static" is simply removed before // passing control to the express.static() middleware, // thus it serves the file correctly by ignoring "/static" -app.use('/static', express.static(__dirname + '/public')); +app.use('/static', express.static(path.join(__dirname, 'public'))); // if for some reason you want to serve files from // several directories, you can use express.static() // multiple times! Here we're passing "./public/css", // this will allow "GET /style.css" instead of "GET /css/style.css": -app.use(express.static(__dirname + '/public/css')); +app.use(express.static(path.join(__dirname, 'public', 'css'))); app.listen(3000); console.log('listening on port 3000'); console.log('try:'); console.log(' GET /hello.txt'); console.log(' GET /js/app.js'); -console.log(' GET /css/style.css'); +console.log(' GET /css/style.css'); \ No newline at end of file From b341919aed96fda024e5bf889559ad4eebc9008b Mon Sep 17 00:00:00 2001 From: Evan Shortiss Date: Wed, 12 Oct 2016 14:15:22 -0500 Subject: [PATCH 2/3] expose the matched route for a request --- lib/router/index.js | 13 +++++++++++++ lib/router/layer.js | 1 + test/Router.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/lib/router/index.js b/lib/router/index.js index dac2514815b..426fb4d268e 100644 --- a/lib/router/index.js +++ b/lib/router/index.js @@ -267,6 +267,9 @@ proto.handle = function handle(req, res, out) { : layer.params; var layerPath = layer.path; + // Expose the definition of the route that was hit + req.matchedRoute = generateMatchedRoute(req.matchedRoute, layer.pathDefinition); + // this should be done for the layer self.process_params(layer, paramcalled, req, res, function (err) { if (err) { @@ -281,6 +284,16 @@ proto.handle = function handle(req, res, out) { }); } + function generateMatchedRoute (prevMatch, curMatch) { + if (!prevMatch) { + return curMatch; + } else if (prevMatch === '/') { + return curMatch; + } else { + return prevMatch + curMatch; + } + } + function trim_prefix(layer, layerError, layerPath, path) { var c = path[layerPath.length]; if (c && '/' !== c && '.' !== c) return next(layerError); diff --git a/lib/router/layer.js b/lib/router/layer.js index fe9210cb9de..6d4dfc2dae9 100644 --- a/lib/router/layer.js +++ b/lib/router/layer.js @@ -42,6 +42,7 @@ function Layer(path, options, fn) { this.name = fn.name || ''; this.params = undefined; this.path = undefined; + this.pathDefinition = path; this.regexp = pathRegexp(path, this.keys = [], opts); if (path === '/' && opts.end === false) { diff --git a/test/Router.js b/test/Router.js index 21cdff2c6c0..08e08e31c27 100644 --- a/test/Router.js +++ b/test/Router.js @@ -68,6 +68,35 @@ describe('Router', function(){ router.handle({ url: '/', method: 'GET' }, { end: done }); }); + it('should expose the matched route on the req object', function (done) { + var router = new Router(); + var path = '/foo/:num'; + + router.use(path, function (req, res) { + assert(req.matchedRoute); + assert.equal(req.matchedRoute, path); + res.end(); + }); + + router.handle({ url: '/foo/123', method: 'GET' }, {end: done}); + }); + + it('should expose the nested matched route on the req object', function (done) { + var layer1 = new Router(); + var layer2 = new Router(); + var layer3 = new Router(); + + layer1.use(layer2); + layer2.use('/foo/:num', layer3); + layer3.get('/bar/:num', function (req, res) { + assert.equal(req.matchedRoute, '/foo/:num/bar/:num'); + res.end(); + }); + + // Simulate request entering "app" or "base" later + layer1.handle({ url: '/foo/123/bar/321', method: 'GET' }, {end: done}); + }); + describe('.handle', function(){ it('should dispatch', function(done){ var router = new Router(); From 303e5e7fb3f851ca05ef47b3fc89b01ccb7977e4 Mon Sep 17 00:00:00 2001 From: Evan Shortiss Date: Wed, 12 Oct 2016 15:36:54 -0500 Subject: [PATCH 3/3] use array data structure for matched routes --- lib/router/index.js | 13 ++----------- test/Router.js | 14 +++++++------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/lib/router/index.js b/lib/router/index.js index 426fb4d268e..b35f86adc3b 100644 --- a/lib/router/index.js +++ b/lib/router/index.js @@ -268,7 +268,8 @@ proto.handle = function handle(req, res, out) { var layerPath = layer.path; // Expose the definition of the route that was hit - req.matchedRoute = generateMatchedRoute(req.matchedRoute, layer.pathDefinition); + req.matchedRoutes = req.matchedRoutes ? + req.matchedRoutes.concat([layer.pathDefinition]) : [layer.pathDefinition]; // this should be done for the layer self.process_params(layer, paramcalled, req, res, function (err) { @@ -284,16 +285,6 @@ proto.handle = function handle(req, res, out) { }); } - function generateMatchedRoute (prevMatch, curMatch) { - if (!prevMatch) { - return curMatch; - } else if (prevMatch === '/') { - return curMatch; - } else { - return prevMatch + curMatch; - } - } - function trim_prefix(layer, layerError, layerPath, path) { var c = path[layerPath.length]; if (c && '/' !== c && '.' !== c) return next(layerError); diff --git a/test/Router.js b/test/Router.js index 08e08e31c27..3d60d3c6a14 100644 --- a/test/Router.js +++ b/test/Router.js @@ -68,33 +68,33 @@ describe('Router', function(){ router.handle({ url: '/', method: 'GET' }, { end: done }); }); - it('should expose the matched route on the req object', function (done) { + it('should expose the matched routes on the req object', function (done) { var router = new Router(); var path = '/foo/:num'; router.use(path, function (req, res) { - assert(req.matchedRoute); - assert.equal(req.matchedRoute, path); + assert(req.matchedRoutes); + assert.deepEqual(req.matchedRoutes, [path]); res.end(); }); router.handle({ url: '/foo/123', method: 'GET' }, {end: done}); }); - it('should expose the nested matched route on the req object', function (done) { + it('should expose the nested matched routes on the req object', function (done) { var layer1 = new Router(); var layer2 = new Router(); var layer3 = new Router(); layer1.use(layer2); layer2.use('/foo/:num', layer3); - layer3.get('/bar/:num', function (req, res) { - assert.equal(req.matchedRoute, '/foo/:num/bar/:num'); + layer3.get(/[0-9]/, function (req, res) { + assert.deepEqual(req.matchedRoutes, ['/', '/foo/:num', /[0-9]/]); res.end(); }); // Simulate request entering "app" or "base" later - layer1.handle({ url: '/foo/123/bar/321', method: 'GET' }, {end: done}); + layer1.handle({ url: '/foo/123/321', method: 'GET' }, {end: done}); }); describe('.handle', function(){