Skip to content

Instantly share code, notes, and snippets.

@robertz
Created July 19, 2016 14:13
Show Gist options
  • Save robertz/cfd7973e3700e44fe0554d98be1fb15e to your computer and use it in GitHub Desktop.
Save robertz/cfd7973e3700e44fe0554d98be1fb15e to your computer and use it in GitHub Desktop.
component {
/*
Parts of this are based on Tim Dawe's
http://amazonsig.riaforge.org
and
Joe Danziger's Amazon S3 REST Wrapper
http://amazons3.riaforge.org/
Written by Patrick Liess
Twitter: @smrchy
http://www.tcs.de
Non-SQS specific code removed and moved to CFScript
*/
public SQSService function init() {
// Handle any init specific code here
this.awsAccessKeyID = "[awsAccessKeyID]";
this.secretAccessKey = "[secretAccessKey]";
this.SQSVersion = "2009-02-01";
this.SQSServiceURL = "http://queue.amazonaws.com/";
return this;
}
public string function sendMessage(required string queue, required string message) {
var reqURL = this.SQSserviceUrl & arguments.queue &
"?Action=SendMessage" &
"&MessageBody=" & URLEncodedFormat(arguments.message,"utf-8") &
"&Version=" & this.SQSVersion;
reqURL = signRequest(requrl,"GET");
cfhttp(method = "GET", url = reqURL, charset = "utf-8");
return cfhttp.fileContent;
}
public string function receiveMessage(required string queue) {
var reqURL = this.SQSServiceURL & arguments.queue &
"?Action=ReceiveMessage" &
"&AttributeName=None" &
"&MaxNumberOfMessages=10" &
"&Version=" & this.SQSVersion;
reqURL = signRequest(reqURL, "GET");
cfhttp(method = "GET", url = reqURL, charset = "utf-8");
return cfhttp.fileContent;
}
public struct function deleteMessage(required string queue, required string receiptHandle) {
var reqURL = this.SQSserviceUrl & arguments.queue &
"?Action=DeleteMessage" &
"&ReceiptHandle=" & URLEncodedFormat(Arguments.receipthandle,"utf-8") &
"&Version=" & this.SQSVersion;
reqURL = signRequest(requrl, "GET");
cfhttp(method = "GET", url = reqURL, charset = "utf-8");
return cfhttp;
}
// Utility Functions
public string function signRequest(required string request, string method default = "GET") {
var lc = {};
// Extract the URL part of the request and strip the protocol
lc.requesturl = listfirst(arguments.request, "?");
lc.requesturl = replacenocase(lc.requesturl, "http://", "");
// Split into host and path
lc.host = listfirst(lc.requesturl, "/");
lc.path = right(lc.requesturl, len(lc.requesturl) - len(lc.host));
// Process the query string parameters into a structure
lc.querystring = listlast(arguments.request, "?");
lc.strParams = {};
var queryArray = listToArray(lc.queryString, "&");
for (var i in queryArray) {
lc.strParams[listfirst(i, "=")] = urldecode(listlast(i, "="));
}
// Add the timestamp
if (not StructKeyExists(lc.strParams, "Timestamp")) {
lc.utcdate = dateconvert("local2Utc", now());
lc.strParams["Timestamp"] = dateformat(lc.utcdate, 'yyyy-mm-dd') & "T" & timeformat(lc.utcdate, 'HH:mm:ss') & "Z";
}
// Add the standard parameters
lc.strParams["AWSAccessKeyId"] = this.awsAccessKeyId;
lc.strParams["SignatureVersion"] = 2;
lc.strParams["SignatureMethod"] = "HmacSHA1";
// Sort the parameters
lc.keys = listsort(structkeylist(lc.strParams), "text");
// Generate a new query string including timestamp, with parameters in the correct order, encoding as we go
lc.qs = "";
for(i in lc.keys) {
lc.qs = lc.qs & rfc3986EncodedFormat(i) & "=" & rfc3986EncodedFormat(lc.strParams[i]) & "&";
}
// Strip off the last &
lc.qs = left(lc.qs, len(lc.qs)-1);
// Build the string to sign
lc.stringToSign = arguments.method & chr(10);
lc.stringToSign = lc.stringToSign & lc.host & chr(10);
lc.stringToSign = lc.stringToSign & lc.path & chr(10);
lc.stringToSign = lc.stringToSign & lc.qs;
lc.signature = HMAC_SHA1(lc.stringToSign);
// Return the new request URL
return "http://" & lc.host & lc.path & "?" & lc.qs & "&Signature=" & urlencodedformat(tobase64(lc.signature));
}
private binary function HMAC_SHA1(required string signMessage) {
var jMsg = JavaCast("string",arguments.signMessage).getBytes("iso-8859-1");
var jKey = JavaCast("string",this.secretAccessKey).getBytes("iso-8859-1");
var key = createObject("java","javax.crypto.spec.SecretKeySpec");
var mac = createObject("java","javax.crypto.Mac");
key = key.init(jKey,"HmacSHA1");
mac = mac.getInstance(key.getAlgorithm());
mac.init(key);
mac.update(jMsg);
return mac.doFinal();
}
public string function createSignature(required string stringIn) {
var fixedData = replace(arguments.stringIn,"\n","#chr(10)#","all");
var digest = HMAC_SHA1(fixedData);
var signature = toBase64(digest);
return signature;
}
public string function rfc3986EncodedFormat(required string text) {
var lc = {};
lc.objNet = createObject("java","java.net.URLEncoder");
lc.encodedText = lc.objNet.encode(arguments.text, 'utf-8').replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
return lc.encodedText;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment