Monday, November 08, 2010 at 12:01 AM.
system.verbs.apps.s3.simpleDb.httpClient
on httpClient (action, adrparams=nil, adrerrorstring=nil, adrxstruct=nil) {
<<Changes
<<1/4/08; 3:59:25 PM by DW
<<Created. Factored from createDomain. A template for all the calls to SimpleDb.
<<http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/
on hmac (data, key) {
<<Changes
<<3/27/06; 5:57:47 PM by LMO
<<Initial implementation, stolen from Digest::HMAC in Perl
local (BLOCK_SIZE=64);
on sha1 (data) {
<<See: http://www.spicynoodles.net/projects/crypto.html
return (crypto.hashSHA1(data, false))};
local(k_ipad, k_opad, i);
if string.length (key) > BLOCK_SIZE {
key = sha1 (key)};
for i = 0 to BLOCK_SIZE-1 {
if i < string.length(key) {
<<XOR characters of the key
k_char = string.nthChar(key, i+1);
k_ipad = k_ipad + char(bit.logicalXor(k_char, char(0x36)));
k_opad = k_opad + char(bit.logicalXor(k_char, char(0x5c)))}
else {
<<Pad out the rest of the block size length
k_ipad = k_ipad + char(0x36);
k_opad = k_opad + char(0x5c)}};
return (sha1 (k_opad + sha1 (k_ipad + data)))};
local (sigtable, paramstring = "");
new (tabletype, @sigtable);
on pushparam (name, value) {
sigtable.[name] = value;
paramstring = paramstring + name + "=" + string.urlencode (value, true) + "&"};
pushparam ("Action", action);
pushparam ("AWSAccessKeyId", user.s3.accounts.default.AWSAccessKeyId);
if adrparams != nil {
local (adr);
for adr in adrparams {
pushparam (nameof (adr^), string (adr^))}};
pushparam ("SignatureVersion", 1);
pushparam ("Timestamp", s3.simpleDb.getTimeStamp (clock.now ()));
pushparam ("Version", "2007-11-07");
local (sigstring = "");
bundle { //set sigstring
local (adr);
for adr in @sigtable {
sigstring = sigstring + nameof (adr^) + string (adr^)}};
paramstring = paramstring + "Signature=" + string.urlencode (base64.encode (hmac (sigstring, user.s3.accounts.default.SecretAccessKey), 0), true);
local (url = "https://sdb.amazonaws.com/?" + paramstring);
scratchpad.url = url;
<<url = string.replaceall (url, "&", "\\&")
<<local (xmltext = sys.unixshellcommand ("curl " + url))
local (xmltext = tcp.httpreadurl (url, flMessages:false));
xml.compile (xmltext, @xstruct);
scratchpad.xstruct = xstruct;
try {
local (adrresponse = xml.getaddress (@xstruct, "Response"));
local (adrerrors = xml.getaddress (adrresponse, "Errors"));
local (adrerror = xml.getaddress (adrerrors, "Error"));
local (errorstring = xml.getvalue (adrerror, "Message"));
if adrerrorstring != nil {
adrerrorstring^ = errorstring};
return (false)};
if adrxstruct != nil {
adrxstruct^ = xstruct};
return (true)}; //no error return
bundle { //test code
local (t, errorstring);
new (tabletype, @t);
t.DomainName = "Iowa";
if not httpClient ("CreateDomain", @t, @errorstring) {
dialog.alert (errorstring)}}
This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.