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.
Related
I just set up my first node HTTP server, and I am trying to get the response data from a JSON file in my application. When I declare a JSON object in the server.js file, all works well.
data = "{"sample json" : "this is a test"}";
But I want to replace data with a static JSON file at data/sample.json
Here's an example in my server.js file
const http = require("http");
const hostname = "localhost";
const port = 3000;
const server = http.createServer(function(req, res) {
data = // this is where I want to get the JSON data from data/sample.json
res.writeHead(200, {'Content-Type': 'application/json'});
res.write(data);
res.end();
});
Solved with fs.readFile()
const http = require("http");
const hostname = "localhost";
const port = 3000;
const fs = require('fs');
const server = http.createServer(function(req, res) {
filePath = './data/sample.json';
if (req.path == '/data/sample.json') {
fs.readFile(filePath, function(error, content) {
if (error) {
if (error.code == 'ENOENT') {
response.writeHead(404);
response.end(error.code);
}
else {
response.writeHead(500);
response.end(error.code);
}
}
else {
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(content);
}
});
}
else {
response.writeHead(404);
response.end('restricted path');
}
});
In case someone else tumbles upon this question. The answer above has ton of typos and errors and incomplete. Here is a working solution.
const http = require("http");
const hostname = "localhost";
const fs = require('fs');
const port = 8080;
const server = http.createServer(function(req, res) {
filePath = './data/sample.json';
if (req.url == '/api/data') {
fs.readFile(filePath, function(error, content) {
if (error) {
if (error.code == 'ENOENT') {
res.writeHead(404);
res.end(error.code);
}
else {
res.writeHead(500);
res.end(error.code);
}
}
else {
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(content);
}
});
}
else {
res.writeHead(404);
res.end('404 NOT FOUND');
}
});
server.listen(port, hostname, () => {
console.log('Server started on port ', port);
});
I cant understand how and where to use response.end(). i get it working when loading only single response but when i try to load (say) two html files (index and form in my case) , the server does not load anything.
if i put res.end() after loading the index html it works but server closes.
var http = require('http');
var formidable = require('formidable');
var url=require('url');
var path=require('path');
var fs=require('fs');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
filepath=path.join(__dirname,'index.html');
fs.readFile(filepath,null,function(err,data){
if(err){
res.writeHead(404);
res.write(err+" Error");
}
else{
res.write(data);
}
res.end();
});
if (req.url == '/fileupload') {
var form = new formidable.IncomingForm();
form.parse(req, function () {
res.write('File uploaded');
res.end();
});
} else {
var q=url.parse(req.url,true);
var filename=path.join(__dirname,q.pathname);
console.log(filename);
fs.readFile(filename,function(err,data){
if (err) {
res.writeHead(404);
res.write(err+"404 Not Found");
}
else{
res.write(data);
}
res.end();
})
}
}).listen(8080);
Other tips on improving code is much appreciated :)
var http = require('http');
var formidable = require('formidable');
var url = require('url');
var path = require('path');
var fs = require('fs');
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/html' });
if (req.url == '/fileupload') {
var form = new formidable.IncomingForm();
form.parse(req, function () {
res.write('File uploaded');
res.end();
});
} else if (req.url.length > 1) {
var q = url.parse(req.url, true);
var filename = path.join(__dirname, q.pathname);
console.log(filename);
fs.readFile(filename, function (err, data) {
if (err) {
res.writeHead(404);
res.write(err + "404 Not Found");
}
else {
res.write(data);
}
res.end();
})
} else {
filepath = path.join(__dirname, 'index.html');
fs.readFile(filepath, null, function (err, data) {
if (err) {
res.writeHead(404);
res.write(err + " Error");
}
else {
res.write(data);
}
res.end();
});
}
}).listen(8080);
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);
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>
Hello I am new in nodeJS, I am trying to broadcast message when any new request arrive.
I am trying ajax calling and send ttype variable and broadcast to all browsers but My problem is when I request arrive
socket.emit('date', {'date': ttype});
not working. but when I checked it on my nodeJs console it's show tyype and it's value. here is my code
var http = require('http');
var url = require('url');
var fs = require('fs');
var server;
var ttype = "";
server = http.createServer(function(req, res){
// your normal server code
var path = url.parse(req.url).pathname;
var queryObject = url.parse(req.url,true).query;
ttype = queryObject.type;
switch (path){
case '/':
fs.readFile(__dirname + path + "test.html", function(err, data){
if (err){
console.log('error');
//return send404(res);
}
res.writeHead(200, {'Content-Type': path == 'json.js' ? 'text/javascript' : 'text/html'});
res.write(data, 'utf8');
res.end();
sendMessage(ttype);
});
break;
case '/test.html':
fs.readFile(__dirname + path, function(err, data){
if (err){
return send404(res);
}
res.writeHead(200, {'Content-Type': path == 'json.js' ? 'text/javascript' : 'text/html'});
res.write(data, 'utf8');
res.end();
});
break;
default: send404(res);
}
}),
send404 = function(res){
res.writeHead(404);
res.write('404');
res.end();
};
server.listen(8076);
sendMessage = function(ttype){
var iio = require('socket.io').listen(server);
iio.sockets.on('connection', function(socket){
socket.emit('date', {'date': ttype});
console.log('in side connection');
});
}
// use socket.io
var io = require('socket.io').listen(server);
// define interactions with client
io.sockets.on('connection', function(socket,data){
socket.emit('date', {'date': ttype});
setInterval(function(){
//socket.emit('date', {'date': new Date()});
}, 5000);
//recieve client data
socket.on('client_data', function(data){
process.stdout.write(data.letter);
});
});
So if you'd like to let all browsers know that there is a new request by sending them ttype. All you would have to do is change your sendMessage function to:
sendMessage = function(ttype){
io.emit('date', {'date': ttype});
console.log('in side connection');
}