Node.js HTTPParser不会调用某些回调

时间:2012-11-30 18:35:41

标签: node.js http parsing

我在Node.js v0.8.15中使用HTTPParser。不幸的是,一些回调永远不会被调用。

例如,以下代码仅调用onHeadersComplete。无法设法拨打onURLonHeaderFieldonHeaderValue

var
    HTTPParser = process.binding('http_parser').HTTPParser,
    parser = new HTTPParser(HTTPParser.REQUEST),
    request = new Buffer(
        'GET /test HTTP/1.1\r\n' +
        'Host: www.example.com\r\n' +
        'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/17.0 Firefox/17.0\r\n' +
        'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n' +
        'Accept-Language: en-US,en;q=0.5\r\n' +
        'Accept-Encoding: gzip, deflate\r\n' +
        '\r\n'
    );

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

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

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

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

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

怎么了?

2 个答案:

答案 0 :(得分:4)

对于那些从搜索引擎来到这里的人。 最新版本的Node使用略有不同的组织。此代码有效:

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

var parser = new HTTPParser(HTTPParser.REQUEST);

const kOnHeaders = HTTPParser.kOnHeaders | 0;
const kOnHeadersComplete = HTTPParser.kOnHeadersComplete | 0;
const kOnBody = HTTPParser.kOnBody | 0;
const kOnMessageComplete = HTTPParser.kOnMessageComplete | 0;
const kOnExecute = HTTPParser.kOnExecute | 0;

parser[kOnHeaders] = 
    function(headers, url) {
        console.log('kOnHeaders');
    }
parser[kOnHeadersComplete] = 
    function(versionMajor, versionMinor, headers, method,
             url, statusCode, statusMessage, upgrade, shouldKeepAlive) {
        console.log('kOnHeadersComplete');
    }
parser[kOnBody] = 
    function(b, start, len) {
        console.log('kOnBody');
    }
parser[kOnMessageComplete] = 
    function() {
        console.log('kOnMessageComplete');
    }
parser[kOnExecute] = 
    function() {
        console.log('kOnExecute');
    }

var ret = parser.execute(new Buffer(
        'GET /test HTTP/1.1\r\n' +
        'Host: www.example.com\r\n' +
        'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/17.0 Firefox/17.0\r\n' +
        'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n' +
        'Accept-Language: en-US,en;q=0.5\r\n' +
        'Accept-Encoding: gzip, deflate\r\n' +
        '\r\n'
    ));

或者,有一些包装模块。 该对象目前有以下方法:

  • close - 取消解析并释放解析器(?)
  • 执行 - 读取数据块并解析它。如果标题缓慢到达,可以被调用任意次数
  • 完成 - 告诉解析器将不再有数据,完成解析
  • reinitialize - 为其他类型的消息(请求/响应)准备解析器
  • 暂停 - IDK,可能会停止解析数据添加
  • resume - IDK,也许开始解析
  • 消费 - IDK,适用于Stream
  • unconsume - IDK,适用于Stream
  • getCurrentBuffer - 返回当前数据收集器(?)

关于使用细节,您可以参考节点源:

答案 1 :(得分:1)

process.binding仅应由核心节点库使用。从我对源代码的简要介绍来看,http解析器C ++代码只暴露了一小部分事件(onHeadersonHeadersCompleteonBodyonMessageComplete),所以我相信这些是你可以锁定的唯一事件。

解析器在内部使用来自解析器的一些额外回调,但它们不会作为事件向JS land公开。