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.
Files changed (45) hide show
  1. data/README.markdown +9 -75
  2. data/lib/acf/acf_interface.rb +6 -4
  3. data/lib/aws.rb +2 -1
  4. data/lib/awsbase/awsbase.rb +98 -65
  5. data/lib/awsbase/errors.rb +9 -5
  6. data/lib/awsbase/parsers.rb +226 -226
  7. data/lib/awsbase/utils.rb +255 -207
  8. data/lib/ec2/ec2.rb +243 -105
  9. data/lib/ec2/mon_interface.rb +2 -1
  10. data/lib/iam/iam.rb +31 -25
  11. data/lib/right_aws.rb +1 -1
  12. data/lib/s3/bucket.rb +7 -8
  13. data/lib/s3/grantee.rb +238 -238
  14. data/lib/s3/key.rb +281 -281
  15. data/lib/s3/s3.rb +2 -1
  16. data/lib/s3/s3_interface.rb +45 -35
  17. data/lib/sdb/active_sdb.rb +19 -22
  18. data/lib/sdb/sdb_interface.rb +4 -5
  19. data/lib/ses/ses.rb +123 -0
  20. data/lib/sqs/sqs.rb +5 -0
  21. data/lib/sqs/sqs_interface.rb +3 -3
  22. metadata +53 -104
  23. data/lib/awsbase/support.rb +0 -142
  24. data/test/acf/test_acf.rb +0 -148
  25. data/test/acf/test_helper.rb +0 -2
  26. data/test/ec2/test_ec2.rb +0 -205
  27. data/test/ec2/test_helper.rb +0 -2
  28. data/test/ec2/test_mon.rb +0 -17
  29. data/test/elb/test_elb.rb +0 -51
  30. data/test/http_connection.rb +0 -87
  31. data/test/iam/test_iam.rb +0 -36
  32. data/test/rds/test_rds.rb +0 -181
  33. data/test/s3/s3_test_base.rb +0 -23
  34. data/test/s3/test_helper.rb +0 -3
  35. data/test/s3/test_s3.rb +0 -162
  36. data/test/s3/test_s3_class.rb +0 -179
  37. data/test/s3/test_s3_rights.rb +0 -139
  38. data/test/s3/test_s3_stubbed.rb +0 -97
  39. data/test/sdb/test_active_sdb.rb +0 -338
  40. data/test/sdb/test_helper.rb +0 -3
  41. data/test/sdb/test_sdb.rb +0 -220
  42. data/test/sqs/test_helper.rb +0 -2
  43. data/test/sqs/test_sqs.rb +0 -232
  44. data/test/test_credentials.rb +0 -54
  45. data/test/ts_right_aws.rb +0 -13
@@ -1,207 +1,255 @@
1
- module Aws
2
-
3
- class AwsUtils #: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'] = AwsUtils::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'] = AwsUtils::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
- HEX = [
65
- "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07",
66
- "%08", "%09", "%0A", "%0B", "%0C", "%0D", "%0E", "%0F",
67
- "%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17",
68
- "%18", "%19", "%1A", "%1B", "%1C", "%1D", "%1E", "%1F",
69
- "%20", "%21", "%22", "%23", "%24", "%25", "%26", "%27",
70
- "%28", "%29", "%2A", "%2B", "%2C", "%2D", "%2E", "%2F",
71
- "%30", "%31", "%32", "%33", "%34", "%35", "%36", "%37",
72
- "%38", "%39", "%3A", "%3B", "%3C", "%3D", "%3E", "%3F",
73
- "%40", "%41", "%42", "%43", "%44", "%45", "%46", "%47",
74
- "%48", "%49", "%4A", "%4B", "%4C", "%4D", "%4E", "%4F",
75
- "%50", "%51", "%52", "%53", "%54", "%55", "%56", "%57",
76
- "%58", "%59", "%5A", "%5B", "%5C", "%5D", "%5E", "%5F",
77
- "%60", "%61", "%62", "%63", "%64", "%65", "%66", "%67",
78
- "%68", "%69", "%6A", "%6B", "%6C", "%6D", "%6E", "%6F",
79
- "%70", "%71", "%72", "%73", "%74", "%75", "%76", "%77",
80
- "%78", "%79", "%7A", "%7B", "%7C", "%7D", "%7E", "%7F",
81
- "%80", "%81", "%82", "%83", "%84", "%85", "%86", "%87",
82
- "%88", "%89", "%8A", "%8B", "%8C", "%8D", "%8E", "%8F",
83
- "%90", "%91", "%92", "%93", "%94", "%95", "%96", "%97",
84
- "%98", "%99", "%9A", "%9B", "%9C", "%9D", "%9E", "%9F",
85
- "%A0", "%A1", "%A2", "%A3", "%A4", "%A5", "%A6", "%A7",
86
- "%A8", "%A9", "%AA", "%AB", "%AC", "%AD", "%AE", "%AF",
87
- "%B0", "%B1", "%B2", "%B3", "%B4", "%B5", "%B6", "%B7",
88
- "%B8", "%B9", "%BA", "%BB", "%BC", "%BD", "%BE", "%BF",
89
- "%C0", "%C1", "%C2", "%C3", "%C4", "%C5", "%C6", "%C7",
90
- "%C8", "%C9", "%CA", "%CB", "%CC", "%CD", "%CE", "%CF",
91
- "%D0", "%D1", "%D2", "%D3", "%D4", "%D5", "%D6", "%D7",
92
- "%D8", "%D9", "%DA", "%DB", "%DC", "%DD", "%DE", "%DF",
93
- "%E0", "%E1", "%E2", "%E3", "%E4", "%E5", "%E6", "%E7",
94
- "%E8", "%E9", "%EA", "%EB", "%EC", "%ED", "%EE", "%EF",
95
- "%F0", "%F1", "%F2", "%F3", "%F4", "%F5", "%F6", "%F7",
96
- "%F8", "%F9", "%FA", "%FB", "%FC", "%FD", "%FE", "%FF"
97
- ]
98
- TO_REMEMBER = 'AZaz09 -_.!~*\'()'
99
- ASCII = {} # {'A'=>65, 'Z'=>90, 'a'=>97, 'z'=>122, '0'=>48, '9'=>57, ' '=>32, '-'=>45, '_'=>95, '.'=>}
100
- TO_REMEMBER.each_char do |c| #unpack("c*").each do |c|
101
- ASCII[c] = c.unpack("c")[0]
102
- end
103
- # puts 'ascii=' + ASCII.inspect
104
-
105
- # Escape a string accordingly Amazon rulles
106
- # http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?REST_RESTAuth.html
107
- def self.amz_escape(param)
108
-
109
- param = param.to_s
110
- # param = param.force_encoding("UTF-8")
111
-
112
- e = "x" # escape2(param.to_s)
113
- # puts 'ESCAPED=' + e.inspect
114
-
115
-
116
- #return CGI.escape(param.to_s).gsub("%7E", "~").gsub("+", "%20") # from: http://umlaut.rubyforge.org/svn/trunk/lib/aws_product_sign.rb
117
-
118
- #param.to_s.gsub(/([^a-zA-Z0-9._~-]+)/n) do
119
- # '%' + $1.unpack('H2' * $1.size).join('%').upcase
120
- #end
121
-
122
- # puts 'e in=' + e.inspect
123
- # converter = Iconv.new('ASCII', 'UTF-8')
124
- # e = converter.iconv(e) #.unpack('U*').select{ |cp| cp < 127 }.pack('U*')
125
- # puts 'e out=' + e.inspect
126
-
127
- e2 = CGI.escape(param)
128
- e2 = e2.gsub("%7E", "~")
129
- e2 = e2.gsub("+", "%20")
130
- e2 = e2.gsub("*", "%2A")
131
-
132
- # puts 'E2=' + e2.inspect
133
- # puts e == e2.to_s
134
-
135
- e2
136
-
137
- end
138
-
139
- def self.escape2(s)
140
- # home grown
141
- ret = ""
142
- s.unpack("U*") do |ch|
143
- # puts 'ch=' + ch.inspect
144
- if ASCII['A'] <= ch && ch <= ASCII['Z'] # A to Z
145
- ret << ch
146
- elsif ASCII['a'] <= ch && ch <= ASCII['z'] # a to z
147
- ret << ch
148
- elsif ASCII['0'] <= ch && ch <= ASCII['9'] # 0 to 9
149
- ret << ch
150
- elsif ch == ASCII[' '] # space
151
- ret << "%20" # "+"
152
- elsif ch == ASCII['-'] || ch == ASCII['_'] || ch == ASCII['.'] || ch == ASCII['~']
153
- ret << ch
154
- elsif ch <= 0x007f # other ascii
155
- ret << HEX[ch]
156
- elsif ch <= 0x07FF # non-ascii
157
- ret << HEX[0xc0 | (ch >> 6)]
158
- ret << HEX[0x80 | (ch & 0x3F)]
159
- else
160
- ret << HEX[0xe0 | (ch >> 12)]
161
- ret << HEX[0x80 | ((ch >> 6) & 0x3F)]
162
- ret << HEX[0x80 | (ch & 0x3F)]
163
- end
164
-
165
- end
166
- ret
167
-
168
- end
169
-
170
- def self.escape_sig(raw)
171
- e = CGI.escape(raw)
172
- end
173
-
174
- # From Amazon's SQS Dev Guide, a brief description of how to escape:
175
- # "URL encode the computed signature and other query parameters as specified in
176
- # RFC1738, section 2.2. In addition, because the + character is interpreted as a blank space
177
- # by Sun Java classes that perform URL decoding, make sure to encode the + character
178
- # although it is not required by RFC1738."
179
- # Avoid using CGI::escape to escape URIs.
180
- # CGI::escape will escape characters in the protocol, host, and port
181
- # sections of the URI. Only target chars in the query
182
- # string should be escaped.
183
- def self.URLencode(raw)
184
- e = URI.escape(raw)
185
- e.gsub(/\+/, "%2b")
186
- end
187
-
188
-
189
- def self.allow_only(allowed_keys, params)
190
- bogus_args = []
191
- params.keys.each { |p| bogus_args.push(p) unless allowed_keys.include?(p) }
192
- 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
193
- end
194
-
195
- def self.mandatory_arguments(required_args, params)
196
- rargs = required_args.dup
197
- params.keys.each { |p| rargs.delete(p) }
198
- raise AwsError.new("The following mandatory arguments were not provided to #{caller_method}: #{rargs.inspect}") if rargs.length > 0
199
- end
200
-
201
- def self.caller_method
202
- caller[1]=~/`(.*?)'/
203
- $1
204
- end
205
-
206
- end
207
- end
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