1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
require 'net/https'
require 'time'
require 'cgi'
require 'openssl'
require 'base64'

# strings are UTF-8 encoded
$KCODE = "u"

ACCESS_KEY = ""
SECRET_ACCESS_KEY = ""

# Hash doesn't store contents in order entered
params = Hash.new
params["Action"] = "GetAccountBalance"
params["AWSAccessKeyId"] = ACCESS_KEY
params["SignatureVersion"] = "1"
params["Timestamp"] = Time.now.gmtime.iso8601
params["Version"] = "2007-01-08"

# case-insensitive sort by Hash key
params = params.sort_by { |hash| hash[0].downcase }

# create digest of concatenated params
digest = OpenSSL::Digest::Digest.new('sha1')
hmac = OpenSSL::HMAC.digest(digest, SECRET_ACCESS_KEY, params.to_s)
signature = Base64.encode64(hmac).chomp

# params are URL-encoding, also add '=' and '&'
query = params.collect {|key, value| key+"="+CGI.escape(value)}.join("&")
# signature is URL-encoded, goes on end of URL (not sorted with other params)
query += "&Signature=#{CGI.escape(signature)}"

# make request
http = Net::HTTP.new('fps.sandbox.amazonaws.com', 443)
http.use_ssl = true
req = Net::HTTP::Get.new('/?' + query)
res = http.start { |http|
  http.request(req)
}

# output XML response
puts res.body