UNPKG

crossfire

Version:

A simple proxy that uses DNS SRV records to dynamically update its routing table.

64 lines (56 loc) 1.93 kB
{async} = require "fairmont" http = require "http" {promise} = require "when" {liftAll} = require "when/node" dns = liftAll require "dns" dns.setServers [ "8.8.8.8" "8.8.4.4" ] parseHost = do (re=/^(\w+)(\.(\w+\.\w+))?(:(\d+))?$/) -> (host) -> if (match = host.match re)? [_, name, _, domain, _, port] = match {name, domain, port} else {} Routes = find: async (request) -> {name, domain} = parseHost request.headers.host console.log "finding routes with ", {name, domain} if domain? addresses = yield dns.resolveSrv "_#{name}._http.#{domain}" address = addresses[Math.round(Math.random() * (addresses.length - 1))] console.log "found route #{address.name}:#{address.port}" address Proxy = log: do (n=0) -> (next) -> (request, response) -> {url, method, headers} = request host = if headers.host? then headers.host else "-" console.log "request #{n}: #{host} #{method} #{url}" do (n) -> response.on "finish", -> {statusCode} = response console.log "response #{n}: #{statusCode}" n++ next request, response start: (_port) -> http.createServer Proxy.log async (request, response) -> {url, method, headers} = request try {name, port} = yield Routes.find request # not sure we need this, but we don't want to rely # on the OS to resolve these names since they may # be changing pretty frequently... [host] = yield dns.resolve name console.log "resolved #{name} to #{host}" request.pipe http.request {host, port, url, method, headers}, (_response) -> _response.pipe response catch error response.statusCode = 503 response.end() .listen _port, -> console.log "Listening on port #{_port}" Proxy.start (if process.argv[2]? then process.argv[2] else 80)