+5
-0
@@ -0,1 +1,6 @@ | ||
| 1.0.0-beta.2 / 2014-11-19 | ||
| ========================= | ||
| * Match routes iteratively to prevent stack overflows | ||
| 1.0.0-beta.1 / 2014-11-16 | ||
@@ -2,0 +7,0 @@ ========================= |
+101
-68
@@ -214,4 +214,3 @@ /*! | ||
| var layer = stack[idx++] | ||
| // remove added slash | ||
| if (slashAdded) { | ||
@@ -222,2 +221,3 @@ req.url = req.url.substr(1) | ||
| // restore altered req.url | ||
| if (removed.length !== 0) { | ||
@@ -229,61 +229,86 @@ req.baseUrl = parentUrl | ||
| if (!layer) { | ||
| // no more matching layers | ||
| if (idx >= stack.length) { | ||
| defer(done, layerError) | ||
| return | ||
| } | ||
| // get pathname of request | ||
| var path = getPathname(req) | ||
| self.match_layer(layer, req, res, function (err, path) { | ||
| if (err || path === undefined) { | ||
| next(layerError || err) | ||
| return | ||
| if (path == null) { | ||
| return done(layerError) | ||
| } | ||
| // find next matching layer | ||
| var layer | ||
| var match | ||
| var route | ||
| while (match !== true && idx < stack.length) { | ||
| layer = stack[idx++] | ||
| match = matchLayer(layer, path) | ||
| route = layer.route | ||
| if (typeof match !== 'boolean') { | ||
| // hold on to layerError | ||
| layerError = layerError || match | ||
| } | ||
| // route object and not middleware | ||
| var route = layer.route | ||
| if (match !== true) { | ||
| continue | ||
| } | ||
| // if final route, then we support options | ||
| if (route) { | ||
| // we don't run any routes with error first | ||
| if (layerError) { | ||
| next(layerError) | ||
| return | ||
| } | ||
| if (!route) { | ||
| // process non-route handlers normally | ||
| continue | ||
| } | ||
| var method = req.method | ||
| var has_method = route._handles_method(method) | ||
| if (layerError) { | ||
| // routes do not match with a pending error | ||
| match = false | ||
| continue | ||
| } | ||
| // build up automatic options response | ||
| if (!has_method && method === 'OPTIONS') { | ||
| options.push.apply(options, route._options()) | ||
| } | ||
| var method = req.method; | ||
| var has_method = route._handles_method(method) | ||
| // don't even bother | ||
| if (!has_method && method !== 'HEAD') { | ||
| next() | ||
| return | ||
| } | ||
| // build up automatic options response | ||
| if (!has_method && method === 'OPTIONS') { | ||
| options.push.apply(options, route._options()) | ||
| } | ||
| // we can now dispatch to the route | ||
| req.route = route | ||
| // don't even bother matching route | ||
| if (!has_method && method !== 'HEAD') { | ||
| match = false | ||
| continue | ||
| } | ||
| } | ||
| // Capture one-time layer values | ||
| req.params = self.mergeParams | ||
| ? mergeParams(layer.params, parentParams) | ||
| : layer.params | ||
| var layerPath = layer.path | ||
| // no match | ||
| if (match !== true) { | ||
| return done(layerError) | ||
| } | ||
| // this should be done for the layer | ||
| self.process_params(layer, paramcalled, req, res, function (err) { | ||
| if (err) { | ||
| next(layerError || err) | ||
| return | ||
| } | ||
| // store route for dispatch on change | ||
| if (route) { | ||
| req.route = route | ||
| } | ||
| if (route) { | ||
| return layer.handle_request(req, res, next) | ||
| } | ||
| // Capture one-time layer values | ||
| req.params = self.mergeParams | ||
| ? mergeParams(layer.params, parentParams) | ||
| : layer.params | ||
| var layerPath = layer.path | ||
| trim_prefix(layer, layerError, layerPath, path) | ||
| }) | ||
| // this should be done for the layer | ||
| self.process_params(layer, paramcalled, req, res, function (err) { | ||
| if (err) { | ||
| return next(layerError || err) | ||
| } | ||
| if (route) { | ||
| return layer.handle_request(req, res, next) | ||
| } | ||
| trim_prefix(layer, layerError, layerPath, path) | ||
| }) | ||
@@ -330,25 +355,2 @@ } | ||
| /** | ||
| * Match request to a layer. | ||
| * | ||
| * @private | ||
| */ | ||
| Router.prototype.match_layer = function match_layer(layer, req, res, done) { | ||
| var error = null | ||
| var path | ||
| try { | ||
| path = parseUrl(req).pathname | ||
| if (!layer.match(path)) { | ||
| path = undefined | ||
| } | ||
| } catch (err) { | ||
| error = err | ||
| } | ||
| done(error, path) | ||
| } | ||
| /** | ||
| * Process any parameters for the layer. | ||
@@ -554,2 +556,33 @@ * | ||
| /** | ||
| * Get pathname of request. | ||
| * | ||
| * @param {IncomingMessage} req | ||
| * @private | ||
| */ | ||
| function getPathname(req) { | ||
| try { | ||
| return parseUrl(req).pathname; | ||
| } catch (err) { | ||
| return undefined; | ||
| } | ||
| } | ||
| /** | ||
| * Match path to a layer. | ||
| * | ||
| * @param {Layer} layer | ||
| * @param {string} path | ||
| * @private | ||
| */ | ||
| function matchLayer(layer, path) { | ||
| try { | ||
| return layer.match(path); | ||
| } catch (err) { | ||
| return err; | ||
| } | ||
| } | ||
| /** | ||
| * Merge params with parent params | ||
@@ -556,0 +589,0 @@ * |
+14
-4
@@ -96,11 +96,21 @@ /*! | ||
| var layer = stack[idx++] | ||
| if (!layer) { | ||
| // no more matching layers | ||
| if (idx >= stack.length) { | ||
| return done(err) | ||
| } | ||
| if (layer.method && layer.method !== method) { | ||
| return next(err) | ||
| var layer | ||
| var match | ||
| // find next matching layer | ||
| while (match !== true && idx < stack.length) { | ||
| layer = stack[idx++] | ||
| match = !layer.method || layer.method === method | ||
| } | ||
| // no match | ||
| if (match !== true) { | ||
| return done(err) | ||
| } | ||
| if (err) { | ||
@@ -107,0 +117,0 @@ layer.handle_error(err, req, res, next) |
+1
-1
| { | ||
| "name": "router", | ||
| "description": "Simple middleware-style router", | ||
| "version": "1.0.0-beta.1", | ||
| "version": "1.0.0-beta.2", | ||
| "author": "Douglas Christopher Wilson <doug@somethingdoug.com>", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
+27
-0
@@ -30,2 +30,29 @@ # router | ||
| ## Example | ||
| Simple example of using the router independently of any framework. | ||
| ```js | ||
| var finalhandler = require('finalhandler') | ||
| var http = require('http') | ||
| var Router = require('router') | ||
| var router = new Router() | ||
| router.get('/', function (req, res) { | ||
| res.setHeader('Content-Type', 'text/plain; charset=utf-8') | ||
| res.end('hello, world!') | ||
| }) | ||
| var server = http.createServer(app) | ||
| server.listen(3000, function onListening() { | ||
| console.log('http server listening on port ' + this.address().port) | ||
| }) | ||
| function app(req, res) { | ||
| router(req, res, finalhandler(req, res)) | ||
| } | ||
| ``` | ||
| ## Testing | ||
@@ -32,0 +59,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
25671
5.82%860
4.62%77
54%1
-50%0
-100%