Skip to content

Instantly share code, notes, and snippets.

@jsteenkamp
Last active May 27, 2016 20:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsteenkamp/20db87f96351448eda632a1fd495422c to your computer and use it in GitHub Desktop.
Save jsteenkamp/20db87f96351448eda632a1fd495422c to your computer and use it in GitHub Desktop.
Replacement for ColdFusion <cffile.../> to upload and read (acl = public-read) to/from Amazon S3
<cffunction name="readFromAmazonS3">
<cfargument name="fileName" required="true"/>
<cfargument name="bucket" default="mybucket"/>
<cfhttp method="GET" url="http://s3.amazonaws.com/#arguments.bucket#/#arguments.fileName#" timeout="300" result="result"></cfhttp>
<cfreturn result.filecontent/>
</cffunction>
<cfscript>
fileName = 'test.png'
bucketName = 'mybucket';
path = 'absolute/path/to/my/file';
</cfscript>
<cffile action="readBinary" file="#path#/#fileName#" variable="fileData"/>
<cfset result = uploadToAmazonS3(fileName, fileData)/>
<cfdump var="#result#"/>
<cffunction name="uploadToAmazonS3">
<cfargument name="fileName" required="true"/>
<cfargument name="data" required="true"/>
<cfargument name="bucket" default="orbital.co.nz"/>
<cfargument name="acl" default="public-read"/>
<cfargument name="accessKeyId" default="XXX"/>
<cfargument name="secretKey" default="xxx/xxx/xxx"/>
<cfargument name="storageClass" default="STANDARD"/>
<cfargument name="HTTPtimeout" default="300"/>
<cfset var response = ""/>
<cfset var dateTimeString = GetHTTPTimeString(Now())/>
<cfset var contentType = getPageContext().getServletContext().getMimeType(arguments.fileName)/>
<!--- authorization --->
<cfset var cs = "PUT\n\n#contentType#\n#dateTimeString#\nx-amz-acl:#arguments.acl#\nx-amz-storage-class:#arguments.storageClass#\n/#arguments.bucket#/#arguments.fileName#"/>
<cfset var signature = createSignature(cs, arguments.secretKey)/>
<cfset var urlstring = "http://s3.amazonaws.com/#arguments.bucket#/#arguments.fileName#"/>
<cfhttp method="PUT" url="#urlstring#" timeout="#arguments.HTTPtimeout#" result="response">
<cfhttpparam type="header" name="Authorization" value="AWS #arguments.accessKeyId#:#signature#"/>
<cfhttpparam type="header" name="Content-Type" value="#contentType#"/>
<cfhttpparam type="header" name="Date" value="#dateTimeString#"/>
<cfhttpparam type="header" name="x-amz-acl" value="#arguments.acl#"/>
<cfhttpparam type="header" name="x-amz-storage-class" value="#arguments.storageClass#"/>
<cfhttpparam type="body" value="#arguments.data#"/>
</cfhttp>
<cfreturn response/>
</cffunction>
<cffunction name="HMAC_SHA1" returntype="binary" access="private" output="false" hint="NSA SHA-1 Algorithm">
<cfargument name="signKey" type="string" required="true"/>
<cfargument name="signMessage" type="string" required="true"/>
<cfset var jMsg = JavaCast("string",arguments.signMessage).getBytes("iso-8859-1")/>
<cfset var jKey = JavaCast("string",arguments.signKey).getBytes("iso-8859-1")/>
<cfset var key = createObject("java","javax.crypto.spec.SecretKeySpec")/>
<cfset var mac = createObject("java","javax.crypto.Mac")/>
<cfset key = key.init(jKey,"HmacSHA1")/>
<cfset mac = mac.getInstance(key.getAlgorithm())/>
<cfset mac.init(key)/>
<cfset mac.update(jMsg)/>
<cfreturn mac.doFinal()/>
</cffunction>
<cffunction name="createSignature" returntype="string" access="public" output="false">
<cfargument name="in" required="true"/>
<cfargument name="secretKey" required="true"/>
<!--- replace "\n" with "chr(10) to get a correct digest --->
<cfset var fixedData = replace(arguments.in,"\n", chr(10), "all")/>
<!--- calculate the hash of the information --->
<cfset var digest = HMAC_SHA1(arguments.secretKey,fixedData)/>
<!--- fix the returned data to be a proper signature --->
<cfset var signature = ToBase64(digest)/>
<cfreturn signature/>
</cffunction>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment