Node.js server and xinetd

I’ve been playing with Node.js and decided to see if I could create a service that could be run out of xinetd. Running a service out of xinetd requires that it use stdin (fd 0) for it’s connection. To accomplish this I subclassed from http.Server adding a connectFD method to be able to set the file descriptor for the server to use.

var sys = require('sys'),
net = require('net'),
http = require('http');

var Server = function (listener) {
    http.Server.call(this, listener);
};

sys.inherits(Server, http.Server);

exports.Server = Server;

Server.prototype.connectFD = function (fd) {
    var s = new net.Stream(fd);
    s.type = this.type;
    s.server = this;
    s.resume();
    this.emit('connection', s);
}

I named this xhttp.js.

You need a service configuration file in /etc/xinetd.d to specify the port and command similar to:

# default: on
# description: node.js based service
#
service xnode
{
        disable                 = no
        port                    = 49000
        socket_type             = stream
        protocol                = tcp
        wait                    = no
        user                    = root
        server                  = <path of node executable>
        server_args             = <path of services js file>
        env             = NODE_PATH=<path to xhttp.js file>
}

Don’t forget to set the required path names.

For my service I decided to have a little fun and have it run commands on the server and return the output.

var sys = require('sys'),
    xhttp = require('xhttp'),
    url = require('url'),
    exec  = require('child_process').exec;

var requestHandler = function (req, res) {
    var cmd = url.parse(req.url).pathname;
    cmd = cmd.substring(1);
    qstr = url.parse(req.url, true).query
    for (key in qstr) {
        cmd  = cmd + " " + qstr[key];
    }

    var child = exec(cmd,
        function (error, stdout, stderr) {
            res.writeHead(200, {'Content-Type': 'text/plain'});
            if (error !== null) {
                res.write(stderr);
            }
            else {
                res.write(stdout);
            }
            res.end();
        });
}
var s = new xhttp.Server(requestHandler);
s.connectFD(0);

After adding the xinetd configuration file to /etc/xinetd.d restart xinetd and try something like :

http://localhost:49000/ls?arg0=-la&arg1=/tmp

Leave a comment

2 Comments.

  1. it was very interesting to read.
    I want to quote your post in my blog. It can?
    And you et an account on Twitter?