Lepozepo / S3

A simple helper for easily uploading files to Amazon S3 from Meteor. This package will also make Knox available server-side.
MIT License
274 stars 74 forks source link

Server side uploads empty file #74

Open abachuk opened 9 years ago

abachuk commented 9 years ago

I'm doing http.post to upload the image to S3. Using S3.knox to upload file, it successfully uploads and returns bucketname.s3.amazonaws.com but it's empty file. Should I pass image path in a different way?

// image.path = /var/folders/sp/pg_4rkwn4q79h2nm40ryykv80000gn/T/arrow.png;

S3.knox.putFile(image.path, "/test/"+image.originalFilename, function(err, res){    
    console.log(res.req.url);
    res.resume();
});
Lepozepo commented 9 years ago

Hmm, you should definitely double check whether that path actually exists. Are you deploying via demeteorizer?

Lepozepo commented 9 years ago

Also, if you plan on doing server side uploads a lot, you should consider looking at some of the previous code I had on the package. You are going to want to leverage multi-part uploads especially if the files can be big. Otherwise your server will get angry at you, lol.

abachuk commented 9 years ago

Thanks for your suggestion! The local path is valid, when I try to copy/paste the path to a browser it opens correct image. I'm not using demeteorizer, it's localhost for now.

abachuk commented 9 years ago

Looks like res.req returns content-length always as zero.

...,
headers: {
'x-amz-id-2': '12284..00238',
'x-amz-request-id': 'qwerty',
'content-length': '0',
'connection': 'close'
},
...
Lepozepo commented 9 years ago

Hmm, have you tried opening an issue with the guys that built Knox? I wish I could help you more but my time is really constrained at the moment >_<

joaopiopedreira commented 7 years ago

If someone's still interested, I lost a few hours to make this work (uploading to S3 from the server, that is).

The meteor method uploadToS3Servershould run on the server.

/**
 * Created by joaopedreira on 07/10/16.
 */

Meteor.methods({
    /**
     * Downloads a file from some url and uploads the resulting buffer to S3
     * @param url - souce url for download
     * @param bucketSubFolder - the S3 subfolder where to put the file (e.g. "test")
     * @param fileName - the file name (e.g. "somename"). No extension needed, since it'll be infered from the buffer.
     */
    uploadToS3Server: function (url,bucketSubFolder,fileName) {
        "use strict";
        check(url,String);
        check(bucketSubFolder,String);
        check(fileName,String)

        var fileType = Npm.require('file-type'),
            filePath, fileExtension, fileMimeType;

        this.unblock();

        filePath = '/' + bucketSubFolder + '/' + fileName;

        var httpResponse = HTTP.get(url,{
            npmRequestOptions: {
                encoding: null
            }
        });
        log.debug(httpResponse.headers);

        if (httpResponse.statusCode === 200) {
            var buffer = httpResponse.content;
            fileExtension = fileType(buffer).ext;
            fileMimeType = fileType(buffer).mime;

            var headers = {
                'Content-Length': buffer.length,
                'Content-Type': fileMimeType || httpResponse.headers['content-type'],
                'x-amz-acl': 'public-read'
            };

            // Check buffer size
            if(buffer.length > 15 * 1024 * 1024) {
                throw new Meteor.Error(
                    '403',
                    'error uploading attachment ' + fileName + '. Attachment size exceeded (15 Mb max).',
                    'S3 Upload Size Exceeded' + filePath + '.' + fileExtension
                )
            }

            S3.knox.putBuffer(buffer, filePath + '.' + fileExtension, headers, function (err, res) {
                if (err) {
                    log.error(err);
                    throw new Meteor.Error(
                        '500',
                        'error uploading attachment to S3: ' + err,
                        'Attachment upload to S3 failed'
                    )
                }
                res.resume();
                log.info('File name: ' + filePath + '.' + fileExtension);
                log.info('Mime-type: ' + fileMimeType);
                log.info('Content-Length: ' + buffer.length);
                log.info('Download url: ' + 'https://' + S3.knox.urlBase  + filePath + '.' + fileExtension);

                return {
                    filePath: filePath + '.' + fileExtension,
                    fileMimeType: fileMimeType,
                    fileLength: buffer.length,
                    DowloadUrl: 'https://' + S3.knox.urlBase  + filePath + '.' + fileExtension
                }
            });
        } else {
            log.error('error downloading attachment from user url: %d, %s',httpResponse.status, httpResponse.headers);
            throw new Meteor.Error(
                '500',
                'error downloading attachment from user url Status: ' + httpResponse.status + '; headers: ' + JSON.stringify(httpResponse.headers),
                'Attachment download from client failed'
            )
        }
    }
});