AWS S3: Force File Download using 'response-content-disposition'

16,977
    String codedFilename=  EncodingUtil.urlEncode(bucketPath,'UTF-8');

    String stringtosign = 'GET\n\n\n'+Lexpires+'\n/'+bucketName+'/'+codedFilename+'?response-content-disposition=attachment; filename=abc.doc';

    String signed = make_sig(stringtosign); 

    String codedsigned = EncodingUtil.urlEncode(signed,'UTF-8');

    String url = serverURL+'/'+bucketName+'/'+codedFilename+'?response-content-disposition='+EncodingUtil.urlEncode('attachment; filename=abc.doc','UTF-8')+'&AWSAccessKeyId='+awskey+'&Expires='+Lexpires+'&Signature='+codedsigned;

Source: Unable to override content disposition header in s3

Chrome has problem if content type is 'application/octet-stream' for a document(pdf int this case). However chrome is OK if content type is 'binary/octet-stream'.

Thankfully S3 defaults Content-Type of download to 'binary/Octet-stream' if nothig is set at the time of upload.

My Advice:- If one needs to files of 'any' type to S3 without knowing content type at the time of upload, simply do not set it or set it to 'binary/Octet-stream'. This way Chrome will show warning but file is downloaded.

Share:
16,977
Ganesh Bhosle
Author by

Ganesh Bhosle

Nothing special.

Updated on June 05, 2022

Comments

  • Ganesh Bhosle
    Ganesh Bhosle almost 2 years

    Few lines(below) generate signed URL to which browser is redirected to download a file from S3.

    I am facing well known issue of Chrome not downloading pdf files from S3 when content type is set as Octet Stream.

    The solution is to force chrome to download file instead of trying to read/open it.

    I tried adding 'response-content-disposition' to sign as well as URL, but it didn't work.

    How to use 'response-content-disposition' header when url is to be generated?

        String codedFilename=  EncodingUtil.urlEncode(bucketPath,'UTF-8');
    
        String stringtosign = 'GET\n\n\n'+Lexpires+'\n/'+bucketName+'/'+codedFilename;
    
        String signed = make_sig(stringtosign); 
    
        String codedsigned = EncodingUtil.urlEncode(signed,'UTF-8');
    
        String url = serverURL+'/'+bucketName+'/'+codedFilename+'?AWSAccessKeyId='+awskey+'&Expires='+Lexpires+'&Signature='+codedsigned;
    

    Note:- This is salesforce-apex syntax.