Comparing version 1.0.0-beta.1 to 1.0.0-beta.2
@@ -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 @@ ========================= |
169
index.js
@@ -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 @@ * |
@@ -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) |
{ | ||
"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", |
@@ -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 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
25671
860
77
0