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