sepro
Version:
Sepro is a http proxy which discovers where to proxy a request.
100 lines (78 loc) • 2.31 kB
JavaScript
var SeaportRouter = require('./seaport')
, fs = require('fs')
, path = require('path')
, send = require('send')
, lsr = require('lsr')
, inherits = require('util').inherits
, EventEmitter = require('events').EventEmitter
, url = require('url')
module.exports = Static
function Static(options) {
if (!(this instanceof Static)) return new Static(options)
EventEmitter.call(this)
options = options || {}
this.cwd = options.cwd || process.cwd()
this.routes = {}
}
inherits(Static, EventEmitter)
Static.prototype.attach = function (sepro) {
var self = this
sepro.routers.map(use)
sepro.on('use', use)
function use(layer) {
if (!(layer instanceof SeaportRouter)) return
Object.keys(layer.routes).forEach(function (key) {
register(layer.routes[key])
})
layer.on('register', register)
function register(service) {
var dirs = service.static
if (!dirs) return
if (typeof dirs === 'string') dirs = [ dirs ]
if (!Array.isArray(dirs)) return
var serverNames = layer.getServerNames(service)
, i
, dir
for (i = 0; i < dirs.length; i++) {
dir = path.resolve(self.cwd, dirs[i])
lsr(dir, onFiles)
}
function onFiles(err, files) {
if (err) return
var i
, stat
, filePath
, j
, sn
for (i = 0; i < files.length; i++) {
stat = files[i]
filePath = stat.path.slice(1)
for (j = 0; j < serverNames.length; j++) {
sn = serverNames[j]
if (!self.routes[sn]) self.routes[sn] = {}
self.routes[sn][filePath] = stat.fullPath
}
}
}
}
}
}
Static.prototype.getFile = function (req, target) {
if (!req) return false
target = target || (req.headers.host || '').split(':')[0]
var files = this.routes[target]
if (!files) return false
var parseUrl = url.parse(req.url)
return files[parseUrl.pathname]
}
Static.prototype.getProxyLocation = function (target, req) {
return this.getFile(req, target) ? this : false
}
Static.prototype.handleRequest = function (req, res, next) {
console.log('handle request')
var file = this.getFile(req)
if (!file) return next()
send(req, file)
.on('error', next)
.pipe(res)
}