regex-router
Advanced tools
60
index.js
@@ -1,45 +0,33 @@ | ||
'use strict'; /*jslint node: true, es5: true, indent: 2 */ | ||
function escapeRegex(string) { | ||
var specials = ['$', '(', ')', '*', '+', '.', '?', '[', '\\', ']', '^', '{', '|' , '}']; | ||
return string.replace(new RegExp('(\\' + specials.join('|\\') + ')', 'g'), '\\$1'); | ||
} | ||
var Router = module.exports = function() { | ||
this.routes = []; // e.g., [{regex: regex, http_method: http_method, func: func}, ...] | ||
this.requestListener = this.route.bind(this); | ||
'use strict'; /*jslint es5: true, node: true, indent: 2 */ | ||
var Router = module.exports = function(default_func) { | ||
this.nroutes = 0; | ||
this.routes = []; | ||
this.default = default_func || function() {}; | ||
}; | ||
Router.prototype.route = function(req, res) { | ||
var m; | ||
for (var route, i = 0; (route = this.routes[i]); i++) { | ||
if (route.http_method === 'any' || route.http_method === req.method.toLowerCase()) { | ||
if ((m = req.url.match(route.regex))) | ||
return route.func(m, req, res); | ||
for (var i = 0; i < this.nroutes; i++) { | ||
var route = this.routes[i]; | ||
var method_match = route.method == 'any' || route.method == req.method.toLowerCase(); | ||
if (method_match && (route.regex ? (m = req.url.match(route.regex)) : (m = req.url) === route.string)) { | ||
return route.func(req, res, m); | ||
} | ||
} | ||
m = req.url.match(/^(.+)$/); | ||
// check for existence of default? | ||
return this.default(m, req, res); | ||
return this.default(req, res, req.url); | ||
}; | ||
Router.prototype._add = function(regex, http_method, func) { | ||
// coerve strings to regex as exact match (must escape regex) | ||
if (!(regex instanceof RegExp)) | ||
regex = new RegExp('^' + escapeRegex(regex) + '$'); | ||
// func signature: (regex_match, req, res) | ||
this.routes.push({regex: regex, http_method: http_method, func: func}); | ||
Router.prototype.add = function(method, url, func) { | ||
/** add: append handler for given HTTP method and url to routes | ||
`url`: String | RegExp | ||
`func`: function(http.IncomingMessage, http.ServerResponse, String | RegExpMatch) */ | ||
var route = {method: method, func: func}; | ||
if (url instanceof RegExp) route.regex = url; | ||
else route.string = url; | ||
this.routes.push(route); | ||
this.nroutes++; | ||
}; | ||
Router.prototype.forward = function(url, router) { | ||
this._add(url, 'any', function(m, req, res) { | ||
// just discard m | ||
router.route(req, res); | ||
}); | ||
}; | ||
// add router.get(url, func), router.GET(url, func) shortcuts for common http methods | ||
// PATCH is not an official HTTP/1.1 method (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) | ||
var http_methods = ['any', 'options', 'get', 'head', 'post', 'put', 'delete', 'trace', 'connect', 'patch']; | ||
http_methods.forEach(function(http_method) { | ||
Router.prototype[http_method] = Router.prototype[http_method.toUpperCase()] = | ||
function(regex, func) { this._add(regex, http_method, func); }; | ||
['any', 'options', 'get', 'head', 'post', 'put', 'delete', 'trace', 'connect', 'patch'].forEach(function(method) { | ||
// add router.get(url, func), router.GET(url, func) shortcuts for common http methods | ||
Router.prototype[method] = Router.prototype[method.toUpperCase()] = | ||
function(url, func) { this.add(method, url, func); }; | ||
}); |
{ | ||
"name": "regex-router", | ||
"version": "0.1.9", | ||
"description": "Route http requests via regular expressions.", | ||
"version": "0.2.0", | ||
"description": "Route http(s) requests via regular expressions", | ||
"keywords": [ | ||
"http", | ||
"nodeps", | ||
"web server", | ||
@@ -17,8 +18,7 @@ "regex", | ||
}, | ||
"main": "index.js", | ||
"license": "MIT", | ||
"author": "Christopher Brown <io@henrian.com>", | ||
"devDependencies": { | ||
"tap": "~0.4", | ||
"request": "~2" | ||
"tap": "*", | ||
"request": "*" | ||
}, | ||
@@ -25,0 +25,0 @@ "scripts": { |
# Regex-router | ||
Regex-router is a simple Node.js library to simplify routing. By simple, I mean 35 lines of code. | ||
Regex-router is a simple Node.js library to simplify web application routing without using a framework. | ||
# Example | ||
Only [31 lines of code](index.js) (not counting tests)! | ||
var fs = require('fs'); | ||
var http = require('http'); | ||
var Router = require('regex-router'); | ||
var r = new Router(); | ||
## Example | ||
r.get(/^\/page\/(\w+)/, function(m, req, res) { | ||
console.log('Serving URL:', req.url); | ||
var page_name = m[1], | ||
page_path = __dirname + '/static_pages/' + page_name + '.html'; | ||
fs.readFile(page_path, 'utf8', function(err, html) { | ||
res.write(html); | ||
res.end(); | ||
}); | ||
}); | ||
```javascript | ||
var fs = require('fs'); | ||
var http = require('http'); | ||
var Router = require('regex-router'); | ||
r.default = function(m, req, res) { | ||
res.end('404. URL not found:', req.url); | ||
}) | ||
var R = new Router(function(req, res, m) { | ||
res.end('404. URL not found:', req.url); | ||
}); | ||
http.createServer(function(req, res) { | ||
r.route(req, res); | ||
}).listen(80, 'localhost'); | ||
R.get(/^\/page\/(\w+)/, function(req, res, m) { | ||
console.log('Serving URL:', req.url); | ||
var page_name = m[1]; | ||
var page_path = __dirname + '/static_pages/' + page_name + '.html'; | ||
fs.readFile(page_path, 'utf8', function(err, html) { | ||
res.write(html); | ||
res.end(); | ||
}); | ||
}); | ||
http.createServer(function(req, res) { | ||
R.route(req, res); | ||
}).listen(80, 'localhost'); | ||
``` | ||
## License | ||
Copyright © 2012–2013 Christopher Brown. [MIT Licensed](LICENSE). |
@@ -1,4 +0,4 @@ | ||
'use strict'; /*jslint node: true, es5: true, indent: 2 */ | ||
'use strict'; /*jslint es5: true, node: true, indent: 2 */ | ||
var fs = require('fs'); | ||
var test = require('tap').test; | ||
var tap = require('tap'); | ||
@@ -19,11 +19,10 @@ function linesOfCode(document) { | ||
var Router = require('..'); | ||
test('line count from README', function (t) { | ||
tap.test('line count from README', function(t) { | ||
t.plan(1); | ||
fs.readFile('../README.md', 'utf8', function (err, readme) { | ||
fs.readFile('../README.md', 'utf8', function(err, readme) { | ||
if (err) throw err; | ||
fs.readFile('../index.js', 'utf8', function (err, main) { | ||
fs.readFile('../index.js', 'utf8', function(err, main) { | ||
if (err) throw err; | ||
var stated_lines = parseInt(readme.match(/(\d+) lines of code/)[1], 10); | ||
var actual_lines = linesOfCode(main); | ||
// console.error(main); | ||
t.equal(stated_lines, actual_lines, 'Stated lines should match actual lines'); | ||
@@ -30,0 +29,0 @@ }); |
@@ -1,34 +0,31 @@ | ||
'use strict'; /*jslint node: true, es5: true, indent: 2 */ | ||
var test = require('tap').test; | ||
'use strict'; /*jslint es5: true, node: true, indent: 2 */ | ||
var tap = require('tap'); | ||
var request = require('request'); | ||
var Router = require('..'); | ||
test('basic server', function (t) { | ||
tap.test('basic server', function(t) { | ||
t.plan(2); | ||
// set up the routes | ||
var r = new Router(); | ||
r.get(/^\/page\/(\w+)/, function(m, req, res) { | ||
var R = new Router(function(req, res) { | ||
res.end('404 :: URL not found.'); | ||
}); | ||
R.get(/^\/page\/(\w+)/, function(req, res, m) { | ||
res.end('Fetching page "' + m[1] + '"'); | ||
}); | ||
r.default = function(m, req, res) { | ||
res.end('404 :: URL not found.'); | ||
}; | ||
// set up the server | ||
var hostname = '127.0.0.1'; | ||
var server = require('http').createServer(function(req, res) { | ||
// console.error('URL: ' + req.url); | ||
r.route(req, res); | ||
R.route(req, res); | ||
}).listen(0, hostname, function() { // port = 0 finds random free port | ||
// server running, ready to run tests | ||
// server running, ready to run tests | ||
var port = server.address().port; | ||
var addrport = 'http://' + hostname + ':' + port; | ||
request.get(addrport + '/page/contact', function (err, res, body) { | ||
request.get(addrport + '/page/contact', function(err, res, body) { | ||
t.equal(body, 'Fetching page "contact"', 'Need to fetch page by name.'); | ||
}); | ||
request.get(addrport + '/reference', function (err, res, body) { | ||
request.get(addrport + '/reference', function(err, res, body) { | ||
t.equal(body, '404 :: URL not found.', 'Need to return 404 page.'); | ||
@@ -41,2 +38,2 @@ }); | ||
}); | ||
}); | ||
}); |
36
9.09%5927
-9.21%92
-10.68%