我有一个原始的HTTP请求字符串,我需要从中创建一个对象表示。
我没有重新发明轮子,而是考虑使用内部http解析器来获取http.IncomingMessage的实例
我想是这样的,因为字符串与完整的流没有那么不同。
我查看了源代码,他们得到了一个请求解析器,如下所示
var HTTPParser = process.binding('http_parser').HTTPParser;
var parser = new HTTPParser(HTTPParser.REQUEST)
修改
取得了一些进展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');
};
由于
答案 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提供优雅的解决方案