gotime_aws 2.5.6

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/lib/s3/s3.rb ADDED
@@ -0,0 +1,347 @@
1
+ #
2
+ # Copyright (c) 2007-2008 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+ module Aws
24
+
25
+ # = Aws::S3 -- RightScale's Amazon S3 interface
26
+ # The Aws::S3 class provides a complete interface to Amazon's Simple
27
+ # Storage Service.
28
+ # For explanations of the semantics
29
+ # of each call, please refer to Amazon's documentation at
30
+ # http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=48
31
+ #
32
+ # See examples below for the bucket and buckets methods.
33
+ #
34
+ # Error handling: all operations raise an Aws::AwsError in case
35
+ # of problems. Note that transient errors are automatically retried.
36
+ #
37
+ # It is a good way to use domain naming style getting a name for the buckets.
38
+ # See http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingBucket.html
39
+ # about the naming convention for the buckets. This case they can be accessed using a virtual domains.
40
+ #
41
+ # Let assume you have 3 buckets: 'awesome-bucket', 'awesome_bucket' and 'AWEsomE-bucket'.
42
+ # The first ones objects can be accessed as: http:// awesome-bucket.s3.amazonaws.com/key/object
43
+ #
44
+ # But the rest have to be accessed as:
45
+ # http:// s3.amazonaws.com/awesome_bucket/key/object and http:// s3.amazonaws.com/AWEsomE-bucket/key/object
46
+ #
47
+ # See: http://docs.amazonwebservices.com/AmazonS3/2006-03-01/VirtualHosting.html for better explanation.
48
+ #
49
+ class S3
50
+
51
+
52
+ class Owner
53
+ attr_reader :id, :name
54
+
55
+ def initialize(id, name)
56
+ @id = id
57
+ @name = name
58
+ end
59
+
60
+ # Return Owner name as a +String+.
61
+ def to_s
62
+ @name
63
+ end
64
+ end
65
+
66
+ require_relative 'bucket'
67
+ require_relative 'key'
68
+ require_relative 'grantee'
69
+
70
+
71
+ attr_reader :interface
72
+
73
+
74
+ # Create a new handle to an S3 account. All handles share the same per process or per thread
75
+ # HTTP connection to Amazon S3. Each handle is for a specific account.
76
+ # The +params+ are passed through as-is to Aws::S3Interface.new
77
+ #
78
+ # Params is a hash:
79
+ #
80
+ # {:server => 's3.amazonaws.com' # Amazon service host: 's3.amazonaws.com'(default)
81
+ # :port => 443 # Amazon service port: 80 or 443(default)
82
+ # :protocol => 'https' # Amazon service protocol: 'http' or 'https'(default)
83
+ # :virtual_hosting => false # Force using bucket virtual hosting: https://s3.amazonaws.com/my-bucket vs. https://my-bucket.s3.amazonaws.com
84
+ # :connection_mode => :default # options are
85
+ # :default (will use best known safe (as in won't need explicit close) option, may change in the future)
86
+ # :per_request (opens and closes a connection on every request)
87
+ # :single (one thread across entire app)
88
+ # :per_thread (one connection per thread)
89
+ # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
90
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
91
+ @interface = S3Interface.new(aws_access_key_id, aws_secret_access_key, params)
92
+ end
93
+
94
+ def close_connection
95
+ @interface.close_connection
96
+ end
97
+
98
+ # Retrieve a list of buckets.
99
+ # Returns an array of Aws::S3::Bucket instances.
100
+ # # Create handle to S3 account
101
+ # s3 = Aws::S3.new(aws_access_key_id, aws_secret_access_key)
102
+ # my_buckets_names = s3.buckets.map{|b| b.name}
103
+ # puts "Buckets on S3: #{my_bucket_names.join(', ')}"
104
+ def buckets
105
+ @interface.list_all_my_buckets.map! do |entry|
106
+ owner = Owner.new(entry[:owner_id], entry[:owner_display_name])
107
+ Bucket.new(self, entry[:name], entry[:creation_date], owner)
108
+ end
109
+ end
110
+
111
+ # Retrieve an individual bucket.
112
+ # If the bucket does not exist and +create+ is set, a new bucket
113
+ # is created on S3. Launching this method with +create+=+true+ may
114
+ # affect on the bucket's ACL if the bucket already exists.
115
+ # Returns a Aws::S3::Bucket instance or +nil+ if the bucket does not exist
116
+ # and +create+ is not set.
117
+ #
118
+ # s3 = Aws::S3.new(aws_access_key_id, aws_secret_access_key)
119
+ # bucket1 = s3.bucket('my_awesome_bucket_1')
120
+ # bucket1.keys #=> exception here if the bucket does not exists
121
+ # ...
122
+ # bucket2 = s3.bucket('my_awesome_bucket_2', true)
123
+ # bucket2.keys #=> list of keys
124
+ # # create a bucket at the European location with public read access
125
+ # bucket3 = s3.bucket('my-awesome-bucket-3', true, 'public-read', :location => :eu)
126
+ #
127
+ # see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html
128
+ # (section: Canned Access Policies)
129
+ #
130
+ def bucket(name, create=false, perms=nil, headers={})
131
+ headers['x-amz-acl'] = perms if perms
132
+ @interface.create_bucket(name, headers) if create
133
+ return Bucket.new(self, name)
134
+ # The old way below was too slow and unnecessary because it retreived all the buckets every time.
135
+ # owner = Owner.new(entry[:owner_id], entry[:owner_display_name])
136
+ # buckets.each { |bucket| return bucket if bucket.name == name }
137
+ # nil
138
+ end
139
+
140
+
141
+ end
142
+
143
+ # Aws::S3Generator and Aws::S3Generator::Bucket methods:
144
+ #
145
+ # s3g = Aws::S3Generator.new('1...2', 'nx...Y6') #=> #<Aws::S3Generator:0xb7b5cc94>
146
+ #
147
+ # # List all buckets(method 'GET'):
148
+ # buckets_list = s3g.buckets #=> 'https://s3.amazonaws.com:443/?Signature=Y...D&Expires=1180941864&AWSAccessKeyId=1...2'
149
+ # # Create bucket link (method 'PUT'):
150
+ # bucket = s3g.bucket('my_awesome_bucket') #=> #<Aws::S3Generator::Bucket:0xb7bcbda8>
151
+ # link_to_create = bucket.create_link(1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=4...D&Expires=1180942132&AWSAccessKeyId=1...2
152
+ # # ... or:
153
+ # bucket = Aws::S3Generator::Bucket.create(s3g, 'my_awesome_bucket') #=> #<Aws::S3Generator::Bucket:0xb7bcbda8>
154
+ # link_to_create = bucket.create_link(1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=4...D&Expires=1180942132&AWSAccessKeyId=1...2
155
+ # # ... or:
156
+ # bucket = Aws::S3Generator::Bucket.new(s3g, 'my_awesome_bucket') #=> #<Aws::S3Generator::Bucket:0xb7bcbda8>
157
+ # link_to_create = bucket.create_link(1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=4...D&Expires=1180942132&AWSAccessKeyId=1...2
158
+ # # List bucket(method 'GET'):
159
+ # bucket.keys(1.day) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=i...D&Expires=1180942620&AWSAccessKeyId=1...2
160
+ # # Create/put key (method 'PUT'):
161
+ # bucket.put('my_cool_key') #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=q...D&Expires=1180943094&AWSAccessKeyId=1...2
162
+ # # Get key data (method 'GET'):
163
+ # bucket.get('logs/today/1.log', 1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=h...M%3D&Expires=1180820032&AWSAccessKeyId=1...2
164
+ # # Delete bucket (method 'DELETE'):
165
+ # bucket.delete(2.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=4...D&Expires=1180820032&AWSAccessKeyId=1...2
166
+ #
167
+ # Aws::S3Generator::Key methods:
168
+ #
169
+ # # Create Key instance:
170
+ # key = Aws::S3Generator::Key.new(bicket, 'my_cool_key') #=> #<Aws::S3Generator::Key:0xb7b7394c>
171
+ # # Put key data (method 'PUT'):
172
+ # key.put #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=2...D&Expires=1180943302&AWSAccessKeyId=1...2
173
+ # # Get key data (method 'GET'):
174
+ # key.get #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=a...D&Expires=1180820032&AWSAccessKeyId=1...2
175
+ # # Head key (method 'HEAD'):
176
+ # key.head #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=b...D&Expires=1180820032&AWSAccessKeyId=1...2
177
+ # # Delete key (method 'DELETE'):
178
+ # key.delete #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=x...D&Expires=1180820032&AWSAccessKeyId=1...2
179
+ #
180
+ class S3Generator
181
+ attr_reader :interface
182
+
183
+ def initialize(aws_access_key_id, aws_secret_access_key, params={})
184
+ @interface = S3Interface.new(aws_access_key_id, aws_secret_access_key, params)
185
+ end
186
+
187
+ # Generate link to list all buckets
188
+ #
189
+ # s3.buckets(1.hour)
190
+ #
191
+ def buckets(expires=nil, headers={})
192
+ @interface.list_all_my_buckets_link(expires, headers)
193
+ end
194
+
195
+ # Create new S3LinkBucket instance and generate link to create it at S3.
196
+ #
197
+ # bucket= s3.bucket('my_owesome_bucket')
198
+ #
199
+ def bucket(name, expires=nil, headers={})
200
+ Bucket.create(self, name.to_s)
201
+ end
202
+
203
+ class Bucket
204
+ attr_reader :s3, :name
205
+
206
+ def to_s
207
+ @name
208
+ end
209
+
210
+ alias_method :full_name, :to_s
211
+
212
+ # Return a public link to bucket.
213
+ #
214
+ # bucket.public_link #=> 'https://s3.amazonaws.com:443/my_awesome_bucket'
215
+ #
216
+ def public_link
217
+ params = @s3.interface.params
218
+ "#{params[:protocol]}://#{params[:server]}:#{params[:port]}/#{full_name}"
219
+ end
220
+
221
+ # Create new S3LinkBucket instance and generate creation link for it.
222
+ def self.create(s3, name, expires=nil, headers={})
223
+ new(s3, name.to_s)
224
+ end
225
+
226
+ # Create new S3LinkBucket instance.
227
+ def initialize(s3, name)
228
+ @s3, @name = s3, name.to_s
229
+ end
230
+
231
+ # Return a link to create this bucket.
232
+ #
233
+ def create_link(expires=nil, headers={})
234
+ @s3.interface.create_bucket_link(@name, expires, headers)
235
+ end
236
+
237
+ # Generate link to list keys.
238
+ #
239
+ # bucket.keys
240
+ # bucket.keys('prefix'=>'logs')
241
+ #
242
+ def keys(options=nil, expires=nil, headers={})
243
+ @s3.interface.list_bucket_link(@name, options, expires, headers)
244
+ end
245
+
246
+ # Return a S3Generator::Key instance.
247
+ #
248
+ # bucket.key('my_cool_key').get #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=B...D&Expires=1180820032&AWSAccessKeyId=1...2
249
+ # bucket.key('my_cool_key').delete #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=B...D&Expires=1180820098&AWSAccessKeyId=1...2
250
+ #
251
+ def key(name)
252
+ Key.new(self, name)
253
+ end
254
+
255
+ # Generates link to PUT key data.
256
+ #
257
+ # puts bucket.put('logs/today/1.log', 2.hour)
258
+ #
259
+ def put(key, meta_headers={}, expires=nil, headers={})
260
+ meta = Aws::S3::Key.add_meta_prefix(meta_headers)
261
+ @s3.interface.put_link(@name, key.to_s, nil, expires, meta.merge(headers))
262
+ end
263
+
264
+ # Generate link to GET key data.
265
+ #
266
+ # bucket.get('logs/today/1.log', 1.hour)
267
+ #
268
+ def get(key, expires=nil, headers={})
269
+ @s3.interface.get_link(@name, key.to_s, expires, headers)
270
+ end
271
+
272
+ # Generate link to delete bucket.
273
+ #
274
+ # bucket.delete(2.hour)
275
+ #
276
+ def delete(expires=nil, headers={})
277
+ @s3.interface.delete_bucket_link(@name, expires, headers)
278
+ end
279
+ end
280
+
281
+
282
+ class Key
283
+ attr_reader :bucket, :name
284
+
285
+ def to_s
286
+ @name
287
+ end
288
+
289
+ # Return a full S# name (bucket/key).
290
+ #
291
+ # key.full_name #=> 'my_awesome_bucket/cool_key'
292
+ #
293
+ def full_name(separator='/')
294
+ "#{@bucket.to_s}#{separator}#{@name}"
295
+ end
296
+
297
+ # Return a public link to key.
298
+ #
299
+ # key.public_link #=> 'https://s3.amazonaws.com:443/my_awesome_bucket/cool_key'
300
+ #
301
+ def public_link
302
+ params = @bucket.s3.interface.params
303
+ "#{params[:protocol]}://#{params[:server]}:#{params[:port]}/#{full_name('/')}"
304
+ end
305
+
306
+ def initialize(bucket, name, meta_headers={})
307
+ @bucket = bucket
308
+ @name = name.to_s
309
+ @meta_headers = meta_headers
310
+ raise 'Key name can not be empty.' if Aws::Utils.blank?(@name)
311
+ end
312
+
313
+ # Generate link to PUT key data.
314
+ #
315
+ # puts bucket.put('logs/today/1.log', '123', 2.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=B...D&Expires=1180820032&AWSAccessKeyId=1...2
316
+ #
317
+ def put(expires=nil, headers={})
318
+ @bucket.put(@name.to_s, @meta_headers, expires, headers)
319
+ end
320
+
321
+ # Generate link to GET key data.
322
+ #
323
+ # bucket.get('logs/today/1.log', 1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=h...M%3D&Expires=1180820032&AWSAccessKeyId=1...2
324
+ #
325
+ def get(expires=nil, headers={})
326
+ @bucket.s3.interface.get_link(@bucket.to_s, @name, expires, headers)
327
+ end
328
+
329
+ # Generate link to delete key.
330
+ #
331
+ # bucket.delete(2.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=4...D&Expires=1180820032&AWSAccessKeyId=1...2
332
+ #
333
+ def delete(expires=nil, headers={})
334
+ @bucket.s3.interface.delete_link(@bucket.to_s, @name, expires, headers)
335
+ end
336
+
337
+ # Generate link to head key.
338
+ #
339
+ # bucket.head(2.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=4...D&Expires=1180820032&AWSAccessKeyId=1...2
340
+ #
341
+ def head(expires=nil, headers={})
342
+ @bucket.s3.interface.head_link(@bucket.to_s, @name, expires, headers)
343
+ end
344
+ end
345
+ end
346
+
347
+ end