right_aws 3.0.0 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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