Search code examples
node.jswebsocketsocket.ionode-http-proxy

node.js not automatically passing library JS when there is http proxy


I have a node-http-proxy set up to forward site/n requests to node.js (at port 9000), and other requests to apache (port 8000). This is because I heavily make use of socket.io, and I don't want apache creating one thread per websocket request.

The following code works great, until I wanted to make it accessible through my public IP. Everything works except one thing - my_public_ip/n/socket.io/socket.io/js returns '404 Not Found'. It seems this request is not silently absorbed by node.js

httpProxy.createServer({
    router: {
        'localhost/n/': '127.0.0.1:9000',
        'localhost': '127.0.0.1:8000',
        'my_public_ip/n': '127.0.0.1:9000',
        'my_public_ip': '127.0.0.1:8000'
    }
}).listen(80);

function handler(req, res) {
    var pathName = url.parse(req.url).pathname;
    if(pathName.substr(0,2) == "//"){
        pathName = pathName.substr(1);
    }
    var pathSplit = pathName.split('/');
    nextURL = pathSplit.join('/').substr(8);
    if(pathSplit[1] == 'static'){
        fs.readFile(__dirname + '/static/' + nextURL, function(err, data) {
            if(err) {
                res.writeHead(404);
                return res.end('404 Not Found');
            }
            res.writeHead(200);
            res.end(data);
        });
    } else if(pathName !== '/'){
        fs.readFile(__dirname + '/index.html', function(err, data) {
            if(err) {
                res.writeHead(500);
                return res.end('Error loading file. Does it exist? (Reading ' + __dirname + ')');
            }
            res.writeHead(200);
            res.end(data);
        });
    }
}

Solution

  • The node http server is serving up the client-side script for socket.IO. What is happening is that because you are not proxying the http traffic over to node.JS, there is no way you can see the client JS script. (Socket.IO doesn't push the JS script over a socket.IO connection.)

    The most basic work around is to create a copy of the JS script on your Apache server. Another way is to route the request to Node.JS by adding an additional routing instruction just for the script path. I think the former will give you better performance.