S3
S3 copied to clipboard
Server side uploads empty file
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();
});
Hmm, you should definitely double check whether that path actually exists. Are you deploying via demeteorizer?
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.
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.
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'
},
...
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 >_<
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 uploadToS3Server
should 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'
)
}
}
});