Questions about Amazon AWS integration

I’m trying to use Amazon AWS simpleDB for a project and I am running into an issue with the required signature. I’m hoping someone on here has either successfully incorporated an AWS service, or can at least help me find some functions I “might” be missing.

First, has anyone done this with AWS before?

I’ve read online that a possible hang up might be that my secret key is not URL encoded, or that the signature is not. Both look like they need to be encoded (one has a “/” in it, the other two "="s. But I cannot find in the documentation or on the forum how to simply url encode a string.

Any (and all) help will be greatly appreciated. Thanks in advance. [import]uid: 64596 topic_id: 22449 reply_id: 322449[/import]

Did you ever figure this out? [import]uid: 13020 topic_id: 22449 reply_id: 96179[/import]

Yes, we finally figured this out. But then we realized our project would also require the use of a server for another part of it, something we are not prepared at this time to pursue, so the project has been shelved. Unfortunately the code I have is just hacked together at this point to prove it will work, so it isn’t pretty enough to post right off.

If you are looking to try this and have any specific questions, please, ask them. I’ll try to get you as far along as I can. [import]uid: 64596 topic_id: 22449 reply_id: 96197[/import]

Well, I think I know (maybe) how to send a REST request, I’m just not sure how to use crypto to create a signature for the request.

Also need to figure out how to make a valid timestamp, but I think I can figure that one out on my own, maybe.

Any help would definitely be appreciated! [import]uid: 13020 topic_id: 22449 reply_id: 96201[/import]

Okay I warned you, it’s ugly, but here are the a few of the functions I built to get simpleDB working:

First, I created two variables, aKey and sKey, to hold my Amazon access and secret keys, respectively.

Be sure to include the following required modules:

local crypto = require("crypto")  
local mime = require("mime")  

The first set of code is my quick solution to creating a timestamp:

function twoDigit(n)  
 local r = tostring(n)  
 if string.len(r) \< 2 then  
 r = "0"..r;  
 end  
 return r  
end  
  
function getTime()  
 local date = os.date("!\*t")  
 return date.year.."-"..twoDigit(date.month).."-"..twoDigit(date.day).."T"..twoDigit(date.hour).."%3A"..twoDigit(date.min).."%3A"..twoDigit(date.sec).."Z"  
end  

The next piece of code is the hash generator signature thingy (yes, technical term) borrowed from bob.dickinson (thanks Bob!)

local function sha1\_hmac( key, text )  
  
 return crypto.hmac(crypto.sha1, text, key, true)  
  
end  

The following is my Create a Domain function, where the passed-in-variable “name” is the name to call the domain.

function createDomain(name)  
  
 local timeStamp = getTime()  
  
 local toSign = "GET\nsdb.amazonaws.com\n/\nAWSAccessKeyId="..aKey.."&Action=CreateDomain&DomainName="..name.."&SignatureMethod=HmacSHA1&SignatureVersion=2&Timestamp="..timeStamp.."&Version=2009-04-15"  
  
 local signature = mime.b64(sha1\_hmac(sKey, toSign))  
  
 local myURL = "https://sdb.amazonaws.com/?Action=CreateDomain&AWSAccessKeyId="..aKey.."&DomainName="..name.."&SignatureVersion=2&SignatureMethod=HmacSHA1&Timestamp="..timeStamp.."&Version=2009-04-15&Signature="..signature  
  
 local function networkListener( event )  
 if ( event.isError ) then  
 print( "Network error!")  
 else  
 print ( "RESPONSE: " .. event.response )  
  
 save(event.response)  
 end  
 end  
  
 network.request( myURL, "GET", networkListener )  
  
end  

This next code lists the domains:

function listDomains()  
  
 local timeStamp = getTime()  
  
 local toSign = "GET\nsdb.amazonaws.com\n/\nAWSAccessKeyId="..aKey.."&Action=ListDomains&SignatureMethod=HmacSHA1&SignatureVersion=2&Timestamp="..timeStamp.."&Version=2009-04-15"  
  
 local signature = mime.b64(sha1\_hmac(sKey, toSign))  
  
 local myURL = "https://sdb.amazonaws.com/?Action=ListDomains&AWSAccessKeyId="..aKey.."&SignatureVersion=2&SignatureMethod=HmacSHA1&Timestamp="..timeStamp.."&Version=2009-04-15&Signature="..signature  
  
 local function networkListener( event )  
 if ( event.isError ) then  
 print( "Network error!")  
 else  
 print ( "RESPONSE: " .. event.response )  
  
 save(event.response)  
 end  
 end  
  
 network.request( myURL, "GET", networkListener )  
  
end  

This next code performs a “Get Attributes” call. Please note that I hard-coded into the strings the attribute and item names just to get the code tested. Like I said, I shelved this project due to other concerns. Again, the passed-in-variable “name” is the domain you are checking.

function getAttributes(name)  
  
 local timeStamp = getTime()  
  
 local toSign = "GET\nsdb.amazonaws.com\n/\nAWSAccessKeyId="..aKey.."&Action=GetAttributes&AttributeName.1=theTest&DomainName="..name.."&ItemName=item\_01&SignatureMethod=HmacSHA1&SignatureVersion=2&Timestamp="..timeStamp.."&Version=2009-04-15"  
  
 local signature = mime.b64(sha1\_hmac(sKey, toSign))  
  
 local myURL = "https://sdb.amazonaws.com/?Action=GetAttributes&AWSAccessKeyId="..aKey.."&AttributeName.1=theTest&DomainName="..name.."&ItemName=item\_01&SignatureVersion=2&SignatureMethod=HmacSHA1&Timestamp="..timeStamp.."&Version=2009-04-15&Signature="..signature  
  
 local function networkListener( event )  
 if ( event.isError ) then  
 print( "Network error!")  
 else  
 print ( "RESPONSE: " .. event.response )  
  
 save(event.response)  
 end  
 end  
  
 network.request( myURL, "GET", networkListener )  
  
end  

So, there you go. Frankencode. But it should get you started. If someone makes use of this please consider submitting a cleaned up version to the code base. Thanks. [import]uid: 64596 topic_id: 22449 reply_id: 96205[/import]

Wow, that is amazing, and so much more than I hoped for. That makes my weekend!
Yes, that should be enough I think; it all makes sense, just didn’t know how to write it.

Thanks again. [import]uid: 13020 topic_id: 22449 reply_id: 96209[/import]

Always glad to help :slight_smile: [import]uid: 64596 topic_id: 22449 reply_id: 96210[/import]

Cool, thanks for the starter code.

It may be worth noting that adding crypto (HTTPS/SSL) means that you are supposed to get special approval for your app.

http://tigelane.blogspot.com/2011/01/apple-itunes-export-restrictions-on.html

[import]uid: 1560 topic_id: 22449 reply_id: 96212[/import]

@Dotnaught,

Yes, that was one of the things that dissuaded us from pursuing this particular project via Amazon. The signature process requires us to use crypto. It may not be that big a deal to get approval, but we are on to other things at the moment.

Thanks, though, for ensuring this is a complete discussion. [import]uid: 64596 topic_id: 22449 reply_id: 96214[/import]

@shane.lipscomb
Thanks a lot for the code.

I’ve posted a decently patched up version in Code Exchange
http://developer.anscamobile.com/code/amazon-simpledb-api [import]uid: 64174 topic_id: 22449 reply_id: 103214[/import]