node.js从原始http请求字符串创建对象

时间:2014-10-03 14:37:07

标签: node.js parsing http

我有一个原始的HTTP请求字符串,我需要从中创建一个对象表示。

我没有重新发明轮子,而是考虑使用内部http解析器来获取http.IncomingMessage的实例

有可能吗?

我想是这样的,因为字符串与完整的流没有那么不同。

怎么做?

我查看了源代码,他们得到了一个请求解析器,如下所示

var HTTPParser = process.binding('http_parser').HTTPParser;
var parser = new HTTPParser(HTTPParser.REQUEST)

修改

node.js test

取得了一些进展
var request = Buffer(raw);
var parser = new HTTPParser(HTTPParser.REQUEST);

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

修改2

某些eventHandlers缺失(全部)

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

parser.onBody = function(body) {
    console.log('body done');
    console.log(body.toString());
}

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

由于

2 个答案:

答案 0 :(得分:2)

显然,http_parser模块是一个基于回调的低级解析器。它将通过这些回调发送它可以解析给你的字符串的任何部分,由你来制作IncomingMessage或其他任何你需要的部分。

我相信你可能正在寻找的东西:

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

function parseMessage(request) {
    var _message = {};
    var _parser = new HTTPParser(HTTPParser.REQUEST);

    _parser.onHeadersComplete = function(headers) { 
        _message = headers; 
    }

    _parser.onBody = function(body, start, len) {
        _message.data = body.slice(start, start+len);
    }

    var _result = _parser.execute(request, 0, request.length);

    if (_result != request.length) { 
        _message.error = _result; 
    }
    else {
        _message.error = false;
    }
    return _message;
}

var request = Buffer("GET / HTTP/1.1\nHost: localhost\nContent-Length: 2\n\nHi\n\n");
result = parseMessage(request);

请注意,特定的IncomingMessage类使用socket参数化,并且通常围绕在服务器中使用它的想法而构建。 code for parsing it有点麻烦,按原样重复使用(按照我的口味)。

答案 1 :(得分:0)

老话题,但我会说些什么。

在自己的东西(模块或应用程序)中导出HTTPParser并不那么简单,因为http库使用许多内部本地函数和构造函数。此外,HTTPParser本身是从C库和一些帮助程序绑定的。

据我所知,http.parsers已从Node> 删除; 4,所以唯一的方法是从http库导入所有必要的东西。

对于节点0.x,可以轻松导入:

var parser = require("http").parsers.alloc();

parser.onIncoming = function(response) {
  console.log(response);
};

function parse(data) {
    var buffer = new Buffer(data);
    parser.execute(buffer, 0, buffer.length);
}
/**
 * tests
 */
parse("DELETE / HTTP/1.1\r\n");
parse("user-agent: curl\r\n");
parse("x-pingback:");
parse("12023\r\n");
parse("\r\n");

//response
{ _readableState: 
   { highWaterMark: 16384,
     buffer: [],
     length: 0,
     pipes: null,
     pipesCount: 0,
     flowing: false,
     ended: false,
     endEmitted: false,
     reading: false,
     calledRead: false,
     sync: true,
     needReadable: false,
     emittedReadable: false,
     readableListening: false,
     objectMode: false,
     defaultEncoding: 'utf8',
     ranOut: false,
     awaitDrain: 0,
     readingMore: false,
     decoder: null,
     encoding: null },
  readable: true,
  domain: null,
  _events: {},
  _maxListeners: 10,
  socket: undefined,
  connection: undefined,
  httpVersion: '1.1',
  complete: false,
  headers: { 'user-agent': 'curl', 'x-pingback': '12023' },
  trailers: {},
  _pendings: [],
  _pendingIndex: 0,
  url: '/',
  method: 'DELETE',
  statusCode: null,
  client: undefined,
  _consuming: false,
  _dumped: false,
  httpVersionMajor: 1,
  httpVersionMinor: 1,
  upgrade: false }

更多信息here

另外,感谢@KT提供优雅的解决方案