aws 2.4.5 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +9 -75
- data/lib/acf/acf_interface.rb +6 -4
- data/lib/aws.rb +2 -1
- data/lib/awsbase/awsbase.rb +98 -65
- data/lib/awsbase/errors.rb +9 -5
- data/lib/awsbase/parsers.rb +226 -226
- data/lib/awsbase/utils.rb +255 -207
- data/lib/ec2/ec2.rb +243 -105
- data/lib/ec2/mon_interface.rb +2 -1
- data/lib/iam/iam.rb +31 -25
- data/lib/right_aws.rb +1 -1
- data/lib/s3/bucket.rb +7 -8
- data/lib/s3/grantee.rb +238 -238
- data/lib/s3/key.rb +281 -281
- data/lib/s3/s3.rb +2 -1
- data/lib/s3/s3_interface.rb +45 -35
- data/lib/sdb/active_sdb.rb +19 -22
- data/lib/sdb/sdb_interface.rb +4 -5
- data/lib/ses/ses.rb +123 -0
- data/lib/sqs/sqs.rb +5 -0
- data/lib/sqs/sqs_interface.rb +3 -3
- metadata +53 -104
- data/lib/awsbase/support.rb +0 -142
- data/test/acf/test_acf.rb +0 -148
- data/test/acf/test_helper.rb +0 -2
- data/test/ec2/test_ec2.rb +0 -205
- data/test/ec2/test_helper.rb +0 -2
- data/test/ec2/test_mon.rb +0 -17
- data/test/elb/test_elb.rb +0 -51
- data/test/http_connection.rb +0 -87
- data/test/iam/test_iam.rb +0 -36
- data/test/rds/test_rds.rb +0 -181
- data/test/s3/s3_test_base.rb +0 -23
- data/test/s3/test_helper.rb +0 -3
- data/test/s3/test_s3.rb +0 -162
- data/test/s3/test_s3_class.rb +0 -179
- data/test/s3/test_s3_rights.rb +0 -139
- data/test/s3/test_s3_stubbed.rb +0 -97
- data/test/sdb/test_active_sdb.rb +0 -338
- data/test/sdb/test_helper.rb +0 -3
- data/test/sdb/test_sdb.rb +0 -220
- data/test/sqs/test_helper.rb +0 -2
- data/test/sqs/test_sqs.rb +0 -232
- data/test/test_credentials.rb +0 -54
- data/test/ts_right_aws.rb +0 -13
data/lib/awsbase/utils.rb
CHANGED
@@ -1,207 +1,255 @@
|
|
1
|
-
module Aws
|
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
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# puts 'full=' + ret.inspect
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
# puts '
|
123
|
-
|
124
|
-
|
125
|
-
#
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
#
|
133
|
-
#
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
1
|
+
module Aws
|
2
|
+
|
3
|
+
class Utils #:nodoc:
|
4
|
+
@@digest1 = OpenSSL::Digest::Digest.new("sha1")
|
5
|
+
@@digest256 = nil
|
6
|
+
if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00908000
|
7
|
+
@@digest256 = OpenSSL::Digest::Digest.new("sha256") rescue nil # Some installation may not support sha256
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.sign(aws_secret_access_key, auth_string)
|
11
|
+
Base64.encode64(OpenSSL::HMAC.digest(@@digest1, aws_secret_access_key, auth_string)).strip
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
# Set a timestamp and a signature version
|
16
|
+
def self.fix_service_params(service_hash, signature)
|
17
|
+
service_hash["Timestamp"] ||= Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.000Z") unless service_hash["Expires"]
|
18
|
+
service_hash["SignatureVersion"] = signature
|
19
|
+
service_hash
|
20
|
+
end
|
21
|
+
|
22
|
+
# Signature Version 0
|
23
|
+
# A deprecated guy (should work till septemper 2009)
|
24
|
+
def self.sign_request_v0(aws_secret_access_key, service_hash)
|
25
|
+
fix_service_params(service_hash, '0')
|
26
|
+
string_to_sign = "#{service_hash['Action']}#{service_hash['Timestamp'] || service_hash['Expires']}"
|
27
|
+
service_hash['Signature'] = Utils::sign(aws_secret_access_key, string_to_sign)
|
28
|
+
service_hash.to_a.collect { |key, val| "#{amz_escape(key)}=#{amz_escape(val.to_s)}" }.join("&")
|
29
|
+
end
|
30
|
+
|
31
|
+
# Signature Version 1
|
32
|
+
# Another deprecated guy (should work till septemper 2009)
|
33
|
+
def self.sign_request_v1(aws_secret_access_key, service_hash)
|
34
|
+
fix_service_params(service_hash, '1')
|
35
|
+
string_to_sign = service_hash.sort { |a, b| (a[0].to_s.downcase)<=>(b[0].to_s.downcase) }.to_s
|
36
|
+
service_hash['Signature'] = Utils::sign(aws_secret_access_key, string_to_sign)
|
37
|
+
service_hash.to_a.collect { |key, val| "#{amz_escape(key)}=#{amz_escape(val.to_s)}" }.join("&")
|
38
|
+
end
|
39
|
+
|
40
|
+
# Signature Version 2
|
41
|
+
# EC2, SQS and SDB requests must be signed by this guy.
|
42
|
+
# See: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?REST_RESTAuth.html
|
43
|
+
# http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1928
|
44
|
+
def self.sign_request_v2(aws_secret_access_key, service_hash, http_verb, host, uri)
|
45
|
+
fix_service_params(service_hash, '2')
|
46
|
+
# select a signing method (make an old openssl working with sha1)
|
47
|
+
# make 'HmacSHA256' to be a default one
|
48
|
+
service_hash['SignatureMethod'] = 'HmacSHA256' unless ['HmacSHA256', 'HmacSHA1'].include?(service_hash['SignatureMethod'])
|
49
|
+
service_hash['SignatureMethod'] = 'HmacSHA1' unless @@digest256
|
50
|
+
# select a digest
|
51
|
+
digest = (service_hash['SignatureMethod'] == 'HmacSHA256' ? @@digest256 : @@digest1)
|
52
|
+
# form string to sign
|
53
|
+
canonical_string = service_hash.keys.sort.map do |key|
|
54
|
+
"#{amz_escape(key)}=#{amz_escape(service_hash[key])}"
|
55
|
+
end.join('&')
|
56
|
+
string_to_sign = "#{http_verb.to_s.upcase}\n#{host.downcase}\n#{uri}\n#{canonical_string}"
|
57
|
+
# sign the string
|
58
|
+
signature = escape_sig(Base64.encode64(OpenSSL::HMAC.digest(digest, aws_secret_access_key, string_to_sign)).strip)
|
59
|
+
ret = "#{canonical_string}&Signature=#{signature}"
|
60
|
+
# puts 'full=' + ret.inspect
|
61
|
+
ret
|
62
|
+
end
|
63
|
+
|
64
|
+
# New signature for ses
|
65
|
+
def self.signature_version3(aws_secret_key, now)
|
66
|
+
algorithm = @@digest256 ? 'HmacSHA256' : 'HmacSHA1'
|
67
|
+
# select a digest
|
68
|
+
digest = (algorithm == 'HmacSHA256' ? @@digest256 : @@digest1)
|
69
|
+
signature = (Base64.encode64(OpenSSL::HMAC.digest(digest, aws_secret_key, now.httpdate)).strip)
|
70
|
+
return signature, algorithm
|
71
|
+
end
|
72
|
+
|
73
|
+
HEX = [
|
74
|
+
"%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07",
|
75
|
+
"%08", "%09", "%0A", "%0B", "%0C", "%0D", "%0E", "%0F",
|
76
|
+
"%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17",
|
77
|
+
"%18", "%19", "%1A", "%1B", "%1C", "%1D", "%1E", "%1F",
|
78
|
+
"%20", "%21", "%22", "%23", "%24", "%25", "%26", "%27",
|
79
|
+
"%28", "%29", "%2A", "%2B", "%2C", "%2D", "%2E", "%2F",
|
80
|
+
"%30", "%31", "%32", "%33", "%34", "%35", "%36", "%37",
|
81
|
+
"%38", "%39", "%3A", "%3B", "%3C", "%3D", "%3E", "%3F",
|
82
|
+
"%40", "%41", "%42", "%43", "%44", "%45", "%46", "%47",
|
83
|
+
"%48", "%49", "%4A", "%4B", "%4C", "%4D", "%4E", "%4F",
|
84
|
+
"%50", "%51", "%52", "%53", "%54", "%55", "%56", "%57",
|
85
|
+
"%58", "%59", "%5A", "%5B", "%5C", "%5D", "%5E", "%5F",
|
86
|
+
"%60", "%61", "%62", "%63", "%64", "%65", "%66", "%67",
|
87
|
+
"%68", "%69", "%6A", "%6B", "%6C", "%6D", "%6E", "%6F",
|
88
|
+
"%70", "%71", "%72", "%73", "%74", "%75", "%76", "%77",
|
89
|
+
"%78", "%79", "%7A", "%7B", "%7C", "%7D", "%7E", "%7F",
|
90
|
+
"%80", "%81", "%82", "%83", "%84", "%85", "%86", "%87",
|
91
|
+
"%88", "%89", "%8A", "%8B", "%8C", "%8D", "%8E", "%8F",
|
92
|
+
"%90", "%91", "%92", "%93", "%94", "%95", "%96", "%97",
|
93
|
+
"%98", "%99", "%9A", "%9B", "%9C", "%9D", "%9E", "%9F",
|
94
|
+
"%A0", "%A1", "%A2", "%A3", "%A4", "%A5", "%A6", "%A7",
|
95
|
+
"%A8", "%A9", "%AA", "%AB", "%AC", "%AD", "%AE", "%AF",
|
96
|
+
"%B0", "%B1", "%B2", "%B3", "%B4", "%B5", "%B6", "%B7",
|
97
|
+
"%B8", "%B9", "%BA", "%BB", "%BC", "%BD", "%BE", "%BF",
|
98
|
+
"%C0", "%C1", "%C2", "%C3", "%C4", "%C5", "%C6", "%C7",
|
99
|
+
"%C8", "%C9", "%CA", "%CB", "%CC", "%CD", "%CE", "%CF",
|
100
|
+
"%D0", "%D1", "%D2", "%D3", "%D4", "%D5", "%D6", "%D7",
|
101
|
+
"%D8", "%D9", "%DA", "%DB", "%DC", "%DD", "%DE", "%DF",
|
102
|
+
"%E0", "%E1", "%E2", "%E3", "%E4", "%E5", "%E6", "%E7",
|
103
|
+
"%E8", "%E9", "%EA", "%EB", "%EC", "%ED", "%EE", "%EF",
|
104
|
+
"%F0", "%F1", "%F2", "%F3", "%F4", "%F5", "%F6", "%F7",
|
105
|
+
"%F8", "%F9", "%FA", "%FB", "%FC", "%FD", "%FE", "%FF"
|
106
|
+
]
|
107
|
+
TO_REMEMBER = 'AZaz09 -_.!~*\'()'
|
108
|
+
ASCII = {} # {'A'=>65, 'Z'=>90, 'a'=>97, 'z'=>122, '0'=>48, '9'=>57, ' '=>32, '-'=>45, '_'=>95, '.'=>}
|
109
|
+
TO_REMEMBER.each_char do |c| #unpack("c*").each do |c|
|
110
|
+
ASCII[c] = c.unpack("c")[0]
|
111
|
+
end
|
112
|
+
# puts 'ascii=' + ASCII.inspect
|
113
|
+
|
114
|
+
# Escape a string accordingly Amazon rulles
|
115
|
+
# http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?REST_RESTAuth.html
|
116
|
+
def self.amz_escape(param)
|
117
|
+
|
118
|
+
param = param.to_s
|
119
|
+
# param = param.force_encoding("UTF-8")
|
120
|
+
|
121
|
+
# e = "x" # escape2(param.to_s)
|
122
|
+
# puts 'ESCAPED=' + e.inspect
|
123
|
+
|
124
|
+
|
125
|
+
#return CGI.escape(param.to_s).gsub("%7E", "~").gsub("+", "%20") # from: http://umlaut.rubyforge.org/svn/trunk/lib/aws_product_sign.rb
|
126
|
+
|
127
|
+
#param.to_s.gsub(/([^a-zA-Z0-9._~-]+)/n) do
|
128
|
+
# '%' + $1.unpack('H2' * $1.size).join('%').upcase
|
129
|
+
#end
|
130
|
+
|
131
|
+
# puts 'e in=' + e.inspect
|
132
|
+
# converter = Iconv.new('ASCII', 'UTF-8')
|
133
|
+
# e = converter.iconv(e) #.unpack('U*').select{ |cp| cp < 127 }.pack('U*')
|
134
|
+
# puts 'e out=' + e.inspect
|
135
|
+
|
136
|
+
e2 = CGI.escape(param)
|
137
|
+
e2 = e2.gsub("%7E", "~")
|
138
|
+
e2 = e2.gsub("+", "%20")
|
139
|
+
e2 = e2.gsub("*", "%2A")
|
140
|
+
|
141
|
+
# puts 'E2=' + e2.inspect
|
142
|
+
# puts e == e2.to_s
|
143
|
+
|
144
|
+
e2
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
# From: https://github.com/tomandersen/aws/commit/04b494b1ac440db1cd3b4ff3c84d0b2745d25250
|
149
|
+
# Not used yet, but worth trying it out.
|
150
|
+
def self.perhaps_a_better_escape(key)
|
151
|
+
# EG: CGI escape is str.gsub(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) }, but we can leave in / and some others for easier reading
|
152
|
+
# escape all characters except a-Z, 0-9, and - _ . ! ~ *' ( ) /
|
153
|
+
key.gsub(/[^a-zA-Z0-9\-_.!~*'()\/]/n) { sprintf("%%%02X", $&.unpack("C")[0]) }
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.escape2(s)
|
157
|
+
# home grown
|
158
|
+
ret = ""
|
159
|
+
s.unpack("U*") do |ch|
|
160
|
+
# puts 'ch=' + ch.inspect
|
161
|
+
if ASCII['A'] <= ch && ch <= ASCII['Z'] # A to Z
|
162
|
+
ret << ch
|
163
|
+
elsif ASCII['a'] <= ch && ch <= ASCII['z'] # a to z
|
164
|
+
ret << ch
|
165
|
+
elsif ASCII['0'] <= ch && ch <= ASCII['9'] # 0 to 9
|
166
|
+
ret << ch
|
167
|
+
elsif ch == ASCII[' '] # space
|
168
|
+
ret << "%20" # "+"
|
169
|
+
elsif ch == ASCII['-'] || ch == ASCII['_'] || ch == ASCII['.'] || ch == ASCII['~']
|
170
|
+
ret << ch
|
171
|
+
elsif ch <= 0x007f # other ascii
|
172
|
+
ret << HEX[ch]
|
173
|
+
elsif ch <= 0x07FF # non-ascii
|
174
|
+
ret << HEX[0xc0 | (ch >> 6)]
|
175
|
+
ret << HEX[0x80 | (ch & 0x3F)]
|
176
|
+
else
|
177
|
+
ret << HEX[0xe0 | (ch >> 12)]
|
178
|
+
ret << HEX[0x80 | ((ch >> 6) & 0x3F)]
|
179
|
+
ret << HEX[0x80 | (ch & 0x3F)]
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
ret
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
def self.escape_sig(raw)
|
188
|
+
e = CGI.escape(raw)
|
189
|
+
end
|
190
|
+
|
191
|
+
# From Amazon's SQS Dev Guide, a brief description of how to escape:
|
192
|
+
# "URL encode the computed signature and other query parameters as specified in
|
193
|
+
# RFC1738, section 2.2. In addition, because the + character is interpreted as a blank space
|
194
|
+
# by Sun Java classes that perform URL decoding, make sure to encode the + character
|
195
|
+
# although it is not required by RFC1738."
|
196
|
+
# Avoid using CGI::escape to escape URIs.
|
197
|
+
# CGI::escape will escape characters in the protocol, host, and port
|
198
|
+
# sections of the URI. Only target chars in the query
|
199
|
+
# string should be escaped.
|
200
|
+
def self.URLencode(raw)
|
201
|
+
e = URI.escape(raw)
|
202
|
+
e.gsub(/\+/, "%2b")
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
def self.allow_only(allowed_keys, params)
|
207
|
+
bogus_args = []
|
208
|
+
params.keys.each { |p| bogus_args.push(p) unless allowed_keys.include?(p) }
|
209
|
+
raise AwsError.new("The following arguments were given but are not legal for the function call #{caller_method}: #{bogus_args.inspect}") if bogus_args.length > 0
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.mandatory_arguments(required_args, params)
|
213
|
+
rargs = required_args.dup
|
214
|
+
params.keys.each { |p| rargs.delete(p) }
|
215
|
+
raise AwsError.new("The following mandatory arguments were not provided to #{caller_method}: #{rargs.inspect}") if rargs.length > 0
|
216
|
+
end
|
217
|
+
|
218
|
+
def self.caller_method
|
219
|
+
caller[1]=~/`(.*?)'/
|
220
|
+
$1
|
221
|
+
end
|
222
|
+
|
223
|
+
def self.blank?(obj)
|
224
|
+
case obj
|
225
|
+
when NilClass, FalseClass
|
226
|
+
true
|
227
|
+
when TrueClass, Numeric
|
228
|
+
false
|
229
|
+
when Array, Hash
|
230
|
+
obj.empty?
|
231
|
+
when String
|
232
|
+
obj.empty? || obj.strip.empty?
|
233
|
+
else
|
234
|
+
# "", " ", nil, [], and {} are blank
|
235
|
+
if obj.respond_to?(:empty?) && obj.respond_to?(:strip)
|
236
|
+
obj.empty? or obj.strip.empty?
|
237
|
+
elsif obj.respond_to?(:empty?)
|
238
|
+
obj.empty?
|
239
|
+
else
|
240
|
+
!obj
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def self.underscore(camel_cased_word)
|
246
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
247
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
248
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
249
|
+
tr("-", "_").
|
250
|
+
downcase
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
end
|
255
|
+
end
|