Ignore header validation for HTTP requests in Node - javascript

I am building a proxy server which is supposed to forward data from an Shoutcast server to the client. Using request or even Node's http module this fails due to missing HTTP header:
{ [Error: Parse Error] bytesParsed: 0, code: 'HPE_INVALID_CONSTANT' }
The URL in question is: http://stream6.jungletrain.net:8000
Doing a header request with curl I was able to verify this:
$ curl -I http://stream6.jungletrain.net:8000
curl: (52) Empty reply from server
Yet the stream is working fine as tested with curl stream6.jungletrain.net:8000.
Is there a way to disable the header verification in request or Node's http? This is the code I am testing it on:
var express = require('express');
var request = require('request');
var app = express();
app.get('/', function (req, res) {
request('http://stream6.jungletrain.net:8000').pipe(res);
stream.pipe(res);
});
var server = app.listen(3000, function () {
console.log('Server started')
});
I am aware this can be achieved by rolling an implementation with net, there is also icecast-stack but subjectively seen it only implements half of the Stream interfaces properly.

Using icecast, I was able to get this working both using the on('data') event and by piping it to the Express response:
var express = require('express');
var app = express();
var icecast = require('icecast');
var url = 'http://stream6.jungletrain.net:8000';
app.get('/', function(req, res) {
icecast.get(url, function(icecastRes) {
console.error(icecastRes.headers);
icecastRes.on('metadata', function(metadata) {
var parsed = icecast.parse(metadata);
console.error(parsed);
});
icecastRes.on('data', function(chunk) {
console.log(chunk);
})
});
});
var server = app.listen(3000, function() {
console.log('Server started')
});
Or simply:
app.get('/', function(req, res) {
icecast.get(url).pipe(res);
});
Also of some note:
It appears the icecast package has been superseded by https://www.npmjs.com/package/icy

Related

How to call node api response in socket.io server

Scenario: Creating a Node API (GET) calling that API in socket.io Node server and calling this socket server in angular client.
What i have done: Created a node API for get request and post and created a socket server I tried to consume the app.
Issues: 1. I tried to consume the API but was unable to get the data in the socket server and 2. If it works, also how can i get the socket data on button click in angular application?
Note: I'm running Node API on 3000 server and running socket server on 3001.
Below is my code
Node api code runnning on 3000 port:
const express = require('express')
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express()
const port = 3000
let books = [{
"isbn": "9781593275846",
"title": "Eloquent JavaScript, Second Edition",
"author": "Marijn Haverbeke",
"publish_date": "2014-12-14",
"publisher": "No Starch Press",
"numOfPages": 472,
}];
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/book', (req, res) => {
const book = req.body;
// output the book to the console for debugging
console.log(book);
books.push(book);
res.send('Book is added to the database');
});
app.get('/book', (req, res) => {
res.json(books);
});
app.listen(port, () => console.log(`Hello world app listening on port ${port}!`));
Socket .io server running on 3001
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
const apiUrl="http://localhost:3000/book"
io.on('connection', function (socket) {
socket.on('getBanners', function(data){
request.get(apiUrl,function (error, response, body){
console.log(body)
socket.emit('result', {res:JSON.parse(body)})
})
});
});
http.listen(3001, function(){
console.log('listening on *:3001');
});
Note: Node API server --> socketio server (not client)
I wouldn't recommend going by that design you have.
Unless there is a very specific/important reason to have the socket.io server on a different port than the HTTP server, I would recommend having your socket.io server upgraded from the HTTP server itself.
eg.
In bin/www:
const { initSocketIOServer } = require('../socket-server');
const port = normalizePort(process.env.PORT || '3001');
app.set('port', port);
/**
* Create HTTP server.
*/
const server = http.createServer(app);
initSocketIOServer(server);
In socket.server.js
module.exports.initSocketServer = (server) => {
io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log('client connected');
socket.on('getBanners', (event) => {
// handle getBanners event here
});
});
};
However, going by your example, if you really need to make a request to the HTTP server to fetch data, you might want to use the HTTP library:
socket.on('getBanners', (event) => {
http.get({
hostname: 'localhost',
port: 3000,
path: '/book',
agent: false // Create a new agent just for this one request
}, (res) => {
// Do stuff with response, eg.
const socketResponse = processBooks(book);
socket.emit('result', socketResponse);
});
});
You can use any node package for requests like request https://github.com/request/request
here

Create a request waiting-list on NodeJs

I'd like to build a NodeJS server that responds to requests just one at the time.
Basically: by doing fetch('<domain>/request/<id> I want that untill the client received the data the other requests are queued. Is it possible?
An npm module like express-queue could work.
var express = require('express');
var queue = require('express-queue');
var app = express();
app.use(queue({
activeLimit: 1
}));
app.use("*", function(req, res, next) {
setTimeout(function() {
res.send("OK");
}, 2000);
});
app.listen(3000);

Node Express sever error : Can't render headers after they are sent to the client

I'm fairly new to this. I created a node-express server that runs locally. And I have a index.html under public\html folder. When I visit that index page, I got an error Can't render headers after they are sent to the client node server error. My understanding is that if the url is localhost:8080 plus /, index.html will be rendered? How do I solve this problem? Many thanks!
ps: The odd thing is that when I move index.html out from the "public" folder to the same directory with the node server.js, and change to app.get('/', function (req, res {fs.readFile('/index.html'.. the index.html seems to work fine.
var fs = require('fs');
var http = require('http');
var https = require('https');
var request = require('request');
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var path = require('path');
var express = require('express');
var app = express();
var certificate = fs.readFileSync( 'something.0.0.1.cert' );
var privateKey = fs.readFileSync('something.0.0.1.key');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
app.use(express.static(__dirname+'/public'));
app.get('/', function (req, res) {
fs.readFile('__dirname + '/public'+ '/html'+/index.html', function(error, content) {
if (error) {
res.writeHead(500);
res.end();
}
else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(content, 'utf-8');
}
});
res.send('Hello World');
});
https.createServer({
key: privateKey,
cert: certificate
}, app).listen(8080,'0.0.0.0');
You only get one response for every request. Your code shows res.send('Hello World');
change this to res.sendFile("__dirname + '/public/html/' + 'index.html' ")
You can remove the fs.readFile line too.
The reason fs.readFile('/index.html') works when you move to the same file as your server is because that line means to read a file called index.html from the same directory. But you want to send a response to a request, not just read files.
Check out the docs on res.sendFile in express
Try this:
app.get('/', function (req, res) {
res.sendFile(__dirname + '/public/html/'+'index.html');
});

How To Response To telegram bot Webhook Request? Same Request Are Coming Repeatedly

I am trying to make a telegram bot(for learning purpose) with nodejs using official telegram bot api. I set a webhook to heroku.
I am able to reply the request but after some time the same request come again after some time. Is it normal to get same request or I did not response to the coming request. when I call the getwebhookinfo method it shows pending_update_count but my code did response to all request coming from webhook.
I use this to reply to the coming requests
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var config = require('./lib/config');
var request = require('request');
var port = process.env.PORT || 3000;
var reply_url = "https://api.telegram.org/bot"+config.bot_token;
app.use(bodyParser.json());
app.get('/',function(req,res) {
res.send("Working");
request({
url: "https://api.telegram.org/bot"+config.bot_token+'/getMe',
json : true
}, (err,res,body)=>{
console.log(body);
});
});
app.post('/'+config.bot_token , (req,res)=>{
var body = req.body;
console.log(body);
console.log(body.message.entities);
request.post((reply_url+'/sendMessage'),{form:{chat_id:body.message.chat.id,text:"POST REPLY SUCCESS",reply_to_message_id:body.message.message_id}});
});
app.listen(port, () =>
{
console.log("Server is Started at - "+port);
});
try adding next in the callback function of the API function(req, res, next) and call next() function after you do res.status(201).send('Working").
Similar applies to other POST API ('/'+config.bot_token); in the success and error callback of /sendMessage API, call res.status().send() and then next();
Always call next() as a standard practice in working with express.js

Node.JS body parser issue

I'm attempting to send data from one machine to another in node.js.
I seem to be having some difficulty getting the parser to function correctly.
Here is my client and server code
Client.JS
var request = require('request');
request.post(
'http://192.168.1.225:3002',
{ form: { key: 'notyourmother' } },
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body)
}
}
);
Server.JS
var express = require('express');
var bodyParser = require('body-parser')
var app = express();
app.use(bodyParser.json());
app.post('/', function (req, res) {
res.send('POST request to the homepage');
console.log(req.body);
});
var server = app.listen(3002, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
When I run both snippets, the console outputs "{}".
What may I be doing incorrect?
Thank you!
You're using the wrong body parser on the server side. request is sending a application/x-www-form-urlencoded request payload with your current client code. So simply swap out bodyParser.json() with something like bodyParser.urlencoded({ extended: false }).

Categories