request: Content-Length header is not set when using the form library

I tried to upload a file using the form library like this:

var r = request.post(options, cb),
    form = r.form();

form.append('image', fs.createReadStream('/tmp/testimg.jpg'));

My server (nginx as reverse proxy in front of Apache) then throws a 411. I then tried to set the Content-Length manually like this:

var r = request.post(options, cb),
    form = r.form();

form.append('image', fs.createReadStream('/tmp/testimg.jpg'));
r.setHeader('Content-Length', form.getLengthSync());

But then the server script (PHP) throws a UPLOAD_ERR_PARTIAL (The file was only partially uploaded) error. So i guess, the Content-Length is still wrong.

About this issue

  • Original URL
  • State: closed
  • Created 12 years ago
  • Comments: 20 (4 by maintainers)

Most upvoted comments

This WILL work with cookie and correct Content-Length !

you need to: npm install form-data

var FormData = require('form-data');
var request = require('request')
var form = new FormData();
form.append('api_key', api_key);
form.append('product_id', 19);
form.append('file', fs.createReadStream(path.join(__dirname, '/IMG_0859.png')));

form.getLength(function(err,length){
    var r = request.post('http://your-site.com', { headers: { 'content-length': length } }, function(err, res, body){ console.log(body) });
     r._form = form
});


+1 still not working…

I got a mix of @mikehaertl and @lildemon solutions to work properly:

var r = request.post(options, cb),
    form = r.form();

form.append('image', fs.createReadStream('/tmp/testimg.jpg'));

form.getLength(function(err, length) {
  r.setHeader('Content-Length', length);
});

For some reason, in my tests form.getLength (source) returns the right length whereas form.getLengthSync(source) returns length minus 12

@mikeal - I have proposed a fix for this on our fork at: https://github.com/postmanlabs/postman-request/pull/13

What do you think? Is it worth a PR here?

I am using multiparty and request module together. Here is code example:

app.post('/submit', function(httpRequest, httpResponse, next){

    var form = new multiparty.Form();

    form.on("part", function(part){
        if(part.filename)
        {

            var FormData = require('form-data');
            var form = new FormData();
            form.append('thumbnail', part);

            form.getLength(function(err,length){
                console.log(length);
                var r = request.post('http://localhost:8888/index.php', { headers: { 'content-length': length } }, function(err, res, body){ 
                    if(err) {
                        return console.error('upload failed:', err);
                    }

                    console.log(body) 
                });
                 r._form = form
            });
        }
    })

    form.on("error", function(error){
        console.log(error);
    })

    form.parse(httpRequest);    
});

Here I am uploading the user uploaded file to another server via streaming i.e., without saving a temporary file.

But on the PHP server no file is uploaded. $_FILES array is empty.

Please help.