aws 2.4.5 → 2.5.0
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.
- 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
|