Drahcir
Drahcir

Reputation: 11972

Parse HTTP messages from Socket

I have a socket server listening for all types of data on the same port, if the data is HTTP then I would like to parse it, otherwise I would like to do something else with it...

net.createServer(function(socket){
    if(/*socket contains HTTP data*/){
        // parse it
    }
    else{
        // do something else with the socket
    }
}).listen(999)

How should I parse the HTTP data from the socket?

I have started to write my own HTTP parser for this purpose, but I don't want to reinvent the wheel, maybe there is a much better way.

Upvotes: 5

Views: 2096

Answers (2)

Drahcir
Drahcir

Reputation: 11972

After looking at the source for http.js, I came up with the following way to do it...

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

var HTTPParser = process.binding('http_parser').HTTPParser;


function freeParser(parser){
    if (parser) {
        parser.onIncoming = null;
        parser.socket = null;
        http.parsers.free(parser);
        parser = null;
    }
};


function parse(socket){
    var emitter = new events.EventEmitter();
    var parser = http.parsers.alloc();

    parser.reinitialize(HTTPParser.REQUEST);
    parser.socket = socket;
    parser.maxHeaderPairs = 2000;

    parser.onIncoming = function(req){
        emitter.emit('request', req);
    };

    socket.on('data', function(buffer){
        var ret = parser.execute(buffer, 0, buffer.length);
        if(ret instanceof Error){
            emitter.emit('error');

            freeParser(parser);
        }
    });

    socket.once('close', function(){
        freeParser(parser);
    });

    return emitter;
};


net.createServer(function(socket){
    var parser = parse(socket);

    parser.on('request', function(req){
        // Got parsed HTTP object
    });

    parser.once('error', function(){
        // Not HTTP data
    });
}).listen(999);

Upvotes: 6

Gates VP
Gates VP

Reputation: 45277

So the Node.JS core libraries actually implement HTTP handling over a socket. That code is written in Javascript and is visible: https://github.com/joyent/node/blob/master/lib/http.js

The big challenge here is really that I'm not clear how you're planning to differentiate traffic types? I mean you can listen for "HTTP" on any port or socket, we just generally agree on 80 (and 443 for https).

But it's not clear how you listen for call to both HTTP and say the MySQL protocol within the same socket. How do you know which packets of data belong to which protocol? I've never really heard of anyone implementing such a "multi-purpose" socket, you normally know what type of data to expect before opening the socket. Otherwise you could just be receiving garbage, right?

Upvotes: 1

Related Questions