+ Start a Discussion
Hitesh Grover 18Hitesh Grover 18 

Salesforce to AWS File Upload

I am trying to upload files from a lightning component to AWS directly with saving in salesforce. I get 400 Bad Request error.
Can anyone help?

 
public with sharing class TestingAmazon {
    @AuraEnabled
    
    public static String testIntegration(String filename, String base64Data , String contentType) {
        System.debug('filename---->>'+filename);
        System.debug('base64Data---->>'+base64Data);
        System.debug('contentType---->>'+contentType);
        //Blob beforeblob = EncodingUtil.base64Decode(base64Data);
        Blob beforeblob = Blob.valueOf(base64Data);
        String attachmentBody = EncodingUtil.base64Encode(beforeblob);
        String formattedDateString = Datetime.now().formatGMT('EEE, dd MMM yyyy HH:mm:ss z');
        String key = '-------------------------------';
        String secret = '---------------------------------------------';
        String bucketname = 'testfileupoad';
        String host = 's3.ap-south-1.amazonaws.com';
        String method = 'PUT';

        HttpRequest req = new HttpRequest();
        req.setMethod(method);
        req.setEndpoint('https://' + bucketname + '.' + host + '/' + bucketname + '/' + filename);

        req.setHeader('Host', bucketname + '.' + host);
        req.setHeader('Content-Length', String.valueOf(attachmentBody.length()));
        req.setHeader('Content-Encoding', 'base64');
        req.setHeader('Content-type', contentType);
        req.setHeader('Connection', 'keep-alive');
        req.setHeader('Date', formattedDateString);
        req.setHeader('ACL', 'public-read');
        req.setBodyAsBlob(beforeblob);
        System.debug('req---->'+req);
        
       /* String stringToSign = 'PUT\n\n' +
                contentType + '\n' +
                formattedDateString + '\n' +
                '/' + bucketname + '/' + bucketname + '/' + filename; */

        String stringToSign = 'PUT\n' +
                contentType + '\n' +
                formattedDateString + '\n' +
                '/' + bucketname + '/' + bucketname + '/' + filename;
        System.debug('stringToSign---->>'+stringToSign);

        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;
        System.debug('authHeader---->>'+authHeader);
        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());
        if(res.getStatusCode() == 200){
            String ReturnUrl = 'https://'+host+'/'+bucketname+'/'+bucketname+'/'+filename;
            System.debug('ReturnUrl---->>'+ReturnUrl);
            return ReturnUrl;
        }
        return 'ERROR';
    }
}

 
Khan AnasKhan Anas (Salesforce Developers) 
Hi Hitesh,

Greetings to you!

If we get Http BAD request 400 error, the problem is surely from our request. Check the endpoint, body, setHeader() and so on.

1. Check the URL.
2. Try HTTP instead of HTTPS and vice versa.
3. The response body will tell you more information. So, use getBody() to find what is the information the body is getting from the URL.
4. Check whether the URL has any blank space.

Please refer to the below links which might help you further with the above requirement.

https://debugonweb.com/2018/08/28/amazon-s3-bucket/

https://www.forcetalks.com/blog/automate-to-upload-files-on-amazon-s3-through-salesforce-apex/

https://www.linkedin.com/pulse/file-upload-from-salesforce-aws-s3-bucket-tanay-das-barman/

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Thanks and Regards,
Khan Anas
Ramesh DepaiahRamesh Depaiah
Hi Hitesh,

Make sure space has been replaced with '%20' in the filename, when passing space in the url thorws 400 Bad request error.

Thanks
Ramesh
Deepali KulshresthaDeepali Kulshrestha
Hi Hitesh,
When we have to upload multiple files or attach many files to any record, Salesforce provides storage limit per user license purchased. It varies from edition to edition. So, sometimes organizations decide to use external storage service like Amazon S3 cloud.

Please refer to the following link as it may be helpful in solving your problem:
https://aws.amazon.com/blogs/apn/connecting-aws-and-salesforce-enables-enterprises-to-do-more-with-customer-data/
https://blogs.absyz.com/2016/06/06/upload-files-in-amazon-s3-from-salesforce/

I hope you find the above solution helpful. If it does please mark as Best Answer to help others too.
Thanks and Regards,
Deepali Kulshrestha 
S3-LinkS3-Link
S3- Link is a Salesforce - Amazon Connector. Its also available on Appexchange. We have a lightning component for file upload in Amazon S3 which you can plugin anywhere in your lighning pages. 

Here is the link

https://appexchange.salesforce.com/listingDetail?listingId=a0N3000000CW1OXEA1

Here is our email address. Let us know if you have any query.
support@neiloncloud.com

Thanks
Sonam MeshramSonam Meshram
Hi All,
It is very easy to integrate SFDC with Amazon S3 by using the app named Drag, Drop & Upload Files to Amazon S3 for this am using the same and its very easy to use and has advanced features like you can delete/view your files from salesforce, and also provide some additional customization.
If you have been using Salesforce for any length of time, you have probably wanted to attach large and multiple files at one time. Now you can! In standard salesforce, you can attach and only upload files up to 25MB size one at a time.

This App provides you the facility to associate multiple files to a record in one go and without any size restriction.

Please have a look : https://sforce.co/34y12sL