asdf-games/node_modules/stacked/stacked.js

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)
})
}
}