Search code examples
node.jsgmaws-sdk-nodejs

Strange node.js + http + gm + s3 behavior


The purpose of this node.js code block is to download an image, resize it, upload the resized image to s3, and then upload the original image to s3.

Non-Working code:

http.get(url, function onResponse(res) {
    gm(res)
    .resize(250,250)
    .stream(function(err, stdout, stderr){
        if(debug)console.log("Resized "+key+" and created "+key+"_thumb.jpg");
        if(err){
                console.log("Error resizing image. Message:",err);
        }
        else{
            var data = {
                Bucket: 'bucket-name',
                Key: key+"_thumb.jpg",
                Body: stdout,
                ACL: "public-read",
                ContentType:"image/jpeg"
            };
            s3 = new aws.S3()
            s3.upload(data, function(err, resp) {
                if(debug)console.log(resp);
            });
            s3=null;
            stdout=null;
            data=null;
        }
    });                        
    s3 = new aws.S3()
    s3.upload({Bucket:"bucket-name", Key: key+".jpg", ACL:"public-read", ContentType:"image/jpeg" ,Body: res}, function(err,data){
        if(debug)console.log(data);
        data=null;
    });
    s3=null;
    res=null;
});

The problem is that this code block does not run as expected. In the code above the thumbnail that s3 uploads is always an empty file.

However, if I remove the second s3 upload request, the thumbnails magically start uploading correctly.

Working code:

http.get(url, function onResponse(res) {
    gm(res)
    .resize(250,250)
    .stream(function(err, stdout, stderr){
        if(debug)console.log("Resized "+key+" and created "+key+"_thumb.jpg");
        if(err){
                console.log("Error resizing image. Message:",err);
        }
        else{
            var data = {
                Bucket: 'bucket-name',
                Key: key+"_thumb.jpg",
                Body: stdout,
                ACL: "public-read",
                ContentType:"image/jpeg"
            };
            s3 = new aws.S3()
            s3.upload(data, function(err, resp) {
                if(debug)console.log(resp);
            });
            s3=null;
            stdout=null;
            data=null;
        }
    });                        
    res=null;
});

Why can I upload thumbnails in the second example, but not the first?


Solution

  • I figured it out.

    After a successful http.get I use the following code to create a re-usable buffer.

    res.on('data', function(chunk) {
        data.push(chunk);
    }).on('end', function() {
        var imgbuffer = Buffer.concat(data);
        //create thumbnail
        //s3.upload thumbnail
        //s3.upload original
    });