http.get() content-length mismatch with body received #3204

Closed
tomasikp opened this Issue May 2, 2012 · 3 comments

2 participants

@tomasikp

I am trying to get images from facebook's graph api. i.e: http://graph.facebook.com/VirginAmerica/picture?type=large

The url responds with a 302 and then provides the URI location of the photo.

The problem I am having:

The cumulative data.length does not match the content-length expected in the headers from the photo location as the images get LARGER.

I am automatically retrying the request if the body.length does not match the expected content-length.

On some larger images I have repeated the request 1000+ times without success. Sometimes it will return successfully in less requests.

Am I doing something wrong?

####Facebook Image Download Example

var http = require('http');
var fs = require('fs');
var url = require('url');

var count = 0;

var imageGrab = function(location)
{
    var parsedURL = url.parse(location);
    var data=0;
    var contentLength=0;

    var options = {
        host: parsedURL.host,
        port: 80,
        path: parsedURL.path
    };

    http.get(options, function(res) {

    contentLength=parseInt(res.headers['content-length']);

    res.on('data', function (chunk) {
        if(data==0)
                            {
                                data=chunk;
                            }
                            else
                                {
                                    data+=chunk;
                                }
    });

    res.on('end', function(){
                        console.dir(res.headers);
                        console.dir(contentLength);
                        console.dir(data.length);
                        count++;
                        console.log("count:" + count);
                        if(data.length==contentLength)
                            {
                                    fs.writeFileSync("pic.jpg", data);
                            }
                            else
                                {
                                    imageGrab(location);
                                }


    });

    }).on('error', function(e) {
    console.log("Got error: " + e.message);
    });

};

var location;

var options = {
    host: 'graph.facebook.com',
    port: 80,
    path: '/VirginAmerica/picture?type=large'
};

http.get(options, function(res) {

    if(res.statusCode==302){

        location=res.headers.location;

        console.dir(location);

        imageGrab(location);
    }

}).on('error', function(e) {
console.log("Got error: " + e.message);
});

Example Output

SS

@tomasikp

Same results on v0.6.7 and v0.6.16

@koichik

Because chunk is not a string, it is a Buffer, you cannot use data += chunk. It means each buffers are converted into string (with UTF-8) and concatenated. In UTF8, the number of the characters and bytes are not identical. So, you should:

var data = [];

res.on('data', function(chunk) {
  data.push(chunk);
});

res.on('end', function(){
  ...
  console.log(data.reduce(function(prev, current) {
    return prev + current.length;
  }, 0);
  ...
});
@koichik koichik closed this May 2, 2012
@tomasikp

Thank you for the response kolchik!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment