从 Apex 上传 CSV 文件到 s3

Uploading a CSV file to s3 From Apex

我需要将 CSV 文件从 Apex 上传到 s3 中的全局存储桶并保留 URL。

下面描述的是我使用 AWS 请求签名过程的相同方法。

 public static void uploadCSVFileToS3(String csvFile, String filename, String awsAccessKey, String awsSecretKey, String bucketname){
    try{
        String formattedDateString = Datetime.now().format('EEE, dd MMM yyyy HH:mm:ss');
        String requestType = 'PUT';
        String contentType = 'text/csv';
        String filePath = 'https://s3.amazonaws.com' + '/'+ bucketname + '/' + 'demo.csv';

        HttpRequest req = new HttpRequest();
        req.setMethod(requestType);
        req.setHeader('Host','https://s3.amazonaws.com');
        req.setEndpoint(filePath);
        req.setHeader('Content-Length', String.valueOf(csvFile.length()));
        req.setHeader('Content-Type', contentType);
        req.setHeader('Date', formattedDateString);
        req.setHeader('ACL', 'public-read-write');
        Blob CSV = Blob.valueof(csvFile);
        req.setBodyAsBlob(CSV);

        String auth = createAuthHeader(requestType, contentType, filename, formattedDateString, bucketname, awsAccessKey, awsSecretKey);

        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());
    } catch(System.CalloutException e) {
        system.debug('AWS Service Callout Exception: ' + e.getMessage());
        system.debug('AWS Service Callout Exception: ' + e.getCause());
        system.debug('Exception: ' + e.getStackTraceString());
    } catch(Exception e) {
        system.debug('Exception: ' + e.getMessage());
        system.debug('Exception: ' + e.getStackTraceString());
    }  
}

public static String createAuthHeader(String method, String contentType, String filename, String formattedDateString, String bucket, String key, String secret){
    string auth;

    String stringToSign = method+'\n'+bucket+'/'+filename+'\n';
    Blob mac = Crypto.generateMac('HmacSHA1', blob.valueof(stringToSign), blob.valueof(secret));
    String sig = EncodingUtil.base64Encode(mac);
    auth = 'AWS' + ' ' + key + ':' + sig;


    return auth;
}  

我已按照 link 此处 (https://developer.salesforce.com/forums/?id=906F0000000BMDFIA4) 使用的方法进行操作。

我可以使用 AWS SDK 将文件从 ruby 或 javascript 上传到同一个存储桶,但它给我的响应代码是 400(错误请求)。 我认为这是签名请求过程的问题。

如果有人能在这里帮助我,我将不胜感激。

这里有一个link,清楚的描述了AWS的认证过程

http://gist.github.com/brianmfear/92cf05807ac4becbd21f