forked from arne/asdf-games
68 lines
1.4 KiB
JavaScript
68 lines
1.4 KiB
JavaScript
|
var URL = require('url')
|
||
|
|
||
|
module.exports = function(/* fn1, fn2, ... */) {
|
||
|
var handle = function (req, res, out) {
|
||
|
var i = 0
|
||
|
function next(err) {
|
||
|
var layer = handle.layers[i++]
|
||
|
|
||
|
if (!layer || res.headersSent) {
|
||
|
// all done
|
||
|
if (out) return out(err) // delegate to parent
|
||
|
|
||
|
if (err && res.statusCode < 400) res.statusCode = err.status || 500
|
||
|
else res.statusCode = 404
|
||
|
|
||
|
return res.end()
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
layer(req, res, next)
|
||
|
}
|
||
|
catch (e) {
|
||
|
next(e)
|
||
|
}
|
||
|
}
|
||
|
next()
|
||
|
}
|
||
|
|
||
|
handle.layers = Array.prototype.slice.call(arguments)
|
||
|
|
||
|
handle.use = function(fn) {
|
||
|
if (typeof fn == 'object' && fn.handle) fn = fn.handle.bind(fn)
|
||
|
handle.layers.push(fn)
|
||
|
return this
|
||
|
}
|
||
|
|
||
|
handle.mount = function(path, fn) {
|
||
|
return this.use(sub(path, fn))
|
||
|
}
|
||
|
|
||
|
return handle
|
||
|
}
|
||
|
|
||
|
function sub(mount, fn) {
|
||
|
if (mount.substr(-1) != '/') mount += '/'
|
||
|
if (typeof fn == 'object' && fn.handle) fn = fn.handle.bind(fn)
|
||
|
|
||
|
return function(req, res, next) {
|
||
|
var url = req.url
|
||
|
, uri = req.uri
|
||
|
|
||
|
if (url.substr(0, mount.length) !== mount && url.substr(0, mount.length) + '/' !== mount) return next()
|
||
|
|
||
|
// modify the URL
|
||
|
if (!req.realUrl) req.realUrl = url
|
||
|
|
||
|
req.url = url.substr(mount.length-1)
|
||
|
if (req.uri) req.uri = URL.parse(req.url)
|
||
|
|
||
|
fn(req, res, function(err) {
|
||
|
// reset the URL
|
||
|
req.url = url
|
||
|
req.uri = uri
|
||
|
next(err)
|
||
|
})
|
||
|
}
|
||
|
}
|