NodeJS Request: How do I get `response.statusCode` when piping? - node.js

Sorry guys, I'm kind of lost. How can I console.log response.statusCode when piping?
var express = require('express');
var path = require('path');
var request = require('request');
var fs = require('fs');
var app = express();
var port = 8000;
var destination = fs.createWriteStream('./downloads/google.html');
var url = "http://www.google.com/";
request(url).pipe(destination)
.on("finish", function() {
console.log("done");
console.log(response.statusCode); // <<<<<<<<<<<<<<<<<<<<<<<<<<<< this
})
.on("error", function(err){
console.log(err);
});
app.listen(port, function(){
console.log('running server on ' + port);
});

You need to catch the response event from request. It won't be in the finished event from the pipe. You should also consider catching errors before the pipe. This is where you'll catch network errors. After the pipe you'll catch file errors.
request(url)
.on('response', function(response) {
console.log(response.statusCode) // <--- Here 200
})
.on("error", function(err){
console.log("Problem reaching URL: ", err);
})
.pipe(destination)
.on("finish", function(response) {
console.log("done");
})
.on("error", function(err){
console.log("Problem writing file: ", err);
});

Related

Vanilla Node js Server, Css not loaded [duplicate]

This question already has an answer here:
Link index.html client.js and server.js
(1 answer)
Closed 10 months ago.
I am trying to write a web server application for my Frontend.
The structure is for the fronted files is :
Backend
server.js
Fronted
Index
Javascript
index.js
style.css
index.html (it is outside of Frontend folder)
The code for server.js is:
const fs = require('fs');
const port = 5000;
const server = http.createServer(function (request, response) {
fs.readFile('../Frontend/index.html', function (error, data) {
response.setHeader( "Content-Type", "text/html");
if (error) {
response.writeHead(404);
response.write('Error: File Not Found');
} else {
response.write(data);
}
response.end();
})
})
server.listen(port, function (error) {
if (error) {
console.log('Something went wrong ', error);
} else {
console.log('Server is listening on port ' + port);
}
});
When I try to access localhost:5000 the HTML code shows, but without CSS, js or images, but when I am looking in the console at the network all the files are there (index.js, style.css, the images);
You can achieve the results you want as follows:
const fs = require('fs');
const port = 5000;
const http = require('http');
const server = http.createServer( function (request, response) {
let filePath = '.'+request.url; //assumes your static files are
// placed in the root directory
if(request.url ==='/' ||request.url==='/index.html'){
filePath = './index.html';
fs.readFile(filePath, function (error, data) {
response.setHeader('Content-Type', 'text/html');;
if (error) {
response.writeHead(404);
response.write('Error: File Not Found');
}
response.end(data,'utf-8');
})
} else if(request.url==='/index.css'){
filePath = './index.css';
fs.readFile(filePath, function (error, data) {
response.setHeader('Content-Type', 'text/css');;
if (error) {
response.writeHead(404);
response.write('Error: File Not Found');
}
response.end(data,'utf-8');
})
} //maybe some additional else if for image and so on or you can improve
//this logic but anyway this code gives you the right direction
})
server.listen(port, function (error) {
if (error) {
console.log('Something went wrong ', error);
} else {
console.log('Server is listening on port ' + port);
}
});

ERR_HTTP_HEADERS_SENT node js socket connection

I am building an API that uses socket connection to interact with a server backend built in C#. This is what I have so far
const request = require('request');
const express = require('express');
const app = express();
var server = require('http').createServer(app);
var cors = require("cors");
app.use(cors());
const net = require('net');
const client = new net.Socket();
const stringToJson=require('./stringToJson')
const port = process.env.PORT;
const host = process.env.HOST;
client.keepAlive=true
client.on('close', function() {
console.log('Connection closed');
});
app.get('/getScores',function (req,res) {
let dataSend=''
client.on('data', function (data) {
console.log('Server Says : ' + data);
if(data!='ANALYSIS-ERROR'){
dataSend=stringToJson.stringToJson(data)
}
else{
dataSend=stringToJson.stringToJson('0:0.0:0.0:0.0:0:0:0.0:0.0:0.0:0.0:0.0:0:0.0:0.0:0.0:0.0:0.0:0:0.0:0.0:0.0:0.0:0.0:0:0.0:0.0:0.0:0.0:0.0')
}
client.destroy()
return res.send(dataSend)
});
client.connect(port, host, function () {
client.write(`GENERAL-ANALYSIS|${req.query.id}|${req.query.website}|`)
return
});
return
})
app.get('/getPlace',function (req,res) {
console.log(req.query)
request(
{ url: `https://maps.googleapis.com/maps/api/place/textsearch/json?query=${req.query.name}+in+${req.query.city}&key=${process.env.API_KEY}` },
(error, response, body) => {
if (error || response.statusCode !== 200) {
return res.status(500).json({ type: 'error', message: error.message });
}
return res.json(JSON.parse(body));
}
)
})
//TODO ADD 404 500 PAGES
app.use((req, res, next) => {
res.status(404).send("Sorry can't find that!");
});
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
server.listen(9000, () => {
console.log(`App running at http://localhost:9000`);
});
Basically it creates a connection with the server and listens for some data to be sent back. Then processes the string and sends it to the React frontend. The api calls are made by the frontend using axios
It works but if you refresh the page it throws this error Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
How do I fix this?
Try setting the headers as found in the documentation request.setHeader(name, value)
request.setHeader('Content-Type', 'application/json');

How to upload a file in NodeJS without Express

I'm trying to pick up a file from a form and save it to myself on disk in any folder. I would like to do it by sockets, but I do not know how to handle it. Can someone help me?
This is my code:
main.js
var http = require('http');
var fs = require('fs');
var io = require('socket.io');
var path = require('path');
var server = http.createServer(function (req, res) {
fs.readFile(__dirname + '/index.html', function (err, data) {
if (err) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write("Not Found");
res.end();
} else {
res.write(data, 'utf8');
res.end();
}
});
}).listen(8000);
var listener = io.listen(server);
listener.sockets.on('connection', function (socket) {
console.log("Connected");
socket.on('disconnect', function () {
console.log("Disconnect");
});
socket.on('form.message', function (data) {
// here to handle the file ??
socket.emit('new.message', {msg: data});
});
});
index.html(client)
<script>
$(function () {
var socket = io.connect();
var $messageForm = $('#messageForm');
var $file = $('#file');
var $outputFile = $('#outputFile');
var obj = {
file: $file.val(),
};
e.preventDefault();
console.log(obj);
socket.emit('form.message', obj);
$file.val('');
socket.on('new.message', function (data) {
$outputFile.append('<div class="well">' + data.msg.file + '</div>');
});
});
</script>

Extract function outside of main app.js

I'm fairly new to nodejs, and in wanting to keep the code neat and clean, I tried to extract a function to a different file, and then require it from my main app.
I'm facing a problem that this function includes socket-io data streaming and it uses the http module that uses my express app
This is the main app, and I want to move the content of getDetails to a seperate file:
const express = require('express');
const app = express();
const spawn = require('child_process').spawn;
const execFile = require('child_process').execFile;
const server = require('http').Server(app);
const io = require('socket.io')(server);
// Set router
const router = express.Router();
// fix body of requests
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
router.get('/getDetails', (req, res) => {
const qry = req.query;
if (qry.func === 'tail') {
const tail = spawn('ssh', ['root#' + qry.srv, qry.script, qry.func, qry.serv]);
io.on('connection', function (socket) {
tail.stdout.on('data', function (data) {
socket.emit('newLine', {line: data.toString('utf8').replace(/\n/g, '<br>')});
});
tail.on('close', (code) => {
console.log('child process exited with code', code);
});
tail.stderr.on('data', (data) => {
console.log('There are some errors:', data.toString('utf8'));
socket.emit('newLine', {line: data.toString('utf8')});
});
});
res.sendStatus(200);
}
else {
execFile('ssh', ['root#' + qry.srv, qry.script, qry.func, qry.serv], {timeout: 5000}, (error, stdout, stderr) => {
if (error) {
console.error('stderr', error);
return res.status(500).send({stderr: stderr, error: error});
}
return res.status(200).send({stdout: stdout.toString('utf8')});
});
}
});
app.use('/', router);
server.listen(port, function () {
console.log('The magic happens on localhost:' + port);
});
Now I can module.exports everything on my seperate file but do I need to also require express, and http again?
And should I move the server.listen to the seperate file?
server.js
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const route = require('./route');
// fix body of requests
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json())
app.set('socketio', io);
app.use('/',route);
server.listen(port, function () {
console.log('The magic happens on localhost:' + port);
});
route.js
const express = require('express');
const router = express.Router();
const Controller = require('./controller');
router.post('/register',Controller.getDetails);
module.exports=router;
controller.js
const spawn = require('child_process').spawn;
const execFile = require('child_process').execFile;
const controller = {
getDetails : (req,res)=>{
// now use socket.io in your controller file
var io = req.app.get('socketio');
const qry = req.query;
if (qry.func === 'tail') {
const tail = spawn('ssh', ['root#' + qry.srv, qry.script, qry.func, qry.serv]);
io.on('connection', function (socket) {
tail.stdout.on('data', function (data) {
socket.emit('newLine', {line: data.toString('utf8').replace(/\n/g, '<br>')});
});
tail.on('close', (code) => {
console.log('child process exited with code', code);
});
tail.stderr.on('data', (data) => {
console.log('There are some errors:', data.toString('utf8'));
socket.emit('newLine', {line: data.toString('utf8')});
});
});
res.sendStatus(200);
}
else {
execFile('ssh', ['root#' + qry.srv, qry.script, qry.func, qry.serv], {timeout: 5000}, (error, stdout, stderr) => {
if (error) {
console.error('stderr', error);
return res.status(500).send({stderr: stderr, error: error});
}
return res.status(200).send({stdout: stdout.toString('utf8')});
});
}
}
}
module.exports=controller;

Error: "tunneling socket could not be established, cause=getaddrinfo ENOTFOUND" code: 'ECONNRESET'

I am using node wget to download files from URL and I am getting this error.
If I use simple wget command to download files it working fine, but I want download file from node module
here is my code
var wget = require('wget');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, response) {
var options = {
protocol: 'https',
host: 'raw.github.com',
path: '/Fyrd/caniuse/master/data.json',
proxy: 'http://host:port',
method: 'GET'
};
var req = wget.request(options, function(res) {
var content = '';
if (res.statusCode === 200) {
res.on('error', function(err) {
console.log(err);
});
res.on('data', function(chunk) {
content += chunk;
});
res.on('end', function() {
console.log(content);
});
} else {
console.log('Server respond ' + res.statusCode);
}
});
req.end();
req.on('error', function(err) {
console.log(err);
});
response.render('index', { title: 'Express' });
});
module.exports = router;
I stumble upon this question. This is probably caused by the proxy not supporting HTTPS. Try a proxy that supports HTTPS and the problem should be solved.

Resources