• Daniel Best 7
  • NEWBIE
  • 10 Points
  • Member since 2020

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 1
    Replies
I have a need to upload binary stream PDF files to Amazon S3.  I've seen the sample code available to use the REST API with the POST operation on visualforce page, however, I need to upload the file via APEX without user involvment, as I'm retrieiving the files from another database via their SOAP API.

I'm trying to do this using the PUT operation, but I don't think I'm doing the authentication correctly as I'm getting a 403 Forbidden response.

Any ideas?
 
public void uploadPDF(String binaryPdfString, String key, String secret){
        String Date = Datetime.now().formatGMT('EEE,   dd MMM yyyy HH:mm:ss z');
        String bucketname = 'BucketName';
        String method = 'PUT';
        String filename = 'FileName';
        HttpRequest req = new HttpRequest();
        req.setMethod(method);
        req.setHeader('Host','s3-us-west-2.amazonaws.com');
        req.setEndpoint('https://s3-us-west-2.amazonaws.com' + '/'+ bucketname + '/' + filename);
        req.setHeader('Content-Length', string.valueOf(binaryPdfString.length()));
        req.setHeader('Content-Encoding', 'base64');
        req.setHeader('Content-Type', 'pdf');
        req.setHeader('Date', Date);

        //get signature string
        String stringToSign = 'PUT\n\n\n'+formattedDateString+'\n\n/'+bucketname+'/'+filename;
        String encodedStringToSign = EncodingUtil.urlEncode(stringToSign,'UTF-8');
        String signed = createSignature(encodedStringToSign,secret);
        String authHeader = 'AWS' + ' ' + key + ':' + signed;
        req.setHeader('Authorization',authHeader);
        req.setBody(binaryPdfString);
        Http http = new Http();

        try {
            //Execute web service call
            HTTPResponse res = http.send(req);
            System.debug('RESPONSE STRING: ' + res.toString());
            System.debug('RESPONSE STATUS: '+res.getStatus());
            System.debug('STATUS_CODE: '+res.getStatusCode());

        } catch(System.CalloutException e) {
            system.debug('AWS Service Callout Exception: ' + e.getMessage());
        }

}

public string createSignature(string canonicalBuffer,String secret){
        string sig;
        Blob mac = Crypto.generateMac('HMacSHA1', blob.valueof(canonicalBuffer),blob.valueof(secret));
        sig = EncodingUtil.base64Encode(mac);

        return sig;

}