AWS S3 preview private and encrypted files with PHP

Recently I had to develop a WordPress plugin that is used to manage files stored on Amazon AWS S3. Due to the nature of the files which contain sensible information they are stored as private and using the AES256 ServerSideEncryption.

In order to serve the files to authorized users an AJAX call is used to generate a temporary link from the AWS PHP SDK. My problem is that for these links the “content-disposition” header is set to “attachment” which forces a download. As the client wanted to offer the option to also view directly in the browser these ( PDF ) files, I was faced with a problem.

Previewing the files without forcing a client download

The Amazon AWS documentation specifies an optional content-disposition parameter. So, for example, in a “getObjectUrl” call you would use:

$args = array(
    'ResponseContentDisposition' => 'attachment; filename=testing.pdf'
);
$request = $s3Client->getObjectUrl( $bucket, 'example/test.pdf', '+2 minutes', $args );

Those arguments get passed to the “getObject” function as explained here. The problem is that for some reason this parameter is ignored – probably because of the encryption.

I found a quick solution to this problem by downloading the file and serving directly from PHP on my server instead of trying to change the content-disposition on Amazon’s requests.

So in the WordPress plugin I added a simple function which takes a file and serves it with content-disposition inline:

add_action( 'wp_ajax_m_view_link', array( $this, 'view_pdf' ) );
function view_pdf() {
   if ( isset($_GET['url']) && is_user_logged_in() ) {
      header('Content-disposition: inline; filename='.basename($_GET['url']));
      header("Content-type:application/pdf");
      echo file_get_contents($_GET['url']);
   }
   die();
}

So now when calling /wp-admin/admin-ajax.php?action=m_view_link&url=url_of_amazon_file the users can preview the files directly in their browsers.

Notes:

To prevent potential security threats you should add some checks to the “view_pdf” function above.

Obviously you can use this for other purposes than Amazon S3 files it’s a quick way to change the content-disposition of certain external files.