I've made a file uploader from SF to AWS S3. Everything works as expected except for the fact that the file itself in S3, despite its size reading correctly, is empty:
public pageReference uploadFromFilesystem() {
try {
String fileBody = EncodingUtil.base64Encode(fileBlob);
String now = Datetime.now().formatGMT('EEE, dd MMM yyyy HH:mm:ss z');
System.debug('fileBody: ' + fileBody);
HttpRequest req = new HttpRequest();
req.setMethod(method);
req.setEndpoint('https://' + bucketname + '.' + host + '/' +
lead.Id + '/' + fileName);
req.setHeader('Host', bucketname + '.' + host);
req.setHeader('Content-Length', String.valueOf(fileBody.length()));
req.setHeader('Content-Encoding', 'UTF-8');
req.setHeader('Content-type', contentType);
req.setHeader('Connection', 'keep-alive');
req.setHeader('Date', now);
req.setHeader('ACL', 'public-read');
req.setBody(fileBody);
String stringToSign = 'PUT\n\n' + contentType + '\n' + now + '\n' +
'/' + bucketname + '/' + lead.Id + '/' + fileName;
String encodedStringToSign = EncodingUtil.urlEncode(stringToSign, 'UTF-8');
Blob mac = Crypto.generateMac('HMACSHA1', Blob.valueOf(stringToSign), Blob.valueOf(secret));
String signed = EncodingUtil.base64Encode(mac);
String authHeader = 'AWS' + ' ' + key + ':' + signed;
req.setHeader('Authorization', authHeader);
String decoded = EncodingUtil.urlDecode(encodedStringToSign , 'UTF-8');
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug('RESPONSE STRING: ' + res.toString());
System.debug('RESPONSE STATUS: ' + res.getStatus());
System.debug('STATUS_CODE: ' + res.getStatusCode());
uploadObjectErrorMsg = null;
} catch(Exception e) {
System.debug('EXCEPTION: ' + e);
uploadObjectErrorMsg = e.getMessage();
}
return null;
}
Debugging the fileBody returns a string, the files all appear in S3 as the right size, but either trying to preview them in Amazon or download them locally they are empty. What am I missing?
Here's the debug:
And all the files in S3:
And yet, when they're viewed or downloaded, they're "empty" or corrupted or similar, so it seems like an encoding issue. What am I missing? fileBlob
comes from an <apex:inputFile>
field.
Best Answer
You should not be setting Content-Encoding. UTF8 is for text, so it'll mess up some bytes in the upload process. Just leave that header out.
Edit: I see you decided to base-64 encode your fileBody. Don't do that, either. Just use
req.setBodyAsBlob(fileBlob);
instead.