Following along with: The Node Beginner Book
I'm unable to debug this issue or find a solution online. A newbie to Node.js, hoping someone can offer a solution
ERROR: Updated with console log info Saturday, February 11, 2012 7:27:17 AM
Request for/ received!
About to route a request for /
Request handler 'start' was called.
Request for/favicon.ico received!
About to route a request for /favicon.ico
No request handler found for /favicon.ico
Request for/favicon.ico received!
About to route a request for /favicon.ico
No request handler found for /favicon.ico
Request for/upload received!
About to route a request for /upload
Request handler 'upload' was called.
about to parse
{ output: [],
outputEncodings: [],
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
_hasBody: true,
_trailer: '',
finished: false,
socket:
{ _handle:
{ writeQueueSize: 0,
socket: [Circular],
onread: [Function: onread] },
_pendingWriteReqs: 0,
_flags: 0,
_connectQueueSize: 0,
destroyed: false,
bytesRead: 66509,
bytesWritten: 638,
allowHalfOpen: true,
writable: true,
readable: true,
server:
{ connections: 1,
allowHalfOpen: true,
_handle: [Object],
_events: [Object],
httpAllowHalfOpen: false },
ondrain: [Function],
_idleTimeout: 120000,
_idleNext:
{ _idleNext: [Circular],
_idlePrev: [Circular],
ontimeout: [Function] },
_idlePrev:
{ _idleNext: [Circular],
_idlePrev: [Circular],
ontimeout: [Function] },
_idleStart: Sat, 11 Feb 2012 15:25:28 GMT,
_events: { timeout: [Function], error: [Function], close: [Object] },
ondata: [Function],
onend: [Function],
_httpMessage: [Circular] },
connection:
{ _handle:
{ writeQueueSize: 0,
socket: [Circular],
onread: [Function: onread] },
_pendingWriteReqs: 0,
_flags: 0,
_connectQueueSize: 0,
destroyed: false,
bytesRead: 66509,
bytesWritten: 638,
allowHalfOpen: true,
writable: true,
readable: true,
server:
{ connections: 1,
allowHalfOpen: true,
_handle: [Object],
_events: [Object],
httpAllowHalfOpen: false },
ondrain: [Function],
_idleTimeout: 120000,
_idleNext:
{ _idleNext: [Circular],
_idlePrev: [Circular],
ontimeout: [Function] },
_idlePrev:
{ _idleNext: [Circular],
_idlePrev: [Circular],
ontimeout: [Function] },
_idleStart: Sat, 11 Feb 2012 15:25:28 GMT,
_events: { timeout: [Function], error: [Function], close: [Object] },
ondata: [Function],
onend: [Function],
_httpMessage: [Circular] },
_events: { finish: [Function] } }
/usr/local/lib/node_modules/formidable/lib/incoming_form.js:247
undefined
if (this.headers['content-length']) {
^
TypeError: Cannot read property 'content-length' of undefined
at IncomingForm._parseContentLength (/usr/local/lib/node_modules/formidable/lib/incoming_form.js:247:19)
at IncomingForm.writeHeaders (/usr/local/lib/node_modules/formidable/lib/incoming_form.js:126:8)
at IncomingForm.parse (/usr/local/lib/node_modules/formidable/lib/incoming_form.js:80:8)
at Object.upload [as /upload] (/Applications/MAMP/htdocs3/js/nodejs/webapp/requestHandlers.js:34:8)
at route (/Applications/MAMP/htdocs3/js/nodejs/webapp/router.js:4:20)
at Server.onRequest (/Applications/MAMP/htdocs3/js/nodejs/webapp/server.js:20:3)
at Server.emit (events.js:70:17)
at HTTPParser.onIncoming (http.js:1511:12)
at HTTPParser.onHeadersComplete (http.js:102:31)
at Socket.ondata (http.js:1407:22)
End Error
requestHandlers.js
var querystring = require("querystring"),
fs = require("fs"),
formidable = require("formidable");
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");
/*
* Some systems [Windows] raise an error when you attempt to rename new file into one that already exists.
* This call deletes the previous .PNG image prior to renaming the new one in its place.
*/
fs.unlinkSync(__dirname +"/tmp/test.jpg");
fs.renameSync(files.upload.path, "/tmp/test.jpg");
response.writeHead(200, {"Content-Type": "text/html"});
response.write("received image:<br/>");
response.write("<img src='/show' />");
response.end();
});
}
function show(response) {
console.log("Request handler 'show' was called.");
fs.readFile(__dirname + "/tmp/test.jpg", "binary", function(error, file) {
if(error) {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write(error + "\n");
response.end();
} else {
response.writeHead(200, {"Content-Type": "image/jpg"});
response.write(file, "binary");
response.end();
}
});
}
exports.start = start;
exports.upload = upload;
exports.show = show;
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);
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/html"});
response.write("404 Not found");
response.end();
}
}
exports.route = route;
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.");
http.createServer(onRequest).listen(1337, "127.0.0.1");
console.log('Server Has Started!');
}
exports.start = start;
No need to use old versions of Node and Formidable. I was able to get the example to work with Node v0.10.20 and Formidable v1.0.14. It would appear that the files.upload
property is no longer used.
Simply change this following line from the book:
fs.rename(files.upload.path, "/tmp/test.png", function(error) { ... });
to
fs.rename(files.file.path, "/tmp/test.png", function(error) { ... });
...and then the upload works perfectly!
Another optional tweak to the example (especially for Windows developers)
Rather than using the error status from fs.rename()
to determine if the file already exists, I had great luck using fs.exists()
to do check for the existing file that felt like less of a hack. I also saved the test.png file to the local directory, since /tmp
is a pretty unnatural Windows path...
var img = "./test.png";
...
fs.exists(img, function(exists){
if(exists){ fs.unlink(img); }
fs.rename(files.file.path, img);
...