正在重写Node.js HTTP解析器
Overriding Node.js HTTP parser
我在普通HTTP服务器上使用Node的基本http.request()
函数没有问题。我需要将http.request()
(或类似的)与SHOUTcast服务器一起使用。SHOUTcast"协议"与HTTP完全兼容,除了一个细节。。。第一条响应线。
普通HTTP服务器响应:
HTTP/1.1 200 OK
SHOUTcast服务器响应:
ICY 200 OK
同样,协议的其余部分是相同的。唯一的区别是HTTP/1.x
与ICY
。
我想扩展、子类化或以某种方式修改Node的http.request()
函数,这样我就可以使它与SHOUTcast服务器一起工作。使用Node连接SHOUTcast以前已经完成,但只是通过重新发明整个轮子。我宁愿不这么做,因为这只是一个小小的协议差异。
我的问题:有没有办法做到以下其中一项
扩展或覆盖Node的HTTP解析器的相关部分。(我怀疑这是否可能,因为解析器似乎是本地代码。)
创建我自己的代码,解析HTTP的相关部分,但尽可能多地重用HTTP的现有Node组件。
创建一个简单的内部代理(或者以某种方式中继数据),这样我就可以在第一个服务器响应行到达Node的HTTP解析器之前修改它。
还有别的吗
我也考虑过使用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
对象创建一个TCP服务器,该服务器实际上位于用户和http服务器之间。如前所述,替换所有请求和响应的第一行,就可以继续按原样使用http服务器。(您在一个非标准端口上创建一个内部http服务器,在另一个端口上创建网络服务器,然后在两者之间链接流,并使用一段代码来拦截来自请求用户的第一块数据和来自响应服务器的第一块数据。)
你所有的代码都是用Javascript编写的,而且都是流式的,(几乎)没有缓冲区。
编辑,我似乎有点误读了你的帖子。我看到你并没有试图实现Node.js shoutcast服务器,而是试图从中访问数据。net
对象应该仍然可以工作,但方式不太一样。
您需要使用net.connect
与指定的shoutcast服务器进行对话,并使用一个知道net.connect
流的新net
服务器在它和您的http.request()
之间进行代理。因此,它的工作方式如下:
+---------------+ +----------+ +-----------+ +----------------+
| http.request()|--->|net.Server|--->|net.connect|--->|SHOUTcast Server|
| |<---| |<---| |<---| |
+---------------+ +----------+ +-----------+ +----------------+
TCP JS TCP
这就是我的结构。
- 什么's本地node.js服务器和python简单http服务器之间的区别
- Angular js http get返回所有页面
- 当数据库中的某些内容发生变化时调用HTTP方法Meteor.js
- 在node-js路由中发出http请求
- http://oauth.googlecode.com/svn/code/javascript/oauth.js已关闭,
- Acync JS HTTP请求通知请求
- Node.js-查找http服务器正在侦听的端口
- 什么CSS/JS技巧驱动镜像反转http://com.google愚人节页面
- Angular.js-$http.get-使用文件中的缓存
- HTTP服务器在一段时间后停止(Node.js)
- Node.js HTTP/NET——连接和请求之间的区别
- Angular JS `$http`发送POST而不是GET
- 如何制作'http请求'在Node js中同步
- 在http服务单元测试中使用request-js时,chai.request不是一个函数
- Angular Provider/JS-如何访问'叔叔方法'从$http().then()
- 使用$http的angular js中的JSON数据-data.push()
- 分析angular.js中的JSONP$http.json()响应
- 我们如何在 lift 中使用 net.liftweb.http.js.JsCmds.Script 对象
- 火狐插件错误:在 resource://gre/modules/commonjs/http.js 找不到模块“路径”
- 循环嵌套$http js函数