Skip to content

Instantly share code, notes, and snippets.

@takeshy
Created December 28, 2012 08:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takeshy/4395859 to your computer and use it in GitHub Desktop.
Save takeshy/4395859 to your computer and use it in GitHub Desktop.
http-proxyを使ったWebSocket対応のreverse proxy。 proxy先のHostの情報のJSONファイルを監視していて、変更があれば読み込むようになっているため動的にproxy先のサーバを変更できる。死活監視プログラムがJSONを作成すればFailOverが実現できる。
var http = require('http')
, httpProxy = require('http-proxy')
, Cookie = require('cookie')
, fs = require('fs');
var SERVERS_FILE_NAME = "servers.json"
var PROXY_PORT = 4000
var SERVERS = null;
var g_httpProxies = {};
function readValidServersInfo(){
fs.readFile(SERVERS_FILE_NAME,function(err,data){
try{
if(err) throw err;
currentServers = JSON.parse(data);
if(currentServers.length == 0) throw new Error("valid server was not existed.");
SERVERS = currentServers;
console.log(SERVERS);
}catch(e){
console.log(e);
if(SERVERS == null){
exit();
}
}
});
}
function decideHost(){
var idx = Math.floor(Math.random() * SERVERS.length);
return {key: idx + ":" + SERVERS[idx].host + SERVERS[idx].port,host: SERVERS[idx].host,port: SERVERS[idx].port};
}
function decideHostFromKey(key){
var sPos = key.indexOf(":");
if(sPos == -1){
return decideHost();
}
var index = key.substr(0,sPos);
var serverWithPort = key.substr(sPos + 1,key.length - sPos - 1);
var serverInfo = SERVERS[index];
if(serverInfo && (serverInfo.host + serverInfo.port) == serverWithPort){
return {key: key,host: serverInfo.host,port: serverInfo.port};
}else{
SERVERS.forEach(function(server){
if((server.host + server.port) == serverWithPort){
return {key: key,host: server.host,port: server.port};
}
});
}
return decideHost();
}
function getProxyInfo(req){
var target,cookie;
if(req.headers.cookie){
cookie = Cookie.parse(req.headers.cookie);
if(cookie && cookie.proxyKey){
return decideHostFromKey(cookie.proxyKey);
}
}
return decideHost();
}
function findOrCreateHttpProxy(req,res){
var proxyInfo = getProxyInfo(req);
if(res){
res.setHeader('Set-Cookie', 'proxyKey=' + proxyInfo.key);
}
if(! g_httpProxies[proxyInfo.key]){
g_httpProxies[proxyInfo.key] = new httpProxy.HttpProxy({target: { host: proxyInfo.host ,port: proxyInfo.port }});
}
return g_httpProxies[proxyInfo.key];
}
readValidServersInfo();
fs.watchFile(SERVERS_FILE_NAME,function(curr,filename){
readValidServersInfo();
});
var server = http.createServer(function(req,res){
var proxy = findOrCreateHttpProxy(req,res);
proxy.proxyRequest(req,res);
});
server.on('upgrade',function(req,socket,head){
var proxy = findOrCreateHttpProxy(req);
proxy.proxyWebSocketRequest(req,socket,head);
});
server.listen(PROXY_PORT);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment