2

I'm trying to put multiple sails server on same server, to do that I want to put a node http-proxy that redirect every domain on the right server like this :

var http = require('http'),
    httpProxy = require('http-proxy'), 
    proxy = httpProxy.createProxyServer({}), 
    url = require('url'); 

http.createServer(function(req, res) 
{ 
    var hostname = req.headers.host.split(":")[0]; 
    var pathname = url.parse(req.url).pathname; 

    switch(hostname) 
    { 
        case 'example.com': 
            proxy.web(req, res, { target: 'http://localhost:8080' }); 
            break; 
        case 'dev.example.com': 
            proxy.web(req, res, { target: 'http://localhost:8081' }); 
            break; 
        default: 
            proxy.web(req, res, { target: 'http://localhost:80' }); 
    } 
}).listen(80, function() { 
    console.log('proxy listening on port 80'); 
});

But with this after a new page is called I have this error and proxy crash :

/var/www/default/node_modules/http-proxy/lib/http-proxy/index.js:119
    throw err; 
          ^ 
Error: socket hang up 
    at createHangUpError (_http_client.js:215:15) 
    at Socket.socketCloseListener (_http_client.js:247:23) 
    at Socket.emit (events.js:129:20)
    at TCP.close (net.js:485:12)

I suppose I missed some code to also forward sockets but how can I do that ? Is this kind of proxy strong enough for production ?

mscdex
  • 104,356
  • 15
  • 192
  • 153
jaumard
  • 8,202
  • 3
  • 40
  • 63

2 Answers2

1

You are only handling proxy for http request, You should also handle socket request.

Here is small trick, you can add your logic in your app.

proxyServer.on('upgrade', function (req, socket, head) {

    console.log(req)
    proxy.ws(req, socket, head);
});
Nishchit
  • 18,284
  • 12
  • 54
  • 81
1

Finally I use this : https://gist.github.com/jaumard/047f10b7c0563b4bd045

It handle http and sockets, and check if web site is alive, if it's not it's send a maintenance page.

/**
 * Node.js proxy to redirect domain to correct server
 * Also check is server is alive or send a maintenance page
 */
var http = require('http'),
    httpProxy = require('http-proxy'),
    proxy = httpProxy.createProxyServer({}),
    request = require('request'),
    domains = {
    "domain1.com" : "localhost:8080",
    "dev.domain1.com" : "localhost:8081",
    "domain2.com" : "localhost:8082",
    "default" : "localhost:8080"
};

var maintenance = "<!DOCTYPE html>"+ "<title>Site Maintenance</title>" + "<style>" + "  body { text-align: center; padding: 150px; }" + "  h1 { font-size: 50px; }" + "  body { font: 20px Helvetica, sans-serif; color: #333; }" + "  article { display: block; text-align: left; width: 650px; margin: 0 auto; }" + "  a { color: #1bbc9b; text-decoration: none; }" + "  a:hover { color: #109a7e; text-decoration: none; }" + "</style>" + "<article>" + "    <h1>We&rsquo;ll be back soon!</h1>" + "    <div>" + "        <p>Sorry for the inconvenience but we&rsquo;re performing some maintenance at the moment. If you need to you can always <a href=\"mailto:me@me.com\">contact us</a>, otherwise we&rsquo;ll be back online shortly!</p>" + "        <p>&mdash; My Team</p>" + "    </div>" + "</article>";

//Check is server is alive, if not respond a maintenance page
var checkServerAvailability = function (req, res, url)
{
    request(url + '/isAlive', function (error, response, body)
    {
        if (!error && response.statusCode == 200)
        {
            proxy.web(req, res, {target : url});
        }
        else
        {
            res.writeHeader(503, {"Content-Type" : "text/html"});
            res.write(maintenance);
            res.end();
        }
    });
};

var server = http.createServer(function (req, res)
{
    var hostname = "";
    //If server call with domaine and not call with IP directly
    if (req.headers.host)
    {
        hostname = req.headers.host.split(":")[0];
    }

        //If it's a know domain, redirect to correct server
    if (domains[hostname])
    {
        checkServerAvailability(req, res, 'http://' + domains[hostname]);
    }
    else
    {
        checkServerAvailability(req, res, 'http://' + domains["default"]);
    }
});

// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
server.on('upgrade', function (req, socket, head)
{
    var hostname = "";
    //If server call with domaine
    if (req.headers.host)
    {
        hostname = req.headers.host.split(":")[0];
    }

    //If it's a know domain, redirect to correct server
    if (domains[hostname])
    {
        proxy.web(req, socket, {target : 'ws://' + domains[hostname]});
    }
    else
    {
        proxy.web(req, socket, {target : 'ws://' + domains["default"]});
    }
});

//Catch error to prevent proxy crash
proxy.on('error', function (err)
{
    console.error(err);
});

server.listen(80, function ()
{
    console.info('proxy listening on port 80');
});
jaumard
  • 8,202
  • 3
  • 40
  • 63