lib/EC2.rb in kunley-amazon-ec2-0.3.4 vs lib/EC2.rb in kunley-amazon-ec2-0.3.8
- old
+ new
@@ -17,11 +17,23 @@
Dir[File.join(File.dirname(__FILE__), 'EC2/**/*.rb')].sort.each { |lib| require lib }
module EC2
# Which host FQDN will we connect to for all API calls to AWS?
- DEFAULT_HOST = 'ec2.amazonaws.com'
+ # If EC2_URL is defined in the users ENV we can use that. It is
+ # expected that this var is set with something like:
+ # export EC2_URL='https://ec2.amazonaws.com'
+ #
+ if ENV['EC2_URL']
+ EC2_URL = ENV['EC2_URL']
+ VALID_HOSTS = ['https://ec2.amazonaws.com', 'https://us-east-1.ec2.amazonaws.com', 'https://eu-west-1.ec2.amazonaws.com']
+ raise ArgumentError, "Invalid EC2_URL environment variable : #{EC2_URL}" unless VALID_HOSTS.include?(EC2_URL)
+ DEFAULT_HOST = URI.parse(EC2_URL).host
+ else
+ # default US host
+ DEFAULT_HOST = 'ec2.amazonaws.com'
+ end
# This is the version of the API as defined by Amazon Web Services
API_VERSION = '2008-12-01'
# Builds the canonical string for signing. This strips out all '&', '?', and '='
@@ -30,22 +42,22 @@
# case-insensitive alphabetical order and must not be url encoded.
def EC2.canonical_string(params, host = DEFAULT_HOST, method="POST", base="/")
# Sort, and encode parameters into a canonical string.
sorted_params = params.sort {|x,y| x[0] <=> y[0]}
encoded_params = sorted_params.collect do |p|
- encoded = (CGI::escape(p[0].to_s) +
+ encoded = (CGI::escape(p[0].to_s) +
"=" + CGI::escape(p[1].to_s))
# Ensure spaces are encoded as '%20', not '+'
encoded.gsub('+', '%20')
end
sigquery = encoded_params.join("&")
# Generate the request description string
- req_desc =
- method + "\n" +
- host + "\n" +
- base + "\n" +
+ req_desc =
+ method + "\n" +
+ host + "\n" +
+ base + "\n" +
sigquery
end
# Encodes the given string with the secret_access_key, by taking the
@@ -104,18 +116,18 @@
raise ArgumentError, "No :access_key_id provided" if options[:access_key_id].nil? || options[:access_key_id].empty?
raise ArgumentError, "No :secret_access_key provided" if options[:secret_access_key].nil? || options[:secret_access_key].empty?
raise ArgumentError, "No :use_ssl value provided" if options[:use_ssl].nil?
raise ArgumentError, "Invalid :use_ssl value provided, only 'true' or 'false' allowed" unless options[:use_ssl] == true || options[:use_ssl] == false
raise ArgumentError, "No :server provided" if options[:server].nil? || options[:server].empty?
-
-
- # based on the :use_ssl boolean, determine which port we should connect to
- case @use_ssl
- when true
+
+ if options[:port]
+ # user-specified port
+ @port = options[:port]
+ elsif @use_ssl
# https
@port = 443
- when false
+ else
# http
@port = 80
end
@access_key_id = options[:access_key_id]
@@ -168,11 +180,11 @@
"SignatureMethod" => 'HmacSHA1',
"AWSAccessKeyId" => @access_key_id,
"Version" => API_VERSION,
"Timestamp"=>Time.now.getutc.iso8601} )
- sig = get_aws_auth_param(params, @secret_access_key)
+ sig = get_aws_auth_param(params, @secret_access_key, @server)
query = params.sort.collect do |param|
CGI::escape(param[0]) + "=" + CGI::escape(param[1])
end.join("&") + "&Signature=" + sig
@@ -191,12 +203,12 @@
end
end
# Set the Authorization header using AWS signed header authentication
- def get_aws_auth_param(params, secret_access_key)
- canonical_string = EC2.canonical_string(params)
+ def get_aws_auth_param(params, secret_access_key, server)
+ canonical_string = EC2.canonical_string(params, server)
encoded_canonical = EC2.encode(secret_access_key, canonical_string)
end
# allow us to have a one line call in each method which will do all of the work
# in making the actual request to AWS.
@@ -246,10 +258,10 @@
# Raise one of our specific error classes if it exists.
# otherwise, throw a generic EC2 Error with a few details.
if EC2.const_defined?(error_code)
raise EC2.const_get(error_code), error_message
else
- raise Error, "This is an undefined error code which needs to be added to exceptions.rb : error_code => #{error_code} : error_message => #{error_message}"
+ raise EC2::Error, error_message
end
end
end