diff --git a/ROADMAP.md b/ROADMAP.md index 78adb64a5..997164f3b 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -71,7 +71,7 @@ This section is an early list of some of the features, enhancements, and other i + **Upgrade to Express 5** + Move implementation of `req.param()` from Express core into Sails core - + Improve error handling and simplify Sails' `res.view()` + + Improve error handling and simplify Sails' `res.view()` + ✓ ~~For performance reasons, on-lift view stat-ing will still be used to build handlers for `{view: 'foo'}` route target syntax.~~ + Use standalone Express router in virtual request interpreter, but continue using express core for handling HTTP requests + **Possibly:** Expose context-free view rendering API (replace experimental sails.renderView() and internally, use [`app.render()`](https://expressjs.com/en/4x/api.html#app.render) or better yet, standalone module) @@ -145,7 +145,7 @@ This section is an early list of some of the features, enhancements, and other i + https://github.com/treelinehq/machine-as-script/commits/master + **Normalize usage of `routesDisabled` config keys** - + Set up all route-disabling config keys (such as in sails.config.csrf and sails.config.session) to use the same route syntax (rather than disparate regexps vs. csv, etc) + + Now applies only to sails.config.session: use Sails [route address syntax](http://sailsjs.org/documentation/concepts/routes/custom-routes#?route-address) + ✓ ~~**Strip Out Deprecated Sockets Methods** + Remove the implementation of deprecated `sails.sockets.*` methods from Sails core. diff --git a/lib/hooks/http/get-configured-http-middleware-fns.js b/lib/hooks/http/get-configured-http-middleware-fns.js index 05dfac6aa..ca571b489 100644 --- a/lib/hooks/http/get-configured-http-middleware-fns.js +++ b/lib/hooks/http/get-configured-http-middleware-fns.js @@ -83,15 +83,16 @@ module.exports = function getBuiltInHttpMiddleware (expressRouterMiddleware, sai // Figure out if the request's method matches. var isMethodExactMatch = req.method === disabledRouteInfo.method; - var isMethodImplicitMatch = disabledRouteInfo.method === '' && _.contains(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], req.method); + var isMethodImplicitMatch = disabledRouteInfo.method === 'ALL' || (disabledRouteInfo.method === '' && _.contains(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], req.method)); // If not, then skip this disabled route- it's not a match. - if (!isMethodExactMatch && !isMethodImplicitMatch && disabledRouteInfo.method === '*') { + if (!isMethodExactMatch && !isMethodImplicitMatch) { return; } // Then figure out if the request's url path matches. var isUrlPathMatch = req.path.match(disabledRouteInfo.urlPatternRegExp); return isUrlPathMatch; + });// // If the session is disabled, then skip running the middleware. diff --git a/lib/hooks/session/index.js b/lib/hooks/session/index.js index 44b702848..85bda3b2f 100644 --- a/lib/hooks/session/index.js +++ b/lib/hooks/session/index.js @@ -128,6 +128,8 @@ module.exports = function(app) { // Build `sails.hooks.session.routesDisabled`. // (only salient if `sails.config.session.routesDisabled` was specified) try { + // Regex to check if the route is...a regex. + var regExRoute = /^r\|(.*)\|(.*)$/; app.hooks.session.routesDisabled = _.reduce(sessionConfig.routesDisabled || [], function (memo, routeAddressStr){ @@ -152,7 +154,19 @@ module.exports = function(app) { } // Generate a regular expression from the URL pattern string. - var urlPatternRegExp = pathToRegexp(urlPattern, []); + var urlPatternRegExp; + + + // Perform the check + var matches = urlPattern.match(regExRoute); + + // If it *is* a regex, create a RegExp object that Express can bind, + // pull out the params, and wrap the handler in regexRouteWrapper + if (matches) { + urlPatternRegExp = new RegExp(matches[1]); + } else { + urlPatternRegExp = pathToRegexp(urlPattern, []); + } memo.push({ method: method, diff --git a/test/integration/middleware.session.test.js b/test/integration/middleware.session.test.js index 8654c3c30..6e7f960e9 100644 --- a/test/integration/middleware.session.test.js +++ b/test/integration/middleware.session.test.js @@ -133,30 +133,34 @@ describe('middleware :: ', function() { log: {level: 'silent'}, session: { secret: 'abc123', - routesDisabled: ['/test', '/foo/:id/bar/'] + routesDisabled: ['/test', '/foo/:id/bar/', 'POST /bar', 'ALL /baz', 'GET r|^[^?]*/[^?/]+\\.[^?/]+(\\?.*)?$|'] }, hooks: {grunt: false}, routes: { '/test': function(req, res) { - if (_.isUndefined(req.session)) { - return res.send(200); - } - res.send(500); + return res.status(200).send(); + }, + '/bar': function(req, res) { + return res.status(200).send(); + }, + '/baz': function(req, res) { + return res.status(200).send(); }, '/foo/123/bar': function(req, res) { - if (_.isUndefined(req.session)) { - return res.send(200); - } - res.send(500); + return res.status(200).send(); + }, + '/sails.io.js': function(req, res) { + return res.status(200).send(); } + } }, done); }); - describe('static path', function() { + describe('static path (blank verb)', function() { - it('there should be no `set-cookie` header in the response', function(done) { + it('there should be no `set-cookie` header in the response when requesting via GET', function(done) { request( { @@ -171,6 +175,89 @@ describe('middleware :: ', function() { ); }); + it('there should be no `set-cookie` header in the response when requesting via HEAD', function(done) { + + request( + { + method: 'HEAD', + uri: 'http://localhost:1535/test', + }, + function(err, response, body) { + assert.equal(response.statusCode, 200); + assert(response.headers['set-cookie']); + return done(); + } + ); + }); + + }); + + + describe('static path (ALL verb)', function() { + + it('there should be no `set-cookie` header in the response when requesting via GET', function(done) { + + request( + { + method: 'GET', + uri: 'http://localhost:1535/baz', + }, + function(err, response, body) { + assert.equal(response.statusCode, 200); + assert(_.isUndefined(response.headers['set-cookie'])); + return done(); + } + ); + }); + + it('there should be no `set-cookie` header in the response when requesting via HEAD', function(done) { + + request( + { + method: 'HEAD', + uri: 'http://localhost:1535/baz', + }, + function(err, response, body) { + assert.equal(response.statusCode, 200); + assert(_.isUndefined(response.headers['set-cookie'])); + return done(); + } + ); + }); + }); + + describe('static path (POST only)', function() { + + it('there should be no `set-cookie` header in the response when requesting via POST', function(done) { + + request( + { + method: 'POST', + uri: 'http://localhost:1535/bar', + }, + function(err, response, body) { + assert.equal(response.statusCode, 200); + assert(_.isUndefined(response.headers['set-cookie'])); + return done(); + } + ); + }); + + it('there SHOULD be a `set-cookie` header in the response when requesting via GET', function(done) { + + request( + { + method: 'GET', + uri: 'http://localhost:1535/bar', + }, + function(err, response, body) { + assert.equal(response.statusCode, 200); + assert(response.headers['set-cookie']); + return done(); + } + ); + }); + }); describe('dynamic path', function() { @@ -192,6 +279,25 @@ describe('middleware :: ', function() { }); + describe('regex path', function() { + + it('there should be no `set-cookie` header in the response', function(done) { + + request( + { + method: 'GET', + uri: 'http://localhost:1535/sails.io.js', + }, + function(err, response, body) { + assert.equal(response.statusCode, 200); + assert(_.isUndefined(response.headers['set-cookie'])); + return done(); + } + ); + }); + + }); + after(function(done) { return app.lower(done); }); @@ -287,9 +393,9 @@ describe('middleware :: ', function() { routes: { '/test': function(req, res) { if (_.isUndefined(req.session)) { - return res.send(200); + return res.status(200).send(); } - res.send(500); + return res.status(500).send(); } } }, done);