right_aws 3.0.0 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -327,3 +327,15 @@ the source key.
327
327
  - SDB: ConsistentRead support
328
328
  - bunch of micro bugs
329
329
 
330
+ === 3.0.1
331
+ Release Notes:
332
+ - Fixed:
333
+ - SignatureDoesNotMatch on file download via get_link()
334
+ - S3#bucket should not fail for non admin creds
335
+ - couple doc typos
336
+
337
+ === 3.0.2
338
+ Release Notes:
339
+ - Fixed:
340
+ - S3 Content-Type not set in Ruby 1.9.2
341
+ - error in rds_interface describe_db_snapshots in Ruby 1.9.2
@@ -126,6 +126,7 @@ module RightAws
126
126
  path += "?" + params.to_a.collect{ |key,val| "#{AwsUtils::amz_escape(key)}=#{AwsUtils::amz_escape(val.to_s)}" }.join("&")
127
127
  end
128
128
  # Headers
129
+ headers = AwsUtils::fix_headers(headers)
129
130
  headers['content-type'] ||= 'text/xml' if body
130
131
  headers['date'] = Time.now.httpdate
131
132
  # Auth
@@ -43,9 +43,10 @@ module RightAws
43
43
  Base64.encode64(OpenSSL::HMAC.digest(@@digest1, aws_secret_access_key, auth_string)).strip
44
44
  end
45
45
 
46
- # Escape a string accordingly Amazon rulles
46
+ # Escape a string accordingly Amazon rules
47
47
  # http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?REST_RESTAuth.html
48
48
  def self.amz_escape(param)
49
+ param = param.flatten.join('') if param.is_a?(Array) # ruby 1.9.x Array#to_s fix
49
50
  param.to_s.gsub(/([^a-zA-Z0-9._~-]+)/n) do
50
51
  '%' + $1.unpack('H2' * $1.size).join('%').upcase
51
52
  end
@@ -66,6 +67,16 @@ module RightAws
66
67
  service_hash
67
68
  end
68
69
 
70
+ def self.fix_headers(headers)
71
+ result = {}
72
+ headers.each do |header, value|
73
+ next if !header.is_a?(String) || value.nil?
74
+ header = header.downcase
75
+ result[header] = value if result[header].right_blank?
76
+ end
77
+ result
78
+ end
79
+
69
80
  # Signature Version 0
70
81
  # A deprecated guy (should work till septemper 2009)
71
82
  def self.sign_request_v0(aws_secret_access_key, service_hash)
@@ -2,7 +2,7 @@ module RightAws #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 3 unless defined?(MAJOR)
4
4
  MINOR = 0 unless defined?(MINOR)
5
- TINY = 0 unless defined?(TINY)
5
+ TINY = 3 unless defined?(TINY)
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.') unless defined?(STRING)
8
8
  end
@@ -162,7 +162,9 @@ module RightAws
162
162
  # :root_device_name => "/dev/sda1",
163
163
  # :block_device_mappings => [ { :ebs_snapshot_id=>"snap-7360871a",
164
164
  # :ebs_delete_on_termination=>true,
165
- # :device_name=>"/dev/sda1"} ] }
165
+ # :device_name=>"/dev/sda1"},
166
+ # { :virtual_name => 'ephemeral0',}
167
+ # :device_name=>"/dev/sdb"} ]
166
168
  # ec2.register_image(image_reg_params) #=> "ami-b2a1f7a4"
167
169
  #
168
170
  def register_image(options)
@@ -345,6 +345,7 @@ module RightAws
345
345
  :tags => {}}
346
346
  when %r{/routeSet/item$} then @route_set = {}
347
347
  when %r{/associationSet/item$} then @association_set = {}
348
+ when %r{/tagSet/item$} then @aws_tag = {}
348
349
  end
349
350
  end
350
351
  def tagend(name)
@@ -206,6 +206,7 @@ module RightAws
206
206
  path += "?" + params.to_a.collect{ |key,val| "#{AwsUtils::amz_escape(key)}=#{AwsUtils::amz_escape(val.to_s)}" }.join("&")
207
207
  end
208
208
  # Headers
209
+ headers = AwsUtils::fix_headers(headers)
209
210
  headers['content-type'] ||= 'text/xml' if body
210
211
  headers['date'] = Time.now.httpdate
211
212
  # Auth
@@ -97,10 +97,24 @@ module RightAws
97
97
  # (section: Canned Access Policies)
98
98
  #
99
99
  def bucket(name, create=false, perms=nil, headers={})
100
- headers['x-amz-acl'] = perms if perms
101
- @interface.create_bucket(name, headers) if create
102
- buckets.each { |bucket| return bucket if bucket.name == name }
103
- nil
100
+ result = nil
101
+ if create
102
+ headers['x-amz-acl'] = perms if perms
103
+ @interface.create_bucket(name, headers)
104
+ end
105
+ begin
106
+ buckets.each do |bucket|
107
+ if bucket.name == name
108
+ result = bucket
109
+ break
110
+ end
111
+ end
112
+ rescue RightAws::AwsError => e
113
+ # With non root creds one can use bucket(s) but can't list them
114
+ raise e unless e.message['AccessDenied']
115
+ result = Bucket::new(self, name)
116
+ end
117
+ result
104
118
  end
105
119
 
106
120
 
@@ -78,10 +78,11 @@ module RightAws
78
78
  #
79
79
  # Params is a hash:
80
80
  #
81
- # {:server => 's3.amazonaws.com' # Amazon service host: 's3.amazonaws.com'(default)
82
- # :port => 443 # Amazon service port: 80 or 443(default)
83
- # :protocol => 'https' # Amazon service protocol: 'http' or 'https'(default)
84
- # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
81
+ # {:server => 's3.amazonaws.com' # Amazon service host: 's3.amazonaws.com'(default)
82
+ # :port => 443 # Amazon service port: 80 or 443(default)
83
+ # :protocol => 'https' # Amazon service protocol: 'http' or 'https'(default)
84
+ # :logger => Logger Object # Logger instance: logs to STDOUT if omitted
85
+ # :no_subdomains => true} # Force placing bucket name into path instead of domain name
85
86
  #
86
87
  def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
87
88
  init({ :name => 'S3',
@@ -174,8 +175,8 @@ module RightAws
174
175
  # calculate request data
175
176
  server, path, path_to_sign = fetch_request_params(headers)
176
177
  data = headers[:data]
177
- # remove unset(==optional) and symbolyc keys
178
- headers.each{ |key, value| headers.delete(key) if (value.nil? || key.is_a?(Symbol)) }
178
+ # make sure headers are downcased strings
179
+ headers = AwsUtils::fix_headers(headers)
179
180
  #
180
181
  headers['content-type'] ||= ''
181
182
  headers['date'] = Time.now.httpdate
@@ -851,17 +852,22 @@ module RightAws
851
852
  # Query API: Links
852
853
  #-----------------------------------------------------------------
853
854
 
855
+ def s3_link_escape(text)
856
+ #CGI::escape(text.to_s).gsub(/[+]/, '%20')
857
+ AwsUtils::amz_escape(text.to_s)
858
+ end
859
+
854
860
  # Generates link for QUERY API
855
861
  def generate_link(method, headers={}, expires=nil) #:nodoc:
856
862
  # calculate request data
857
863
  server, path, path_to_sign = fetch_request_params(headers)
858
- path_to_sign = CGI.unescape(path_to_sign)
864
+
859
865
  # expiration time
860
866
  expires ||= DEFAULT_EXPIRES_AFTER
861
867
  expires = Time.now.utc + expires if expires.is_a?(Fixnum) && (expires < ONE_YEAR_IN_SECONDS)
862
868
  expires = expires.to_i
863
- # remove unset(==optional) and symbolyc keys
864
- headers.each{ |key, value| headers.delete(key) if (value.nil? || key.is_a?(Symbol)) }
869
+ # make sure headers are downcased strings
870
+ headers = AwsUtils::fix_headers(headers)
865
871
  #generate auth strings
866
872
  auth_string = canonical_string(method, path_to_sign, headers, expires)
867
873
  signature = CGI::escape(AwsUtils::sign( @aws_secret_access_key, auth_string))
@@ -908,7 +914,7 @@ module RightAws
908
914
  # s3.list_bucket_link('my_awesome_bucket') #=> url string
909
915
  #
910
916
  def list_bucket_link(bucket, options=nil, expires=nil, headers={})
911
- bucket += '?' + options.map{|k, v| "#{k.to_s}=#{CGI::escape v.to_s}"}.join('&') unless options.right_blank?
917
+ bucket += '?' + options.map{|k, v| "#{k.to_s}=#{s3_link_escape(v)}"}.join('&') unless options.right_blank?
912
918
  generate_link('GET', headers.merge(:url=>bucket), expires)
913
919
  rescue
914
920
  on_exception
@@ -919,7 +925,7 @@ module RightAws
919
925
  # s3.put_link('my_awesome_bucket',key, object) #=> url string
920
926
  #
921
927
  def put_link(bucket, key, data=nil, expires=nil, headers={})
922
- generate_link('PUT', headers.merge(:url=>"#{bucket}/#{CGI::escape key}", :data=>data), expires)
928
+ generate_link('PUT', headers.merge(:url=>"#{bucket}/#{s3_link_escape(key)}", :data=>data), expires)
923
929
  rescue
924
930
  on_exception
925
931
  end
@@ -945,11 +951,11 @@ module RightAws
945
951
  #
946
952
  def get_link(bucket, key, expires=nil, headers={}, response_params={})
947
953
  if response_params.size > 0
948
- response_params = '?' + response_params.map { |k, v| "#{k}=#{CGI::escape(v).gsub(/[+]/, '%20')}" }.join('&')
954
+ response_params = '?' + response_params.map { |k, v| "#{k}=#{s3_link_escape(v)}" }.join('&')
949
955
  else
950
956
  response_params = ''
951
957
  end
952
- generate_link('GET', headers.merge(:url=>"#{bucket}/#{CGI::escape key}#{response_params}"), expires)
958
+ generate_link('GET', headers.merge(:url=>"#{bucket}/#{s3_link_escape(key)}#{response_params}"), expires)
953
959
  rescue
954
960
  on_exception
955
961
  end
@@ -959,7 +965,7 @@ module RightAws
959
965
  # s3.head_link('my_awesome_bucket',key) #=> url string
960
966
  #
961
967
  def head_link(bucket, key, expires=nil, headers={})
962
- generate_link('HEAD', headers.merge(:url=>"#{bucket}/#{CGI::escape key}"), expires)
968
+ generate_link('HEAD', headers.merge(:url=>"#{bucket}/#{s3_link_escape(key)}"), expires)
963
969
  rescue
964
970
  on_exception
965
971
  end
@@ -969,7 +975,7 @@ module RightAws
969
975
  # s3.delete_link('my_awesome_bucket',key) #=> url string
970
976
  #
971
977
  def delete_link(bucket, key, expires=nil, headers={})
972
- generate_link('DELETE', headers.merge(:url=>"#{bucket}/#{CGI::escape key}"), expires)
978
+ generate_link('DELETE', headers.merge(:url=>"#{bucket}/#{s3_link_escape(key)}"), expires)
973
979
  rescue
974
980
  on_exception
975
981
  end
@@ -980,7 +986,7 @@ module RightAws
980
986
  # s3.get_acl_link('my_awesome_bucket',key) #=> url string
981
987
  #
982
988
  def get_acl_link(bucket, key='', headers={})
983
- return generate_link('GET', headers.merge(:url=>"#{bucket}/#{CGI::escape key}?acl"))
989
+ return generate_link('GET', headers.merge(:url=>"#{bucket}/#{s3_link_escape(key)}?acl"))
984
990
  rescue
985
991
  on_exception
986
992
  end
@@ -990,7 +996,7 @@ module RightAws
990
996
  # s3.put_acl_link('my_awesome_bucket',key) #=> url string
991
997
  #
992
998
  def put_acl_link(bucket, key='', headers={})
993
- return generate_link('PUT', headers.merge(:url=>"#{bucket}/#{CGI::escape key}?acl"))
999
+ return generate_link('PUT', headers.merge(:url=>"#{bucket}/#{s3_link_escape(key)}?acl"))
994
1000
  rescue
995
1001
  on_exception
996
1002
  end
@@ -31,7 +31,6 @@ Gem::Specification.new do |spec|
31
31
  spec.authors = ['RightScale, Inc.']
32
32
  spec.email = 'support@rightscale.com'
33
33
  spec.summary = 'Interface classes for the Amazon EC2, SQS, and S3 Web Services'
34
- spec.has_rdoc = true
35
34
  spec.rdoc_options = ['--main', 'README.txt', '--title', '']
36
35
  spec.extra_rdoc_files = ['README.txt']
37
36
  spec.required_ruby_version = '>= 1.8.7'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: right_aws
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 0
10
- version: 3.0.0
9
+ - 3
10
+ version: 3.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - RightScale, Inc.
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-11-15 00:00:00 Z
18
+ date: 2012-03-08 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: right_http_connection
@@ -220,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
220
  requirements:
221
221
  - libxml-ruby >= 0.5.2.0 is encouraged
222
222
  rubyforge_project: rightaws
223
- rubygems_version: 1.7.2
223
+ rubygems_version: 1.8.17
224
224
  signing_key:
225
225
  specification_version: 3
226
226
  summary: Interface classes for the Amazon EC2, SQS, and S3 Web Services