resource is not passed - node js - node.js

I'm trying to forward created resource (http) by callback to print result on web page using it
var http = require('http');
var net = require('net');
var fs = require ('fs');
var Path = require('path');
function LookDirs(server,port,callback){
http.createServer(function (req, res) {
res.setHeader("Content-Type", "text/html");
res.writeHead(200);
res.write('<html><head><title>Simple Server</title></head>');
res.write('<body> Test1');
callback('..', res);
res.end('\n</body</html>');
}).listen(port);
};
function ViewContent(dirPath){
fs.readdir(dirPath, function(err, entries){
for (var idx in entries){
var fullPath = Path.join(dirPath, entries[idx]);
(function(fullPath){
console.log(fullPath,idx);
res.write('abc');
})(fullPath);
}
})
}
LookDirs("Test 234", "1337", ViewContent);
And I keep getting
res.write('abc');
^
ReferenceError: res is not defined
I was sure that I have passed that resource during callback..

You can not access res from ViewContent.
This (req, res) responses from createServer stand for request and response. Here you can see more about it: https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/
const server = http.createServer((request, response) => {
// magic happens here!
});
Also you can not run callbacks on createServer prototype, but you can run on the listen method though.
var http = require('http');
var net = require('net');
var fs = require('fs');
var Path = require('path');
function LookDirs(server, port, callback) {
http.createServer(function (req, res) {
res.setHeader("Content-Type", "text/html");
res.writeHead(200);
res.write('<html><head><title>Simple Server</title></head>');
res.write('<body> Test1');
res.end('\n</body</html>');
}).listen(port, callback("./"));
};
function ViewContent(dirPath) {
fs.readdir(dirPath, function (err, entries) {
for (var idx in entries) {
var fullPath = Path.join(dirPath, entries[idx]);
// I can not access res from here, it has sent already.
console.log(fullPath)
}
})
}
LookDirs("Test 234", "1337", ViewContent);

Related

Why does NodeJs server return the same data 2 times?

I am currently learning NodeJs, thus I am building a simple NodeJs server which is called server.js
const http = require('http');
const port = 3000;
const fs = require('fs');
const sourceFile = './client/src/account.json';
var data = []
const service = http.createServer(
(req, res) => {
var receive = "";
var result = "";
req.on('data', (chunk)=>{ receive += chunk })
req.on('end', () =>{
data = fs.readFileSync(sourceFile, 'UTF8');
result = JSON.stringify(data);
var data_receive = receive;
console.log(data)
res.setHeader('Access-Control-Allow-Origin', '*');
res.write(data);
res.end()
})
})
service.listen(port)
Why does every time I request to the server, the console.log returns the data 2 times. It seems like it is looped somewhere.
This is my json file account.json
[
{
"id":"account_1",
"pass":"abc123",
"name":"Account 1"
}
]
Thank you for you help!
When performing the request from the browser, you will get an extra request for favicon.ico.
To avoid those double requests, handle the favicon.
if (req.url === '/favicon.ico') {
res.writeHead(200, { 'Content-Type': 'image/x-icon' });
console.log('favicon...');
return res.end();
}
/* The rest of your code */

Nodejs basic auth with https

I have a nodjs app running that uses basic auth with the password details in a file generated by htpasswd. This is working fine.
What I'd like to do is run it over https. I can get it working with https fine, but can't seem to work out how to get the two working together, https + basic auth.
This is for a browser going to the server and sending a variable in the url. I've found a few solutions but many seem to focus on the server doing a outbound call to something else with basic auth.
This is the basic auth one.
// Authentication module.
const auth = require('http-auth');
const basic = auth.basic({
realm: "REALM.",
file: __dirname + "/users.htpasswd"
});
const http = require('http');
const fs = require('fs');
var url = require('url');
const hostname = '0.0.0.0';
const port = 80;
const server = http.createServer(basic, (req, res) => {
var url_parts = url.parse(req.url, true);
var key = url_parts.query["name"];
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
fs.readFile(__dirname + '/basic.json', function (err, data) {
if (err) {
throw err;
}
table = JSON.parse(data.toString());
var value = table[key];
res.end(JSON.stringify({"group" : value}));
});
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
And this is the https bit without the basic auth.
const https = require('https');
const fs = require('fs');
var url = require('url');
const hostname = '0.0.0.0';
const port = 443;
const options = {
key: fs.readFileSync('star.pkey'),
cert: fs.readFileSync('star.pem'),
};
const server = https.createServer(options, (req, res) => {
var url_parts = url.parse(req.url, true);
var key = url_parts.query["name"];
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
fs.readFile(__dirname + '/basic.json', function (err, data) {
if (err) {
throw err;
}
table = JSON.parse(data.toString());
var value = table[key];
res.end(JSON.stringify({"group" : value}));
});
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Any help appreciated.

Node JS require('path')

I have this problem with the path module. When I try to use "path.join..." inside the request handler, I get the error message
TypeError: Cannot read property 'join' of undefined
However, I can fix it by loading the module inside the body of the requestHandler (I commented it out in the code).
Could you explain why it fails and why the "fix" works and what is the most common way to handle this?
var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
var port = 3000;
var requestHandler = (request, response) => {
//path = require('path');
var uri = url.parse(request.url).pathname;
var filename = path.join(process.cwd(), uri);
var path = process.cwd();
var buffer = fs.readFileSync(path + "/someSite.html");
response.end(buffer);
};
var server = http.createServer(requestHandler);
server.listen(port, (err) => {
if (err) {
return console.log('sum ting wong', err);
}
console.log('server is listening on ${port}');
});
It's broken because you're reassigning to path inside your request handler w/ var path = process.cwd().
The var declaration is being hoisted, which means your implementation is equivalent to:
var requestHandler = (request, response) => {
var path; // hoisted!
var uri = url.parse(request.url).pathname;
var filename = path.join(process.cwd(), uri);
path = process.cwd();
// ...
};

How do I get POST data with node.js?

How do I get the caller ID from twilio? I've tried many different ways to get the POST data but it isn't working.
var twilio = require('./node_modules/twilio/index'),
http = require('http'),
express = require('express');
http.createServer(function (req, res) {
/*
var app = express();
app.use(express.urlencoded());
app.post('/call',function (req, res) {
*/
var name, from;
// if (req.method=='POST')
// req.on('From', function (data) {from = data;});
try {
from = req.param('From');
// from = req.body.from;
}
catch (err)
{
console.log("No Caller ID");
}
console.log("Number: " + from);
//Some code goes here..
res.end(resp.toString());
}).listen(8080);
It's throwing me the error every single time at the try catch statement (always null).
I'm trying to get the caller ID of an incoming text message.
Things in comments are the different approaches I tried.
The thrown error is:
Error TypeError: Object #IncomingMessage> has no method 'param'
I guess that this will do the trick:
var qs = require('querystring');
var processRequest = function(req, callback) {
var body = '';
req.on('data', function (data) {
body += data;
});
req.on('end', function () {
callback(qs.parse(body));
});
}
var http = require('http');
http.createServer(function (req, res) {
processRequest(req, function(data) {
// data
});
}).listen(9000, "127.0.0.1");

isn't res in scope? (node.js)

var http = require('http');
var url= require('url');
var util= require('util');
var fs = require('fs');
var body_404="<html><body><center>404 error</center></body></html>";
http.createServer(function (req,res) {
var what = url.parse("http://127.0.0.1:1235"+req.url);
var pathname = what.pathname;
switch(pathname) {
case "/":
pathname="/www/index.html";
default:
res.writeHead(200, {'Content-type' : 'text/html'});
ret = res;
fs.stat("."+pathname, function (err, stat) {
if(err)
res.write(body_404);
else
res.write(fs.readFileSync("."+pathname));
});
res.end();
break;
}
}).listen(1235, '127.0.0.1');
I am wondering why the write method inside the fs.stat callback does not actually write anything, it seems, to the client. I believe res is in scope.
You're calling res.end before res.write. Therefore, nothing gets written out. Move the call to res.end into the stat handler:
var http = require('http');
var url= require('url');
var util= require('util');
var fs = require('fs');
var path = require('path');
var body_404="<html><body><center>404 error</center></body></html>";
var rootPath = path.abspath(".");
http.createServer(function (req,res) {
var what = url.parse("http://127.0.0.1:1235"+req.url);
var pathname = what.pathname;
var buffer;
switch(pathname) {
case "/":
pathname="/www/index.html";
default:
var filename = path.join(rootPath, pathname);
if (filename.indexOf(rootPath) !== 0) {
res.writeHead(400, {'Content-type': 'text/plain'});
res.write('Directory traversal attack averted.');
res.end();
return;
}
fs.readFile(function (err, content) {
if(err) {
res.writeHead(404, {'Content-type' : 'text/html'});
res.write(body_404);
} else {
res.writeHead(200, {'Content-type' : 'text/html'});
res.write(content);
}
res.end();
});
break;
}
}).listen(1235, '127.0.0.1');
Also note that your original code is vulnerable to directory traversal attacks, and suffers from a race condition between os.stat and os.readFileSync.

Resources