Obtaining 'undefined ' from response.write(string) is JS - javascript

I'm creating a http server with JS and Node JS.
It consists of a form where you can input text that should be the pathname of a file. Once you press on submit button, it should show on webpage the content of that file.
I read the content of the file with function file(pathname) and return it as a String. Then I try to to show the content on webpage with:
response.write('File content: '+ string); but it shows 'File content: undefined'
I think my problem is on the response.write(), because when I use console.log() to show the file content is working correctly.
What I'm doing wrong?
Here is the code when you press on submit:
if(url_parts.pathname == '/submit') { //Processing the form content, if the relative URL is '/ submit'
var pathname=url_parts.query['name']; //Read the contents of the field (form) named 'name'
var string = file(pathname); //file(pathname) returns the content of the file.
console.log("Creating a response header")
response.writeHead(200, {"Content-Type": "text/plain; charset=utf-8"}); //Creating an answer header - we inform the browser that the body of the answer will be plain text
console.log("Creating the body of the response")
response.write('File content: '+ string); // Write content of the file
response.end(); //The end of the response - send it to the browser
console.log("Sending a response")
}
ALL CODE:
var http = require("http");
var url = require("url");
var fs = require('fs');
function file(pathname){
fs.stat(pathname, function(err, stats) {
console.log("----------------------------------------------------------");
console.log("FILE OPERATION RESULT:");
console.log("----------------------------------------------------------");
if (err){ console.log("'" + pathname + "' is not a directory or a file");
} else if(stats.isDirectory()){
console.log("Is a directory");
} else if(stats.isFile()){
console.log("Is a file");
console.log("Reading content...");
console.log("---------------");
fs.readFile(pathname, function (err, data) {
fileContent=data.toString('utf8');
console.log(fileContent);
return fileContent;
});
}
});
}
http.createServer(function(request, response) {
console.log("--------------------------------------")
console.log("The relative URL of the current request: "+request.url+"\n")
var url_parts = url.parse(request.url,true); //parsing (relative) URL
if(url_parts.pathname == '/submit') { //Processing the form content, if the relative URL is '/ submit'
var pathname=url_parts.query['name']; //Read the contents of the field (form) named 'name'
var string = file(pathname);
console.log("Creating a response header")
response.writeHead(200, {"Content-Type": "text/plain; charset=utf-8"}); //Creating an answer header - we inform the browser that the body of the answer will be plain text
console.log("Creating the body of the response")
response.write('File content: '+ string); //WRITE FILECONTENT IF PATHNAME IS A FILE
response.end(); //The end of the response - send it to the browser
console.log("Sending a response")
}
else { //Generating the form
console.log("Creating a response header")
response.writeHead(200, {"Content-Type": "text/html; charset=utf-8"}); //Creating a repsonse header - we inform the browser that the body of the response will be HTML text
//and now we put an HTML form in the body of the answer
console.log("Creating a response body")
response.write('<form method="GET" action="/submit">');
response.write('<label for="name">Write pathname</label>');
response.write('<input name="name">');
response.write('<br>');
response.write('<input type="submit">');
response.write('<input type="reset">');
response.write('</form>');
response.end(); //The end of the response - send it to the browser
console.log("Sending a response")
}
}).listen(8080);
console.log("The server was started on port 8080");
console.log("To end the server, press 'CTRL + C'");

Related

NodeJS - The Node Beginner Book - show function not getting called

I am following the guide in the Node Beginner Book and have managed to get all the way through to the last section, Handling file uploads. This book focuses on JavaScript calling methods and using request and response with very little HTML included only as strings when necessary.
All my console.log statements are showing me the correct file path. But instead of displaying the image I get the following HTML line:
I think the problem is in this line in requestHandlers.js:
response.write("<img src='/show' />");
It is supposed to be calling the show function at the bottom of requestHandlers.js. Look at the Console output at the bottom of this post and you can see that execution never gets into the show function. Source code and Console output is below:
index.js
var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");
var handle = {};
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;
handle["/show"] = requestHandlers.show;
server.start(router.route, handle);
server.js
var http = require("http");
var url = require("url");
function start(route, handle) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
route(handle, pathname, response, request);
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
router.js
function route(handle, pathname, response, request) {
console.log("About to route a request for " + pathname);
if (typeof handle[pathname] === 'function') {
handle[pathname](response, request);
} else {
console.log("No request handler found for " + pathname);
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not found");
response.end();
}
}
exports.route = route;
requestHandlers.js
var querystring = require("querystring"),
fs = require("fs"),
formidable = require("formidable");
var path = require('path');
var file = path.join(__dirname, 'tmp', "test.png");
function start(response) {
console.log("Request handler 'start' was called.");
var body = '<html>'+
'<head>'+
'<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'+
'</head>'+
'<body>'+
'<form action="/upload" enctype="multipart/form-data" method="post">'+
'<input type="file" name="upload" multiple="multiple"/>'+
'<input type="submit" value="Upload file"/>'+
'</form>'+
'</body>'+
'</html>';
response.writeHead(200, {"Content-Type": "text/html"});
response.write(body);
response.end();
}
function upload(response, request) {
console.log("Request handler 'upload' was called.");
var form = new formidable.IncomingForm();
console.log("about to parse");
form.parse(request, function(error, fields, files) {
console.log("parsing done");
console.log("File = "+file);
fs.rename(files.upload.path, file, function (error) {
if(error) {
console.log("error");
fs.unlink(file);
console.log(file);
fs.rename(files.upload.path, file);
console.log(file);
}
});
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("received image:<br/>");
response.write("<img src='/show' />");
response.end();
});
}
function show(response) {
console.log("Request handler 'show' was called.");
response.writeHead(200, {"Content-Type": "image/png"});
fs.createReadStream(file).pipe(response);
}
exports.start = start;
exports.upload = upload;
exports.show = show;
Console output
C:\Users\pdl\Projects\TestSeparateJS>node index.js
Server has started.
Request for / received.
About to route a request for /
Request handler 'start' was called.
Request for /upload received.
About to route a request for /upload
Request handler 'upload' was called.
about to parse
parsing done
File = C:\Users\pdl\Projects\TestSeparateJS\tmp\test.png
error
C:\Users\pdl\Projects\TestSeparateJS\tmp\test.png
C:\Users\pdl\Projects\TestSeparateJS\tmp\test.png
You're sending the content as plaintext instead of HTML. So the browser never runs it as HTML. That's why you see the <img> text instead of an <img> tag being generated.
In your upload function change this:
response.writeHead(200, {"Content-Type": "text/plain"});
to this:
response.writeHead(200, {"Content-Type": "text/html"});
When using a newer version of node.js, you also might like to change the code files.upload.path into files.upload.filepath

Using eval in Node.js to send requests to the server using submit button and input text

So here is what I'm trying to achieve!
I want to create a very simple Node application where I can make use of the eval function by creating a input text box and a submit button. I want to be able to write things in the text box and when hitting submit to use the eval function to send this parameter to the server.
So if I write while(true) in the text box this should cause a DoS attack to the server, due to the eval vulnerability.
Here is my code so far (fix doesn't work properly)
var http = require("http");
var server = http.createServer(function(request, res) {
res.writeHead(200, {"Content-Type": "text/html"});
res.write("<html>");
res.write("<head>");
res.write("<title>Hello World Page</title>");
res.write("</head>");
res.write("<body>");
res.write("Enter Some text");
res.write('<input type="text" name="fname">');
res.write('<input type="submit" value="Submit")');
var parameter = eval(req.body.fname);
res.send(parameter);
res.write("</body>");
res.write("</html>");
res.end();
});
server.listen(1337);
console.log("Server is listening");
Any ideas on how to make this work?
First - here is a good post on the topic: Accessing the HTTP message body (e.g. POST data) in node.js
A couple of minor changes to your html:
I've added a form element with an action and method set to POST. You could use GET as well to avoid some of the req.on(...) logic below.
added closing bracket for the submit button - you had a typo with a paren
When reading posted form data, you will need to read all of the data coming in until it is complete. The req parameter is an event emitter so you would use:
req.on('data', function(chunk) {...}
req.on('end', function() {...}
To buffer up the incoming data then act on it when the end of the request is reached.
The form data is encoded, so you will need to parse it using the querystring module.
I've also added just enough error checking (and fixed a few naming bugs) to get the code to function at a basic level.
Code:
var http = require("http");
var querystring = require('querystring');
var util = require('util');
var server = http.createServer(function(req, res) {
var body = "";
req.on('data', function (chunk) {
body += chunk;
});
req.on('end', function () {
console.log('POSTed: ' + body);
body = querystring.parse(body);
console.log('decoded: ' + util.inspect(body));
res.writeHead(200, {"Content-Type": "text/html"});
res.write("<html>");
res.write("<head>");
res.write("<title>Hello World Page</title>");
res.write("</head>");
res.write("<body>");
res.write("Enter Some text");
res.write('<form action="/" method="post">');
res.write('<input type="text" name="fname">');
res.write('<input type="submit" value="Submit">');
res.write('</form>');
if(body.fname) {
var parameter = eval(body.fname);
console.log(util.inspect(parameter));
if(parameter) {
res.write(parameter);
}
}
res.write("</body>");
res.write("</html>");
res.end();
});
});
server.listen(1337);
console.log("Server is listening");

NodeJs/Formidable, Uploading Images error

I am trying to make an Image/File upload form using NodeJs and Formidable. I'm not using express. Just formidable. But anyways, I tried the most common scripts with formidable, and none have worked.My code is basically exactly the same as the one from this tutorial: http://justinkjchang.wordpress.com/2013/11/08/image-uploader-using-node-js/
There are a lot of these tutorials around, and i've seen almost the exact same thing in some books, or videos, and they all seem to work, except mines. I have Installed formidable, and I have the latest version of both that, and Node. I'm on a mac too. When I try to upload, it'll go through the form.parse and everything, but when it tries to write the file, it throws this error:
/Users/USER/Documents/Node/requestHandlers.js:42
fs.rename(files.upload.path, "/tmp/test.png", function (error) {
^
TypeError: Cannot read property 'path' of undefined
I'm new to Nodejs, so any kind of help would be nice. I tried doing file.write too, and it still throws the same error. Any help would be gladly appreciated (:
Updated with code:
var exec = require("child_process").exec;
var qs = require("querystring"),
fs = require("fs"),
formidable = require("formidable"),
url = require( "url" );
function start(response, request) {
/*
var fileName = "start.html"
var localPath = __dirname;
var mimeType = "text/html";
var name = localPath + "/" + fileName;
getFile(name, response, mimeType);
console.log("Request handler 'start' was called.");
console.log("Serving File: " + name);
*/
var body = '<html>'+
'<head>'+
'<meta http-equiv="Content-Type" '+
'content="text/html; charset=UTF-8" />'+
'</head>'+
'<body>'+
'<form action="/upload" enctype="multipart/form-data" '+
'method="post">'+
'<input type="file" name="upload" multiple="multiple">'+
'<input type="submit" value="Upload file" />'+
'</form>'+
'</body>'+
'</html>';
console.log( "Request for 'start' is called." );
response.writeHead( 200, { "Content-Type" : "text/html" } );
response.end( body );
}
function upload(response, request) {
console.log("Request handler 'upload' was called.");
console.log( "Preparing upload" );
var form = new formidable.IncomingForm();
form.parse(request, function(error, fields, files){
if(error){
console.log(error);
console.log("Dun Goofed");
}
console.log("parsing done");
fs.rename(files.upload.path, "/tmp/test.png", function (error) {
if (error) {
fs.unlink("/tmp/test.png");
fs.rename(files.upload.path, "/tmp/test.png");
}
});
/* fs.rename(files.upload.path, "/tmp/test.png", function(err){
if(err){
fs.unlink("/tmp/test.png");
fs.rename(files.upload.path, "/tmp/test.png");
}
}); */
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Received image: <br/>");
response.write("<img src='./show' />");
response.end();
});
}
exports.start = start;
exports.upload = upload;
//exports.show = show;
I Omitted some parts because they have nothing to do with the file upload, please excuse the comments too, just old code. I also do not have a /show function because I erased it temporarily.
Also Here are the errors I get in the console. One of the errors is because the upload cancels. After I enter the file I want to upload, the browser just sits there for a while and waits for request for the server, and in the console, it just stops before form.parse, and sits there doing nothing for about a minute, then it rolls out all the errors.
Web Server started on 127.0.0.1:8888
Request for / received.
About to route a request for /
Served a request for /
Request for 'start' is called.
Request for /upload received.
Received POST data chunk
About to route a request for /upload
Served a request for /upload
Request handler 'upload' was called.
Preparing upload
Successfully executes until here.
Then the browser waits for a while, and then It either pops up with no data received, or the webpage is unavailable, and then these errors come up in the console.
{}
[Error: Request aborted]
Dun Goofed
parsing done
/Users/USER/Documents/Node/requestHandlers.js:50
fs.rename(files.upload.path, "/tmp/test.png", function (error) {
^
TypeError: Cannot read property 'path' of undefined
at /Users/USER/Documents/Node/requestHandlers.js:50:31
at IncomingForm.<anonymous> (/Users/USER/node_modules/formidable/lib/incoming_form.js:89:9)
at IncomingForm.EventEmitter.emit (events.js:95:17)
at IncomingForm._error (/Users/USER/node_modules/formidable/lib/incoming_form.js:272:8)
at IncomingMessage.<anonymous> (/Users/USER/node_modules/formidable/lib/incoming_form.js:107:12)
at IncomingMessage.EventEmitter.emit (events.js:92:17)
at abortIncoming (http.js:1911:11)
at Socket.serverSocketCloseListener (http.js:1923:5)
at Socket.EventEmitter.emit (events.js:117:20)
at TCP.close (net.js:465:12)
I have the same problem.
delete the code request.setEncoding("utf8"); in server.js
like this:
function start(route, handler) {
http.createServer(function(request, response) {
var postData = "";
var pathname = url.parse(request.url).pathname;
route(handler, pathname, response, request);
}).listen(8889);
}

Form is timeouting on submitting without selected file in input type=file

Having a simple form as in the following js Fiddle http://jsfiddle.net/UdugW/ I am POSTing some form data to my node.js application (based on sails.js). This is one of the controller functions from product model:
image_upload: function(req, res) {
if (req.method.toLowerCase() == 'post') {
console.log("request: " + util.inspect(req.body));
if( req.files && req.files.product_image){
fs.readFile(req.files.product_image.path, function (err, data) {
var imageName = req.files.product_image.name;
if(!imageName){
console.log("There was an error with image upload : " + util.index(req.files.product_image));
res.redirect("/product/new_product");
res.end();
} else {
var newPath = UPLOAD_PATH + imageName;
/// write file to uploads/fullsize folder
fs.writeFile(newPath, data, function (err) {
res.writeHead(200, {'content-type': 'text/plain'});
res.end();
return;
});
}
});
}
}else if (req.body) {
console.log("product_name: " + product_name);
console.log("product_price: " + product_price);
console.log("product_description: " + product_description);
res.writeHead(200, {'content-type': 'text/plain'});
res.end();
}
else{
console.log("request err");
res.writeHead(500, {'content-type': 'text/plain'});
res.end();
}
},
I have a problem when I do not select an image for upload, then my POST request is timing out. Any ideas why this may happen ?
9/10 with node.js app, when something is timing out, chances are you forgot to close the socket (at least in my experience). and in your case it's no different :-)
here is the problem: you have this if-statement
if( req.files && req.files.product_image){
but the poor guy doesn't have a matching else-statement :-(
so if that condition is not true... well, nothing happens. execution basically just ends and the browser is left waiting... for ever.
just adding an else-statment with a res.end() inside of it and you should be good.
So something like this
if( req.files && req.files.product_image){
//all the stuff you already have for when it matches
}else{
console.log("No files were included in the post");
res.end();
}

Node.js dirty Is it possible to reload a dirty database?

How do make the server reload the Dirty database when it's trying to get something from it? Because when I edit the database file with a text editor, and reload the browser, it doesn't update the page.
"reloadDB();" is where I want to reload the db.
Code example
http.createServer(function (request, response) {
var pathname = url.parse(request.url).pathname;
var html = db.get(pathname);
//Check if the requsted file is CSS or JS
if (/\.(css)$/.test(pathname) || /\.(js)$/.test(pathname)){
fs.createReadStream(__dirname + pathname, {
'bufferSize': 4 * 1024
}).pipe(response);
} else if (!!html && pathname !== '/admin' ) {
//Pages from our Dirty DB
response.writeHead(200, {'Content-Type': 'text/html'});
//reloadDB();
response.end(html);
} else if (pathname === '/admin') {
//Display Admin page
response.writeHead(200, {'Content-Type': 'text/html'});
response.end('Admin!');
} else {
//Show 404 Page
response.writeHead(404, {'Content-Type': 'text/html'});
//reloadDB();
response.end(db.get('404'));
}
You just need to call the .Dirty(path) method of your existing instance; if you look at the source, you'll see that there's a check allowing Dirty() to be used as either an instance method or a constructor.

Categories

Resources