2

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:

debug

And all the files in S3:

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.

2 Answers 2

5

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.

3
  • Thanks for the hint, but removing it didn't solve my issue.
    – t56k
    Jun 28, 2016 at 5:58
  • @CD-RUM I just realized that you base-64 encoded your file. Don't do that, either.
    – sfdcfox
    Jun 28, 2016 at 6:06
  • Thank-you! That did it. You've helped me out with like every SF question I have, too, so thank you, really.
    – t56k
    Jun 28, 2016 at 6:40
1

I have faced this issue before and the problem was the content-type. From the file size, its evident that the upload has worked fine but the MIME type has not been set correctly.

In this line of code, can you check that "contentType" has been set correctly.

 req.setHeader('Content-type', contentType);

Also in your bucket where the files are uploaded, go to properties and check under metadata whether the content type is correct.

9
  • It's correct in the bucket properties. I've set it according to a question I asked maybe three hours ago here -- salesforce.stackexchange.com/questions/129022/… -- and it seems to be working fine. I've tried opening the result in Photoshop and it just says the file is corrupt. Pretty stuck here.
    – t56k
    Jun 28, 2016 at 5:27
  • It definitely should be UTF-8, right?
    – t56k
    Jun 28, 2016 at 5:29
  • For a jpeg it should be "image/jpeg". For more see here: webdesign.about.com/od/multimedia/a/…
    – Richard N
    Jun 28, 2016 at 5:30
  • Yeah, I've got a PNG in there right now that I uploaded through my class that automatically was set to "image/png". I meant that it should be UTF-8 for the Content-Encoding.
    – t56k
    Jun 28, 2016 at 5:32
  • BTW which browser are you using? Can you try in another one?
    – Richard N
    Jun 28, 2016 at 5:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .