Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Corrupted image on uploading image to AWS-S3 via signed url

I'm trying to upload images to aws-s3 via a signed-url from NodeJS server (not from a browser). The image to upload has been generated by NodeJS. I'm getting the signed-url from aws and succeeding to upload it to s3.

But my image is corrupted. For some reason, S3 is adding some headers to my image (compare image attached).

What am I doing wrong?

getting the signed url:

    try {
        var params = {
            Bucket: bucketName,
            Key: 'FILE_NAME.png',
            Expires: 60
        };
        const url = await s3.getSignedUrlPromise('putObject', params);
        return url;
    } catch (err) {
        throw err;
    }

uploading to s3

        var stats = fs.statSync(filePath);
        var fileSizeInBytes = stats["size"];
        const imageBuffer = fs.readFileSync(filePath);

        var formData = {
            'file': {
                value: imageBuffer,
                options: {
                    filename: 'FILE_NAME.png'
                }
            }
        };

        request({ 
            method: 'put',
            url, 
            headers: {
                'Content-Length': fileSizeInBytes,
                'Content-MD': md5(imageBuffer)           
            }, 
            formData 
        }, function (err, res, body) {
             console.log('body',body);
        });

Compare between the actual image and the uploaded image to s3. S3 added some headers:

compare

like image 468
Nir Krevner Avatar asked Oct 04 '19 10:10

Nir Krevner


1 Answers

I know this is old but I struggled with the same issue for a while. When uploading using a pre-sgined url, DO NOT use new FormData();

One thing I noticed that all of my files on s3 were exactly 2kb larger than the originals.

<input type="file" id="upload"/>

var upload = document.getElementById('upload');
var file = upload.files[0];

//COMMENTED OUT BECAUSE IT WAS CAUSING THE ISSUE
//const formData = new FormData();
//formData.append("file", file);

// Assuming axios

const config = {
    onUploadProgress: function(progressEvent) {
        var percentCompleted = Math.round(
            (progressEvent.loaded * 100) / progressEvent.total
        );
        console.log(percentCompleted);
    },
    header: {
        'Content-Type': file.type
    }
};

axios.put(S3SignedPutURL, file, config)
   .then(async res => {
        callback({res, key})
    })
    .catch(err => {
        console.log(err);
    })
like image 128
Sam Munroe Avatar answered Oct 06 '22 21:10

Sam Munroe