node.js从原始http请求string创build对象
我有一个原始的HTTP请求string,我需要创build一个对象表示。
而不是重新发明轮子,我正在考虑使用内部http分析器来获取http.IncomingMessage的一个实例
可能吗?
我想是因为string和完整的string没有太大的区别。
怎么做?
我看了一下源代码,他们得到一个请求parsing器如下
var HTTPParser = process.binding('http_parser').HTTPParser; var parser = new HTTPParser(HTTPParser.REQUEST)
编辑
从node.jstesting中取得一些进展
var request = Buffer(raw); var parser = new HTTPParser(HTTPParser.REQUEST); parser.execute(request, 0, request.length);
编辑2
一些事件处理者失踪(所有这些)
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'); };
谢谢
显然, http_parser
模块是一个低级的基于callback的parsing器。 它将通过这些callback函数发送可以parsing的string的任何部分,由您来决定如何创build一个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
参数化的,并且通常是围绕在服务器内使用它的想法而构build的。 parsing它的代码是有点混乱,以重用(按我的口味)。
老话题,但我会说点什么。
在自己的东西(模块或应用程序)中导出HTTPParser并不那么简单,因为http库使用了许多内部本地函数和构造函数。 另外,HTTPParser本身是从C库和一些helper绑定的。
据我所知,http.parsers从节点> 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 }
更多信息在这里
此外,感谢@KT优雅的解决scheme