Thursday, October 14, 2010

CFHTTP directly to output

We store our files on S3. Before they are uploaded there we know the file content-type and store it in the database with the file name and other data.

Then out site links to the file. This was previously exposing the raw S3 link with key and signature to the user - which is ugly.

Yeah, ugly. But it was functional. Images would display in the browser and files of other content type would be prompted for download.

I wanted to change that but googling wasn't providing the answers.

I'm using the awesome Railo CFML server. There were some ACF examples, incomplete at best, which referenced "cfhttp.fileContent.toByteArray()", but that wasn't working in Railo.

After an hour of trial and lots of errors, I came up with this so-far-solidly working solution:

<cfhttp url="#variables.s3filelink#" getAsBinary="yes" method="get" />
<cfheader name="Content-Disposition" value="inline;filename=#variables.filename#" />
<cfcontent type="#variables.filetype#" reset="Yes" variable="cfhttp.filecontent">

This solution hides the external S3 link and preserves the view-in-browser for images and prompts for download on other file types.

Also, it was important for images that the user can right click on the displayed image and select to save the file locally to their machine. Using the cfheader line shown above and setting the filename=#variables.filename# attribute the original file name is prevserved when the user is prompted to download the file. I found without that setting the download file name was the name of my cfml template - which is bad because it looses the original file extision of .jpg or .pdf. Very important.

That's a wrap.