nodejs & formidable header error
Asked Answered
G

4

10

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;
Guerdon answered 5/2, 2012 at 0:30 Comment(5)
I think we're missing the important part. How are you calling all of these functions?Decompress
Included all the code. Thanks for the reply.Guerdon
Shouldn't you use response instead of request? So it should be form.parse(response, function(... in an upload function. Please try it and let me know. Additionally debug request / response before form.parse() by typing in console.log(response) / console.log(request)Petrick
@Marek Tuchalski updated the error code with console log info. form.parse(response).... didn't help, but returned different errors. See the online tutorial I'm pulling this from. It could shed some light.Guerdon
I'm having the exact same problem. Were you ever able to fix this? I tried the solutions below (except for the ones where they suggest getting older versions) but they didn't work for me.Roose
Q
2

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);

        ...
Quezada answered 8/10, 2013 at 0:39 Comment(0)
N
0

For what it is worth the above code worked for me.

The problem seems to occur within formidable. Checking the package.json in node_modules I am using version 1.0.8 on node -v = v0.4.12.

It appears the browser or request you are making does not include a content-length header in the request. I was using Chrome, but if you were using CURL or perhaps making the request asynchronously or as a stream you might not have a content-length header in the request causing this issue. This is somewhat discussed here: https://github.com/felixge/node-formidable/issues/93

In my opinion, formidable should check for the existence of the parameter properly (typeof(this.headers['content-length']) != undefined). It would help others if you identify your browser and type of file you were trying to upload, then you could file a bug over at https://github.com/felixge/node-formidable/

Note: you might also update the title of this question to nodejs not nodjs. Good luck with node!

Northernmost answered 12/2, 2012 at 15:57 Comment(0)
S
0

If you use the same versions of Formidable and Node.js as used in the tutorial, the code works as advertised.

The version of Formidable used in the tutorial is 1.0.2. To obtain this version, issue:

$ sudo npm install [email protected]

The version of Node.js is 0.6.10, which can be found here: https://github.com/joyent/node/tags

Sulfaguanidine answered 24/1, 2013 at 4:14 Comment(0)
A
0

Well I have the same code that you, but with a little change in function upload on RequestHandlers.js, try changing this:

function upload(response, request) { 
...
var form = new formidable.IncomingForm();
...
}

to this:

function upload(response, request){
...
var form = new formidable.IncomingForm(), files = [], fields = [];
...
}

If that doesn't work you should be able to see how is the request header forming :

function upload(response, request){
...
form.parse(request, function(error, fields,files){
console.dir(request.headers);
...
}
}

Hope you solve your problem

Autointoxication answered 28/4, 2014 at 4:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.