Friday, April 24, 2009

S3.cfc on Railo - my fix

RiaForge has an awesome project S3.cfc for Amazon's S3 storage. http://amazons3.riaforge.org/

I love it. But it didn't work on Railo out of the box.

I was getting Signature doesn't match errors when attempting to run the s3test.cfm file in Railo on Linux.

After much research and dumping the s3 xml response I discovered that the difference is in the 'StringToSign'.

Using cf8 the 'StringToSign' it was expecting was: "GET Fri, 24 Apr 2009 17:28:00 GMT /"

However, using Railo on Linux the 'StringToSign' it was expecting was:
"GET text/html; charset=UTF-8 Fri, 24 Apr 2009 17:59:00 GMT /"

Notice the 'text/html; charset=UTF-8'.

This was comparing tests from CF8 on windows and Railo on Linux. I'm not actually sure if this is a Linux issue or a Railo issue. I have not tested the reverse (Railo on Windows & CF8 on Linux).

The strange thing is that Amazon was expecting it to be different when Windows CF8 and Linux Railo were passing the exact same request. I reset the 'datetimestring' to drop the seconds on the time [<cfset var dateTimeString = GetHTTPTimeString(DateAdd("s",-(DatePart("s",NOW())),Now()))>] so that I could verify that the signature on the generated signatures from the two machines were identical, and they were. So this really doesn't make sense to me, but I'm glad there was an easy solution.

The fix to making this cfc work on Railo on Linux was to change the following line inside the 'getBuckets' function in s3.cfc

from:
<!--- Create a canonical string to send --->
<cfset var cs = "GET\n\n\n#dateTimeString#\n/">

to:
<!--- Create a canonical string to send --->
<cfset var cs = "GET\n\ntext/html; charset=UTF-8\n#dateTimeString#\n/">

The same edit is required inside 'getBucket' and 'getObject'. Insert "text/html; charset=UTF-8" after the second '\n'.

Then everything worked perfectly. (So far.)