Comparing version 0.3.2 to 0.4.0
var router = require('router').create(); | ||
router.file('/', './index.js'); | ||
router.get('/s/{prefix}?/{top}', function(req, res) { | ||
res.writeHead(200, {'content-type':'application/javascript'}); | ||
res.end(JSON.stringify(req.params)); | ||
}); | ||
router.get('/s/{prefix}?/{top}/*.*', function(req, res) { | ||
res.writeHead(200, {'content-type':'application/javascript'}); | ||
res.end(JSON.stringify(req.params)); | ||
}); | ||
router.get('/s/{prefix}?/{top}/*', function(req, res) { | ||
res.writeHead(200, {'content-type':'application/javascript'}); | ||
res.end(JSON.stringify(req.params)); | ||
}); | ||
router.all(function(req, res) { | ||
res.writeHead(200); | ||
res.end('olla mundo'); | ||
}); | ||
router.listen(9999); |
92
index.js
@@ -1,13 +0,9 @@ | ||
var common = require('common'); | ||
var http = require('http'); | ||
var https = require('https'); | ||
var common = require('common'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var mimes = require('mimes'); | ||
var matcher = require('./matcher'); | ||
var createRouter = function(options) { // TODO: params instead of matches | ||
var that = {}; | ||
var that = common.createEmitter(); | ||
@@ -28,3 +24,3 @@ options = options || {}; | ||
var methods = {request:[], upgrade:[], get:[], put:[], post:[], head:[], 'delete':[]}; | ||
var methods = {upgrade:[], get:[], put:[], post:[], head:[], 'delete':[], options:[]}; | ||
var server = options.server || (options.key ? https.createServer({key:options.key,cert:options.cert}) : http.createServer()); | ||
@@ -46,4 +42,3 @@ | ||
that.route = function(request, response) { | ||
if (find(methods.request, request, response) || | ||
find(methods[request.method.toLowerCase()], request, response) || !that.autoclose) { | ||
if (find(methods[request.method.toLowerCase()], request, response) || !that.autoclose) { | ||
return; | ||
@@ -60,18 +55,12 @@ } | ||
server.on('request', function(request, response) { | ||
if (request.method === 'OPTIONS') { | ||
response.writeHead(200, { | ||
'access-control-allow-origin': '*', | ||
'access-control-allow-methods': 'PUT, POST, GET, OPTIONS', | ||
'access-control-allow-headers': 'Content-Type' | ||
}); | ||
response.end(); | ||
return; | ||
} | ||
that.emit('request', request, response); | ||
that.route(request, response); | ||
}); | ||
server.on('upgrade', function(request, connection, head) { | ||
if (that.listeners('upgrade').length) { | ||
that.emit('upgrade', request, connection, head); | ||
} | ||
if (find(methods.upgrade, request, connection, head)) { | ||
return; | ||
} | ||
connection.destroy(); | ||
@@ -103,3 +92,3 @@ }); | ||
request.matches = matches; | ||
request.params = matches; | ||
fn(request, a, b); | ||
@@ -114,58 +103,17 @@ | ||
that.request = router(methods.request); | ||
that.upgrade = router(methods.upgrade); | ||
var fns = ['get', 'put', 'del', 'post', 'head', 'options']; | ||
fns.forEach(function(method) { | ||
that[method] = router(methods[method.replace('del', 'delete')]); | ||
}); | ||
that.get = router(methods.get); | ||
that.put = router(methods.put); | ||
that.del = router(methods['delete']); // :( | ||
that.post = router(methods.post); | ||
that.head = router(methods.head); | ||
that.file = function(pattern, rewrite, options) { | ||
if (arguments.length === 1 || typeof rewrite === 'object') { | ||
options = rewrite; | ||
rewrite = pattern; | ||
pattern = /(.*)/g; | ||
} | ||
options = options || {}; | ||
options.status = options.status || 200; | ||
that.all = function() { | ||
var args = arguments; | ||
that.get(pattern, rewrite, function(request, response) { | ||
var url = path.normalize(request.url.split('?')[0]); | ||
var onnotfound = function() { | ||
response.writeHead(404); | ||
response.end(); | ||
}; | ||
if (/\/\.\.\//.test(url)) { // security check | ||
onnotfound(); | ||
return; | ||
} | ||
fs.stat(url, common.fork(onnotfound, function(stat) { | ||
var ifmod = request.headers['if-modified-since']; | ||
if (ifmod && new Date(ifmod) >= stat.mtime) { | ||
response.writeHead(304); | ||
response.end(); | ||
return; | ||
} | ||
var headers = { | ||
'content-type':mimes.resolve(url), | ||
'content-length':stat.size, | ||
'date':new Date().toUTCString(), | ||
'last-modified':stat.mtime.toUTCString() | ||
}; | ||
if (options.cacheMaxAge !== undefined) | ||
headers['Cache-Control'] = 'public, max-age=' + options.cacheMaxAge; | ||
response.writeHead(options.status, headers); | ||
fs.createReadStream(url).pipe(response); | ||
})); | ||
fns.forEach(function(method) { | ||
that[method].apply(that, args); | ||
}); | ||
}; | ||
that.upgrade = router(methods.upgrade); | ||
@@ -172,0 +120,0 @@ that.close = function() { |
@@ -1,5 +0,1 @@ | ||
var escapeRegex = function(str) { | ||
return str.replace(/([\/\\\*\+\.\?\|\(\)\[\]\{\}])/g, '\\$1'); | ||
}; | ||
module.exports = function(pattern) { | ||
@@ -11,26 +7,17 @@ if (typeof pattern !== 'string') { // regex | ||
} | ||
var offset = 0; | ||
var keys = []; | ||
var res = '^'; | ||
pattern = pattern.replace(/:(\w+)/g, '{$1}'); // normalize | ||
pattern = pattern.replace(/(\/)?(\.)?\{([^}]+)\}(?:\(([^)]*)\))?(\?)?/g, function(match, slash, dot, key, capture, opt, offset) { | ||
var incl = (pattern[match.length+offset] || '/') === '/'; | ||
pattern.replace(/\{[^\{\}]+\}/g, function(a,b) { // a hack - we use replace as a tokenizer :) | ||
res += escapeRegex(pattern.substring(offset, b)); | ||
offset = a.length+b; | ||
res += '([^\\'+(pattern[offset]||'/')+']*)'; | ||
keys.push(a.substring(1, a.length-1)); | ||
keys.push(key); | ||
return (incl ? '(?:' : '')+(slash || '')+(incl ? '' : '(?:')+(dot || '')+'('+(capture || '[^/]+')+'))'+(opt || ''); | ||
}); | ||
pattern = pattern.replace(/([\/.])/g, '\\$1').replace(/\*/g, '(.+)'); | ||
pattern = new RegExp('^'+pattern+'[\\/]?$', 'i'); | ||
res += escapeRegex(pattern.substring(offset)); | ||
res += (res[res.length-1] === '/' ? '' : '/?')+'$'; | ||
res = new RegExp(res, 'i'); | ||
if (!keys.length) { // small optimization | ||
return function(str) { | ||
return res.test(str); | ||
}; | ||
} | ||
return function(str) { | ||
var match = str.match(res); | ||
var match = str.match(pattern); | ||
@@ -42,8 +29,10 @@ if (!match) { | ||
match.slice(1).forEach(function(result, i) { | ||
map[keys[i]] = result; | ||
match.slice(1).forEach(function(param, i) { | ||
var k = keys[i] = keys[i] || 'wildcard'; | ||
map[k] = map[k] ? [].concat(map[k]).concat(param) : param; | ||
}); | ||
return map; | ||
}; | ||
}; | ||
}; |
{ | ||
"name":"router", | ||
"version":"0.3.2", | ||
"version":"0.4.0", | ||
"description":"A lean and mean web router", | ||
@@ -5,0 +5,0 @@ "contributors": [ |
@@ -24,3 +24,3 @@ # Router | ||
router.get('/{base}', function(request, response) { | ||
var base = request.matches.base; // ex: if the path is /foo/bar, then base = foo | ||
var base = request.params.base; // ex: if the path is /foo/bar, then base = foo | ||
}); | ||
@@ -33,6 +33,23 @@ ``` | ||
router.get('/{x}x{y}', function(request, response) { | ||
// if the path was /200x200, then request.matches = {x:'200', y:'200'} | ||
// if the path was /200x200, then request.params = {x:'200', y:'200'} | ||
}); | ||
``` | ||
Optional patterns are supported by adding a `?` at the end | ||
``` js | ||
router.get('/{prefix}?/{top}', function(request, response) { | ||
// matches both '/a/b' and '/b' | ||
}); | ||
``` | ||
If you want to just match everything you can use a wildcard `*` which works like unix wildcards. | ||
``` js | ||
router.get('/{prefix}/*', function(request, response) { | ||
// matches both '/a/', '/a/b', 'a/b/c' and so on. | ||
// the value of the wildcard is available through request.params.wildcard | ||
}); | ||
``` | ||
You can also use regular expressions and the related capture groups instead: | ||
@@ -42,7 +59,7 @@ | ||
router.get(/^\/foo\/(\w+)/, function(request, response) { | ||
var group = request.matches[1]; // if path is /foo/bar, then group is bar | ||
var group = request.params[1]; // if path is /foo/bar, then group is bar | ||
}); | ||
``` | ||
Besides `get` the avaiable methods are `post`, `put`, `head`, `del`, `request` and `upgrade`. | ||
`request` matches all the standard http methods and `upgrade` is usually used for websockets. | ||
Besides `get` the avaiable methods are `options`, `post`, `put`, `head`, `del`, `all` and `upgrade`. | ||
`all` matches all the standard http methods and `upgrade` is usually used for websockets. |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
62
1
6858
5
145