admin管理员组文章数量:1332377
I am using Node's basic http.request()
function without problem on normal HTTP servers. I need to use http.request()
(or similar) with SHOUTcast servers. The SHOUTcast "protocol" is fully patible with HTTP, except for one detail... the first response line.
Normal HTTP servers respond with:
HTTP/1.1 200 OK
SHOUTcast servers respond with:
ICY 200 OK
Again, the rest of the protocol is the same. The only difference is HTTP/1.x
vs. ICY
.
I would like to extend, subclass, or somehow modify Node's http.request()
function so that I can make it work with SHOUTcast servers. Connecting to SHOUTcast with Node has been done before, but only by re-inventing the entire wheel. I'd rather not do that for what amounts to be a minor protocol difference.
My Question: Is there a way to do one of the following?
Extend or override the relevant parts of Node's HTTP parser. (I doubt this is possible, as it seems the parser is native code.)
Create my own bit of code that parses the relevant parts of HTTP, but reuses as many existing Node ponents for HTTP as possible.
Create a simple internal proxy (or somehow relay data) so that I can modify that first server response line prior to it reaching Node's HTTP parser.
Something else?
I have also considered using Shred, but it does not offer an option to stream the response. (It waits for the entire server response to be plete before firing an event, which won't work for streaming servers where the data can run indefinitely.) Along those same lines, I tried Request, but it uses Node's own HTTP parser, so I get the same parse errors as I would with the native HTTP client.
I am using Node's basic http.request()
function without problem on normal HTTP servers. I need to use http.request()
(or similar) with SHOUTcast servers. The SHOUTcast "protocol" is fully patible with HTTP, except for one detail... the first response line.
Normal HTTP servers respond with:
HTTP/1.1 200 OK
SHOUTcast servers respond with:
ICY 200 OK
Again, the rest of the protocol is the same. The only difference is HTTP/1.x
vs. ICY
.
I would like to extend, subclass, or somehow modify Node's http.request()
function so that I can make it work with SHOUTcast servers. Connecting to SHOUTcast with Node has been done before, but only by re-inventing the entire wheel. I'd rather not do that for what amounts to be a minor protocol difference.
My Question: Is there a way to do one of the following?
Extend or override the relevant parts of Node's HTTP parser. (I doubt this is possible, as it seems the parser is native code.)
Create my own bit of code that parses the relevant parts of HTTP, but reuses as many existing Node ponents for HTTP as possible.
Create a simple internal proxy (or somehow relay data) so that I can modify that first server response line prior to it reaching Node's HTTP parser.
Something else?
I have also considered using Shred, but it does not offer an option to stream the response. (It waits for the entire server response to be plete before firing an event, which won't work for streaming servers where the data can run indefinitely.) Along those same lines, I tried Request, but it uses Node's own HTTP parser, so I get the same parse errors as I would with the native HTTP client.
Share Improve this question edited Nov 27, 2018 at 0:47 Brad asked Mar 26, 2012 at 23:20 BradBrad 164k56 gold badges377 silver badges553 bronze badges 4- 1 Wow, SHOUTcast looks really bad... – seppo0010 Commented Mar 27, 2012 at 0:36
- 1 It was made in a simpler time. :-D – Brad Commented Mar 27, 2012 at 0:38
- "fully patible"... Except for the most popular response code. – Joe Commented Mar 27, 2012 at 2:11
-
1
@Joe, The status codes (
200 OK
, etc) are the same. The only difference is the protocol identification/version. – Brad Commented Mar 27, 2012 at 2:15
2 Answers
Reset to default 5I've e up with another way to do this, similar to the internal proxy, but without the extra connection. It seems that it is possible to override the internally used socket for the HTTP client. When this is done, it is easy to hook in and modify data before passing it off to the original internal socket ondata
function.
Usage
var httpicy = new HttpIcyClient();
httpicy.request(/* your normal request parameters here */);
Source
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 . Create a simple internal proxy
Bang. You got it.
Use the Node.js net
object to create a TCP server that actually sits between the user and the http server. Replace the first line of all requests and responses as you've described, and you can continue to use http server essentially as-is. (You create an internal http server on a non-standard port, the net server on another port, then chain up streams between the two, with a bit of code to intercept the first chunk of data from the requesting user, and the first chunk of data from the responding server.)
All of your code in Javascript and it's all streaming with (almost) no bufferbloat.
EDIT, it seems I misread your post slightly. I see that you're not trying to implement a Node.js shoutcast server, but trying to access data from it. The net
object should still work, but not quite in the same way.
You'll need to use net.connect
to talk to the specified shoutcast server, and use a new net
server that knows about the net.connect
stream to proxy between it and your http.request()
. So, it would work like:
+---------------+ +----------+ +-----------+ +----------------+
| http.request()|--->|net.Server|--->|net.connect|--->|SHOUTcast Server|
| |<---| |<---| |<---| |
+---------------+ +----------+ +-----------+ +----------------+
TCP JS TCP
That's about how I'd structure it.
本文标签: javascriptOverriding Nodejs HTTP parserStack Overflow
版权声明:本文标题:javascript - Overriding Node.js HTTP parser - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742305512a2449834.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论