5

I'm trying to parse an HTTP response in the form of a String or Buffer into an Object.

The result would be an Object like the native http module's response.

I tried to import the native HTTP parser, but the results were too raw for my use-case :

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

var parser = new HTTPParser(HTTPParser.RESPONSE);

parser.onHeadersComplete = function(res) {
    console.log('onHeadersComplete');
    console.log(res);
};

parser.execute(data, 0, data.length);

which would return something like this :

onHeadersComplete
{
   headers: 
   [ 'X-Powered-By',
     'Express',
     'Content-Type',
     'text/plain',
     'Content-Length',
     '2',
     'Date',
     'Sat, 19 Apr 2014 20:16:45 GMT',
     'Connection',
     'keep-alive' ],
  statusCode: 200,
  versionMajor: 1,
  versionMinor: 1,
  shouldKeepAlive: true,
  upgrade: false 
}

Two things are lacking for my use-case :

  1. map of header names associated with header values
  2. parsing the response body

    • Does anyone know how to achieve this ?

Thank you in advance for your help !

2
  • Why are you trying to manually parse an HTTP response? Commented Apr 19, 2014 at 23:45
  • 2
    Because I'm writing a fuzzer which uses Node.js's net module to send mis-constructed HTTP requests to test HTTP servers. Commented Apr 20, 2014 at 8:35

3 Answers 3

4

You have to fill all the callbacks.

var HTTPParser = require('http-parser-js').HTTPParser;
var parser = new HTTPParser(HTTPParser.RESPONSE);
parser.onHeadersComplete = function(res) {
    console.log(res.headers);
};
parser.onBody = function(chunk, offset, length) {
    console.log("body", chunk.toString(), offset, length)
}
parser.onMessageComplete = function() {

}
parser.execute(new Buffer('HTTP/1.1 200 OK\r\nContent-Type: text/plain; xya\r\nContent-Length: 11\r\n\r\nhello world'))
Sign up to request clarification or add additional context in comments.

Comments

0

For headers transform you can use private method http.IncomingMessage(socket)._addHeaderLines(headersArr, headersNumber)

var msg=new http.IncomingMessage()

msg._addHeaderLines(['X-Powered-By',
     'Express',
     'Content-Type',
     'text/plain',
     'Content-Length',
     '2',
     'Date',
     'Sat, 19 Apr 2014 20:16:45 GMT',
     'Connection',
     'keep-alive' ], 10);
console.log(msg);

Result:

IncomingMessage {
  ...
  headers:
   { 'x-powered-by': 'Express',
     'content-type': 'text/plain',
     'content-length': '2',
     date: 'Sat, 19 Apr 2014 20:16:45 GMT',
     connection: 'keep-alive' },
  rawHeaders:
   [ 'X-Powered-By',
     'Express',
     'Content-Type',
     'text/plain',
     'Content-Length',
     '2',
     'Date',
     'Sat, 19 Apr 2014 20:16:45 GMT',
     'Connection',
     'keep-alive' ],
  ...
 }

Usage sample from Node sources: https://github.com/nodejs/node/blob/master/lib/_http_common.js

Comments

-1

I'm also trying to study node.js and I just started yesterday. Since it's a javascript thing, here's my suggested solution.

I assume the object being parsed here is 'res' argument.

var headers = {};
for (index = 0; index < res.headers.length; index++) {
    headers[res.headers[index].replace('-', '')] = res.headers[++index];
}

// or this
for (index = 0; index < res.headers.length; index+=2) {
    var headerName = res.headers[index].replace('-', '');
    headers[headerName] = res.headers[index + 1];
}

// Note that we removed the '-' in the name since it's an invalid character for property name.

// Access sample.
console.log(headers.ContentType);
console.log(headers['ContentType']);

I hope it helped you out.

1 Comment

Sorry, but I'm not trying to remodel the Express objects. What I want to do is parse HTTP protocol "packets" from a TCP stream result buffer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.