繁体   English   中英

覆盖Node.js HTTP解析器

[英]Overriding Node.js HTTP parser

我在正常的HTTP服务器上使用Node的基本http.request()函数没有问题。 我需要在SHOUTcast服务器上使用http.request() (或类似的)。 SHOUTcast“协议”与HTTP完全兼容,除了一个细节......第一个响应行。

普通HTTP服务器响应:

HTTP/1.1 200 OK

SHOUTcast服务器响应:

ICY 200 OK

同样,协议的其余部分是相同的。 唯一的区别是HTTP/1.xICY

我想扩展,子类或以某种方式修改Node的http.request()函数,以便我可以使它与SHOUTcast服务器一起使用。 之前已经完成了与节点连接到SHOUTcast,但只能通过重新发明整个轮子。 我宁愿不这样做,因为它只是一个小的协议差异。

我的问题:有没有办法做到以下其中一种?

  1. 扩展或覆盖 Node的HTTP解析器的相关部分。 (我怀疑这是可能的,因为解析器似乎是本机代码 。)

  2. 创建我自己的代码来解析HTTP的相关部分,但尽可能多地重用HTTP的现有Node组件。

  3. 创建一个简单的内部代理 (或以某种方式中继数据),以便我可以在它到达Node的HTTP解析器之前修改第一个服务器响应行。

  4. 别的什么?

我也考虑过使用Shred ,但它没有提供流式响应的选项。 (它等待整个服务器响应在触发事件之前完成,这对于数据无限期运行的流服务器不起作用。)沿着同样的路线,我尝试了Request ,但它使用了Node自己的HTTP解析器,所以我得到与原生HTTP客户端相同的解析错误。

我想出了另一种方法,类似于内部代理,但没有额外的连接。 似乎可以覆盖HTTP客户端的内部使用的套接字。 完成此操作后,在将数据传递给原始内部套接字ondata函数之前,很容易挂钩并修改数据。

用法

var httpicy = new HttpIcyClient();
httpicy.request(/* your normal request parameters here */);

资源

var http = require('http');

var HttpIcyClient = function () {};
HttpIcyClient.prototype.request = function (options, callback) {
    var req = http.request(options, callback),
        originalOnDataFunction,
        receiveBuffer = new Buffer(0);

    req.on('socket', function (socket) {
        originalOnDataFunction = socket.ondata;
        socket.ondata = function (d, start, end) {
            receiveBuffer = Buffer.concat([receiveBuffer, d.slice(start, end)]);
            if (receiveBuffer.length >= 4) {
                socket.ondata = originalOnDataFunction;
                if (receiveBuffer.toString('ascii', 0, 4) === 'ICY ') {
                    receiveBuffer = Buffer.concat([new Buffer('HTTP/1.0 ', 'ascii'), receiveBuffer.slice(4)]);
                }
                socket.ondata.apply(this, [receiveBuffer, 0, receiveBuffer.length]);
            }
        };
    });
    return req;
}

3。 创建一个简单的内部代理

砰。 你说对了。

使用Node.js net对象创建实际位于用户和http服务器之间的TCP服务器。 如您所述,替换所有请求和响应的第一行,您可以继续按原样继续使用http服务器。 (您在非标准端口上创建内部http服务器,在另一个端口上创建网络服务器,然后在两者之间链接流,使用一些代码拦截来自请求用户的第一个数据块,以及第一个块来自响应服务器的数据。)

你在Javascript中的所有代码,它都是(几乎)没有bufferbloat流。

编辑,似乎我误读了你的帖子。 我看到你并没有尝试实现Node.js shoutcast服务器,而是尝试从中访问数据。 net对象应该仍然可以工作,但不是完全相同。

您需要使用net.connect与指定的shoutcast服务器通信,并使用一个知道net.connect流的新net服务器来代理它与您的http.request()之间的代理。 所以,它会像:

+---------------+    +----------+    +-----------+    +----------------+
| http.request()|--->|net.Server|--->|net.connect|--->|SHOUTcast Server|
|               |<---|          |<---|           |<---|                |
+---------------+    +----------+    +-----------+    +----------------+
                  TCP             JS               TCP

那就是我如何构建它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM