diff --git a/README.md b/README.md index f7af838..b2b1921 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,9 @@ router.on('GET', '/example', (req, res, params, store) => { ##### Versioned routes -If needed you can provide a `version` option, which will allow you to declare multiple versions of the same route. +If needed you can provide a `version` option, which will allow you to declare multiple versions of the same route. If you never configure a versioned route, the `'Accept-Version'` header will be ignored. + +Remember to set a [Vary](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary) header in your responses with the value you are using for deifning the versioning (e.g.: 'Accept-Version'), to prevent cache poisoning attacks. You can also configure this as part your Proxy/CDN. ###### default diff --git a/index.js b/index.js index f82ea6d..dff3f72 100644 --- a/index.js +++ b/index.js @@ -50,7 +50,7 @@ function Router (opts) { this.ignoreTrailingSlash = opts.ignoreTrailingSlash || false this.maxParamLength = opts.maxParamLength || 100 this.allowUnsafeRegex = opts.allowUnsafeRegex || false - this.versioning = opts.versioning || acceptVersionStrategy + this.versioning = opts.versioning || acceptVersionStrategy(false) this.tree = new Node({ versions: this.versioning.storage() }) this.routes = [] } @@ -105,6 +105,9 @@ Router.prototype._on = function _on (method, path, opts, handler, store) { }) const version = opts.version + if (version != null && this.versioning.disabled) { + this.versioning = acceptVersionStrategy(true) + } for (var i = 0, len = path.length; i < len; i++) { // search for parametric or wildcard routes diff --git a/lib/accept-version.js b/lib/accept-version.js index 3d698c6..a5a7708 100644 --- a/lib/accept-version.js +++ b/lib/accept-version.js @@ -2,9 +2,20 @@ const SemVerStore = require('semver-store') -module.exports = { - storage: SemVerStore, - deriveVersion: function (req, ctx) { - return req.headers['accept-version'] +function build (enabled) { + if (enabled) { + return { + storage: SemVerStore, + deriveVersion: function (req, ctx) { + return req.headers['accept-version'] + } + } + } + return { + storage: SemVerStore, + deriveVersion: function (req, ctx) {}, + disabled: true } } + +module.exports = build diff --git a/test/version.default-versioning.test.js b/test/version.default-versioning.test.js index 497f641..b6d42dd 100644 --- a/test/version.default-versioning.test.js +++ b/test/version.default-versioning.test.js @@ -240,3 +240,28 @@ test('It should throw if you declare multiple times the same route', t => { t.is(err.message, 'Method \'GET\' already declared for route \'/\' version \'1.2.3\'') } }) + +test('Versioning won\'t work if there are no versioned routes', t => { + t.plan(2) + + const findMyWay = FindMyWay({ + defaultRoute: (req, res) => { + t.fail('We should not be here') + } + }) + + findMyWay.on('GET', '/', (req, res) => { + t.pass('Yeah!') + }) + + findMyWay.lookup({ + method: 'GET', + url: '/', + headers: { 'accept-version': '2.x' } + }, null) + + findMyWay.lookup({ + method: 'GET', + url: '/' + }, null) +})