right_aws 1.1.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/History.txt +3 -0
- data/Manifest.txt +21 -0
- data/README.txt +96 -0
- data/Rakefile +25 -0
- data/lib/awsbase/benchmark_fix.rb +39 -0
- data/lib/awsbase/right_awsbase.rb +231 -0
- data/lib/ec2/right_ec2.rb +1034 -0
- data/lib/right_aws.rb +63 -0
- data/lib/s3/right_s3.rb +879 -0
- data/lib/s3/right_s3_interface.rb +900 -0
- data/lib/sqs/right_sqs.rb +369 -0
- data/lib/sqs/right_sqs_interface.rb +655 -0
- data/test/awsbase/test_helper.rb +2 -0
- data/test/awsbase/test_right_awsbase.rb +12 -0
- data/test/ec2/test_helper.rb +2 -0
- data/test/ec2/test_right_ec2.rb +67 -0
- data/test/s3/test_helper.rb +2 -0
- data/test/s3/test_right_s3.rb +217 -0
- data/test/sqs/test_helper.rb +2 -0
- data/test/sqs/test_right_sqs.rb +226 -0
- data/test/test_credentials.rb +37 -0
- data/test/ts_right_aws.rb +9 -0
- metadata +102 -0
data/lib/right_aws.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2007 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
|
+
|
24
|
+
require 'benchmark'
|
25
|
+
require 'net/https'
|
26
|
+
require 'uri'
|
27
|
+
require 'time'
|
28
|
+
require "cgi"
|
29
|
+
require "base64"
|
30
|
+
require "rexml/document"
|
31
|
+
require "openssl"
|
32
|
+
require "digest/sha1"
|
33
|
+
|
34
|
+
require 'rubygems'
|
35
|
+
require 'active_support'
|
36
|
+
require 'right_http_connection'
|
37
|
+
|
38
|
+
$:.unshift(File.dirname(__FILE__))
|
39
|
+
require 'awsbase/benchmark_fix'
|
40
|
+
require 'awsbase/right_awsbase'
|
41
|
+
require 'ec2/right_ec2'
|
42
|
+
require 's3/right_s3_interface'
|
43
|
+
require 's3/right_s3'
|
44
|
+
require 'sqs/right_sqs_interface'
|
45
|
+
require 'sqs/right_sqs'
|
46
|
+
|
47
|
+
|
48
|
+
module RightAws #:nodoc:
|
49
|
+
module VERSION #:nodoc:
|
50
|
+
MAJOR = 1
|
51
|
+
MINOR = 1
|
52
|
+
TINY = 0
|
53
|
+
|
54
|
+
STRING = [MAJOR, MINOR, TINY].join('.')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# We also want everything available in the Rightscale namespace for backward
|
59
|
+
# compatibility reasons.
|
60
|
+
module Rightscale
|
61
|
+
include RightAws
|
62
|
+
extend RightAws
|
63
|
+
end
|
data/lib/s3/right_s3.rb
ADDED
@@ -0,0 +1,879 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2007 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
|
+
|
24
|
+
module RightAws
|
25
|
+
|
26
|
+
class S3
|
27
|
+
attr_reader :interface
|
28
|
+
|
29
|
+
def initialize(aws_access_key_id, aws_secret_access_key, params={})
|
30
|
+
@interface = S3Interface.new(aws_access_key_id, aws_secret_access_key, params)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Retrieve a list of buckets.
|
34
|
+
# Returns an array of Bucket instances.
|
35
|
+
#
|
36
|
+
# s3 = RightAws::S3.new(aws_access_key_id, aws_secret_access_key)
|
37
|
+
# p s3.buckets #=> array of buckets
|
38
|
+
#
|
39
|
+
def buckets
|
40
|
+
@interface.list_all_my_buckets.map! do |entry|
|
41
|
+
owner = Owner.new(entry[:owner_id], entry[:owner_display_name])
|
42
|
+
Bucket.new(self, entry[:name], entry[:creation_date], owner)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Return an object representing a bucket.
|
47
|
+
# If the bucket does not exist and +create+ is set, a new bucket
|
48
|
+
# is created on S3. The +create+ parameter has no effect if
|
49
|
+
# the bucket alrady exists.
|
50
|
+
# Returns Bucket instance or +nil+ if the bucket does not exist
|
51
|
+
# and +create+ is not set.
|
52
|
+
#
|
53
|
+
# s3 = RightAws::S3.new(aws_access_key_id, aws_secret_access_key)
|
54
|
+
# bucket1 = s3.bucket('my_awesome_bucket')
|
55
|
+
# bucket1.keys #=> exception here if the bucket does not exists
|
56
|
+
# ...
|
57
|
+
# bucket2 = s3.bucket('my_awesome_bucket', true)
|
58
|
+
# bucket2.keys #=> list of keys
|
59
|
+
#
|
60
|
+
# see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html
|
61
|
+
# (section: Canned Access Policies)
|
62
|
+
#
|
63
|
+
def bucket(name, create=true, perms=nil, headers={})
|
64
|
+
headers['x-amz-acl'] = perms if perms
|
65
|
+
@interface.create_bucket(name, headers) if create
|
66
|
+
buckets.each { |bucket| return bucket if bucket.name == name }
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
class Bucket
|
72
|
+
attr_reader :s3, :name, :owner, :creation_date
|
73
|
+
|
74
|
+
# Create a Bucket instance.
|
75
|
+
# If the bucket does not exist and +create+ is set, a new bucket
|
76
|
+
# is created on S3. The +create+ parameter has no effect if
|
77
|
+
# the bucket alrady exists.
|
78
|
+
# Returns Bucket instance or +nil+ if the bucket does not exist
|
79
|
+
# and +create+ is not set.
|
80
|
+
#
|
81
|
+
# s3 = RightAws::S3.new(aws_access_key_id, aws_secret_access_key)
|
82
|
+
# ...
|
83
|
+
# bucket1 = RightAws::S3::Bucket.create(s3, 'my_awesome_bucket')
|
84
|
+
# bucket1.keys #=> exception here if the bucket does not exists
|
85
|
+
# ...
|
86
|
+
# bucket2 = RightAws::S3::Bucket.create(s3, 'my_awesome_bucket', true)
|
87
|
+
# bucket2.keys #=> list of keys
|
88
|
+
#
|
89
|
+
def self.create(s3, name, create=true, perms=nil, headers={})
|
90
|
+
s3.bucket(name, create, perms, headers)
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
# Create a bucket instance. In normal use this method should
|
95
|
+
# not be called directly.
|
96
|
+
# Use RightAws::S3::Bucket.create or RightAws::S3.bucket instead.
|
97
|
+
def initialize(s3, name, creation_date=nil, owner=nil)
|
98
|
+
@s3 = s3
|
99
|
+
@name = name
|
100
|
+
@owner = owner
|
101
|
+
@creation_date = creation_date
|
102
|
+
if @creation_date && !@creation_date.is_a?(Time)
|
103
|
+
@creation_date = Time.parse(@creation_date)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Return bucket name as a String.
|
108
|
+
#
|
109
|
+
# bucket = RightAws::S3.bucket('my_awesome_bucket')
|
110
|
+
# puts bucket #=> 'my_awesome_bucket'
|
111
|
+
#
|
112
|
+
def to_s
|
113
|
+
@name.to_s
|
114
|
+
end
|
115
|
+
alias_method :full_name, :to_s
|
116
|
+
|
117
|
+
# Return a public link to bucket.
|
118
|
+
#
|
119
|
+
# bucket.public_link #=> 'https://s3.amazonaws.com:443/my_awesome_bucket'
|
120
|
+
#
|
121
|
+
def public_link
|
122
|
+
params = @s3.interface.params
|
123
|
+
"#{params[:protocol]}://#{params[:server]}:#{params[:port]}/#{full_name}"
|
124
|
+
end
|
125
|
+
|
126
|
+
# Retrieve a group of keys from Amazon.
|
127
|
+
# +options+ is a hash: { 'prefix'=>'', 'marker'=>'', 'max-keys'=>5, 'delimiter'=>'' }).
|
128
|
+
# Retrieves meta-headers information if +head+ it +true+.
|
129
|
+
# Returns an array of Key instances.
|
130
|
+
#
|
131
|
+
# bucket.keys #=> # returns all keys from bucket
|
132
|
+
# bucket.keys('prefix' => 'logs') #=> # returns all keys that starts with 'logs'
|
133
|
+
#
|
134
|
+
def keys(options={}, head=false)
|
135
|
+
keys_and_service(options, head)[0]
|
136
|
+
end
|
137
|
+
|
138
|
+
# Same as +keys+ method but return an array of [keys, service_data].
|
139
|
+
# where +service_data+ is a hash with additional output information.
|
140
|
+
#
|
141
|
+
# keys, service = bucket.keys_and_service({'max-keys'=> 2, 'prefix' => 'logs'})
|
142
|
+
# p keys #=> # 2 keys array
|
143
|
+
# p service #=> {"max-keys"=>"2", "prefix"=>"logs", "name"=>"my_awesome_bucket", "marker"=>"", "is_truncated"=>true}
|
144
|
+
#
|
145
|
+
def keys_and_service(options={}, head=false)
|
146
|
+
opt = {}; options.each{ |key, value| opt[key.to_s] = value }
|
147
|
+
service_data = {}
|
148
|
+
thislist = {}
|
149
|
+
list = []
|
150
|
+
@s3.interface.incrementally_list_bucket(@name, opt) do |thislist|
|
151
|
+
thislist[:contents].each do |entry|
|
152
|
+
owner = Owner.new(entry[:owner_id], entry[:owner_display_name])
|
153
|
+
key = Key.new(self, entry[:key], nil, {}, {}, entry[:last_modified], entry[:e_tag], entry[:size], entry[:storage_class], owner)
|
154
|
+
key.head if head
|
155
|
+
list << key
|
156
|
+
end
|
157
|
+
end
|
158
|
+
thislist.each_key do |key|
|
159
|
+
service_data[key] = thislist[key] unless (key == :contents || key == :common_prefixes)
|
160
|
+
end
|
161
|
+
[list, service_data]
|
162
|
+
end
|
163
|
+
|
164
|
+
# Retrieve key information from Amazon.
|
165
|
+
# The +key_name+ is a +String+ or Key instance.
|
166
|
+
# Retrieves meta-header information if +head+ is +true+.
|
167
|
+
# Returns new Key instance.
|
168
|
+
#
|
169
|
+
# key = bucket.key('logs/today/1.log', true) #=> #<RightAws::S3::Key:0xb7b1e240 ... >
|
170
|
+
# # is the same as:
|
171
|
+
# key = RightAws::S3::Key.create(bucket, 'logs/today/1.log')
|
172
|
+
# key.head
|
173
|
+
#
|
174
|
+
def key(key_name, head=false)
|
175
|
+
raise 'Key name can not be empty.' if key_name.blank?
|
176
|
+
key_instance = nil
|
177
|
+
# if this key exists - find it ....
|
178
|
+
keys({'prefix'=>key_name}, head).each do |key|
|
179
|
+
if key.name == key_name.to_s
|
180
|
+
key_instance = key
|
181
|
+
break
|
182
|
+
end
|
183
|
+
end
|
184
|
+
# .... else this key is unknown
|
185
|
+
unless key_instance
|
186
|
+
key_instance = Key.create(self, key_name.to_s)
|
187
|
+
end
|
188
|
+
key_instance
|
189
|
+
end
|
190
|
+
|
191
|
+
# Store object data.
|
192
|
+
# The +key+ is a +String+ or Key instance.
|
193
|
+
# Returns +true+.
|
194
|
+
#
|
195
|
+
# bucket.put('logs/today/1.log', 'Olala!') #=> true
|
196
|
+
#
|
197
|
+
def put(key, data=nil, meta_headers={}, perms=nil, headers={})
|
198
|
+
key = Key.create(self, key.to_s, data, meta_headers) unless key.is_a?(Key)
|
199
|
+
key.put(data, perms, headers)
|
200
|
+
end
|
201
|
+
|
202
|
+
# Retrieve object data from Amazon.
|
203
|
+
# The +key+ is a +String+ or Key.
|
204
|
+
# Returns Key instance.
|
205
|
+
#
|
206
|
+
# key = bucket.get('logs/today/1.log') #=>
|
207
|
+
# puts key.data #=> 'sasfasfasdf'
|
208
|
+
#
|
209
|
+
def get(key, headers={})
|
210
|
+
key = Key.create(self, key.to_s) unless key.is_a?(Key)
|
211
|
+
key.get(headers)
|
212
|
+
end
|
213
|
+
|
214
|
+
# Remove all keys from a bucket.
|
215
|
+
# Returns +true+.
|
216
|
+
#
|
217
|
+
# bucket.clear #=> true
|
218
|
+
#
|
219
|
+
def clear
|
220
|
+
@s3.interface.clear_bucket(@name)
|
221
|
+
end
|
222
|
+
|
223
|
+
# Delete all keys where the 'folder_key' can be interpreted
|
224
|
+
# as a 'folder' name.
|
225
|
+
# Returns an array of string keys that have been deleted.
|
226
|
+
#
|
227
|
+
# bucket.keys.map{|key| key.name}.join(', ') #=> 'test, test/2/34, test/3, test1, test1/logs'
|
228
|
+
# bucket.delete_folder('test') #=> ['test','test/2/34','test/3']
|
229
|
+
#
|
230
|
+
def delete_folder(folder, separator='/')
|
231
|
+
@s3.interface.delete_folder(@name, folder, separator)
|
232
|
+
end
|
233
|
+
|
234
|
+
# Delete a bucket. Bucket must be empty.
|
235
|
+
# If +force+ is set, clears and deletes the bucket.
|
236
|
+
# Returns +true+.
|
237
|
+
#
|
238
|
+
# bucket.delete(true) #=> true
|
239
|
+
#
|
240
|
+
def delete(force=false)
|
241
|
+
force ? @s3.interface.force_delete_bucket(@name) : @s3.interface.delete_bucket(@name)
|
242
|
+
end
|
243
|
+
|
244
|
+
# Return a list of grantees.
|
245
|
+
#
|
246
|
+
def grantees
|
247
|
+
Grantee::grantees(self)
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
|
252
|
+
|
253
|
+
class Key
|
254
|
+
attr_reader :bucket, :name, :last_modified, :e_tag, :size, :storage_class, :owner
|
255
|
+
attr_accessor :headers, :meta_headers
|
256
|
+
attr_writer :data
|
257
|
+
|
258
|
+
# Separate Amazon meta headers from other headers
|
259
|
+
def self.split_meta(headers) #:nodoc:
|
260
|
+
hash = headers.dup
|
261
|
+
meta = {}
|
262
|
+
hash.each do |key, value|
|
263
|
+
if key[/^#{S3Interface::AMAZON_METADATA_PREFIX}/]
|
264
|
+
meta[key.gsub(S3Interface::AMAZON_METADATA_PREFIX,'')] = value
|
265
|
+
hash.delete(key)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
[hash, meta]
|
269
|
+
end
|
270
|
+
|
271
|
+
def self.add_meta_prefix(meta_headers, prefix=S3Interface::AMAZON_METADATA_PREFIX)
|
272
|
+
meta = {}
|
273
|
+
meta_headers.each do |meta_header, value|
|
274
|
+
if meta_header[/#{prefix}/]
|
275
|
+
meta[meta_header] = value
|
276
|
+
else
|
277
|
+
meta["#{S3Interface::AMAZON_METADATA_PREFIX}#{meta_header}"] = value
|
278
|
+
end
|
279
|
+
end
|
280
|
+
meta
|
281
|
+
end
|
282
|
+
|
283
|
+
|
284
|
+
# Create a new Key instance, but do not create the actual key.
|
285
|
+
# The +name+ is a +String+.
|
286
|
+
# Returns a new Key instance.
|
287
|
+
#
|
288
|
+
# key = RightAws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<RightAws::S3::Key:0xb7b1e240 ... >
|
289
|
+
# key.exists? #=> true | false
|
290
|
+
# key.put('Woohoo!') #=> true
|
291
|
+
# key.exists? #=> true
|
292
|
+
#
|
293
|
+
def self.create(bucket, name, data=nil, meta_headers={})
|
294
|
+
new(bucket, name, data, {}, meta_headers)
|
295
|
+
end
|
296
|
+
|
297
|
+
# Create a new Key instance, but do not create the actual key.
|
298
|
+
# In normal use this method should not be called directly.
|
299
|
+
# Use RightAws::S3::Key.create or bucket.key() instead.
|
300
|
+
#
|
301
|
+
def initialize(bucket, name, data=nil, headers={}, meta_headers={},
|
302
|
+
last_modified=nil, e_tag=nil, size=nil, storage_class=nil, owner=nil)
|
303
|
+
raise 'Bucket must be a Bucket instance.' unless bucket.is_a?(Bucket)
|
304
|
+
@bucket = bucket
|
305
|
+
@name = name
|
306
|
+
@data = data
|
307
|
+
@e_tag = e_tag
|
308
|
+
@size = size.to_i
|
309
|
+
@storage_class = storage_class
|
310
|
+
@owner = owner
|
311
|
+
@last_modified = last_modified
|
312
|
+
if @last_modified && !@last_modified.is_a?(Time)
|
313
|
+
@last_modified = Time.parse(@last_modified)
|
314
|
+
end
|
315
|
+
@headers, @meta_headers = self.class.split_meta(headers)
|
316
|
+
@meta_headers.merge!(meta_headers)
|
317
|
+
end
|
318
|
+
|
319
|
+
# Return key name as a String.
|
320
|
+
#
|
321
|
+
# key = RightAws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<RightAws::S3::Key:0xb7b1e240 ... >
|
322
|
+
# puts key #=> 'logs/today/1.log'
|
323
|
+
#
|
324
|
+
def to_s
|
325
|
+
@name.to_s
|
326
|
+
end
|
327
|
+
|
328
|
+
# Return the full S3 path to this key (bucket/key).
|
329
|
+
#
|
330
|
+
# key.full_name #=> 'my_awesome_bucket/cool_key'
|
331
|
+
#
|
332
|
+
def full_name(separator='/')
|
333
|
+
"#{@bucket.to_s}#{separator}#{@name}"
|
334
|
+
end
|
335
|
+
|
336
|
+
# Return a public link to a key.
|
337
|
+
#
|
338
|
+
# key.public_link #=> 'https://s3.amazonaws.com:443/my_awesome_bucket/cool_key'
|
339
|
+
#
|
340
|
+
def public_link
|
341
|
+
params = @bucket.s3.interface.params
|
342
|
+
"#{params[:protocol]}://#{params[:server]}:#{params[:port]}/#{full_name('/')}"
|
343
|
+
end
|
344
|
+
|
345
|
+
# Return Key data. Retrieve this data from Amazon if it is the first time call.
|
346
|
+
# TODO TRB 6/19/07 What does the above mean? Clarify.
|
347
|
+
#
|
348
|
+
def data
|
349
|
+
get if !@data and exists?
|
350
|
+
@data
|
351
|
+
end
|
352
|
+
|
353
|
+
# Retrieve object data and attributes from Amazon.
|
354
|
+
# Returns a +String+.
|
355
|
+
#
|
356
|
+
def get(headers={})
|
357
|
+
response = @bucket.s3.interface.get(@bucket.name, @name, headers)
|
358
|
+
@data = response[:object]
|
359
|
+
@headers, @meta_headers = self.class.split_meta(response[:headers])
|
360
|
+
refresh(false)
|
361
|
+
@data
|
362
|
+
end
|
363
|
+
|
364
|
+
# Store object data on S3.
|
365
|
+
# Parameter +data+ is a +String+ or S3Object instance.
|
366
|
+
# Returns +true+.
|
367
|
+
#
|
368
|
+
# key = RightAws::S3::Key.create(bucket, 'logs/today/1.log')
|
369
|
+
# key.data = 'Qwerty'
|
370
|
+
# key.put #=> true
|
371
|
+
# ...
|
372
|
+
# key.put('Olala!') #=> true
|
373
|
+
#
|
374
|
+
def put(data=nil, perms=nil, headers={})
|
375
|
+
headers['x-amz-acl'] = perms if perms
|
376
|
+
@data = data || @data
|
377
|
+
meta = self.class.add_meta_prefix(@meta_headers)
|
378
|
+
@bucket.s3.interface.put(@bucket.name, @name, @data, meta.merge(headers))
|
379
|
+
end
|
380
|
+
|
381
|
+
# Retrieve key info from bucket and update attributes.
|
382
|
+
# Refresh meta-headers (by calling +head+ method) if +head+ is set.
|
383
|
+
# Returns +true+ if the key exists in bucket and +false+ otherwise.
|
384
|
+
#
|
385
|
+
# key = RightAws::S3::Key.create(bucket, 'logs/today/1.log')
|
386
|
+
# key.e_tag #=> nil
|
387
|
+
# key.meta_headers #=> {}
|
388
|
+
# key.refresh #=> true
|
389
|
+
# key.e_tag #=> '12345678901234567890bf11094484b6'
|
390
|
+
# key.meta_headers #=> {"family"=>"qwerty", "name"=>"asdfg"}
|
391
|
+
#
|
392
|
+
def refresh(head=true)
|
393
|
+
new_key = @bucket.key(self)
|
394
|
+
@last_modified = new_key.last_modified
|
395
|
+
@e_tag = new_key.e_tag
|
396
|
+
@size = new_key.size
|
397
|
+
@storage_class = new_key.storage_class
|
398
|
+
@owner = new_key.owner
|
399
|
+
if @last_modified
|
400
|
+
self.head
|
401
|
+
true
|
402
|
+
else
|
403
|
+
@headers = @meta_headers = {}
|
404
|
+
false
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
# Retrieve meta-headers from S3.
|
409
|
+
# Returns +true+.
|
410
|
+
#
|
411
|
+
# key.meta_headers #=> {"family"=>"qwerty"}
|
412
|
+
# key.head #=> true
|
413
|
+
# key.meta_headers #=> {"family"=>"qwerty", "name"=>"asdfg"}
|
414
|
+
#
|
415
|
+
def head
|
416
|
+
@headers, @meta_headers = self.class.split_meta(@bucket.s3.interface.head(@bucket, @name))
|
417
|
+
true
|
418
|
+
end
|
419
|
+
|
420
|
+
# Check for existence of the key in the given bucket.
|
421
|
+
# Returns +true+ or +false+.
|
422
|
+
#
|
423
|
+
# key = RightAws::S3::Key.create(bucket,'logs/today/1.log')
|
424
|
+
# key.exists? #=> false
|
425
|
+
# key.put('Woohoo!') #=> true
|
426
|
+
# key.exists? #=> true
|
427
|
+
#
|
428
|
+
def exists?
|
429
|
+
@bucket.key(self).last_modified ? true : false
|
430
|
+
end
|
431
|
+
|
432
|
+
# Remove key from bucket.
|
433
|
+
# Returns +true+.
|
434
|
+
#
|
435
|
+
# key.delete #=> true
|
436
|
+
#
|
437
|
+
def delete
|
438
|
+
raise 'Key name must be specified.' if @name.blank?
|
439
|
+
@bucket.s3.interface.delete(@bucket, @name)
|
440
|
+
end
|
441
|
+
|
442
|
+
# Return a list of grantees.
|
443
|
+
#
|
444
|
+
def grantees
|
445
|
+
Grantee::grantees(self)
|
446
|
+
end
|
447
|
+
|
448
|
+
end
|
449
|
+
|
450
|
+
|
451
|
+
class Owner
|
452
|
+
attr_reader :id, :name
|
453
|
+
|
454
|
+
def initialize(id, name)
|
455
|
+
@id = id
|
456
|
+
@name = name
|
457
|
+
end
|
458
|
+
|
459
|
+
# Return Owner name as a +String+.
|
460
|
+
def to_s
|
461
|
+
@name
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
|
466
|
+
# There are 2 ways to set permissions for a bucket or key (called a +thing+ below):
|
467
|
+
#
|
468
|
+
# 1 . Use +perms+ param to set 'Canned Access Policies' when calling the <tt>bucket.create</tt>,
|
469
|
+
# <tt>bucket.put</tt> and <tt>key.put</tt> methods.
|
470
|
+
# The +perms+ param can take these values: 'private', 'public-read', 'public-read-write' and
|
471
|
+
# 'authenticated-read'.
|
472
|
+
# (see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html).
|
473
|
+
#
|
474
|
+
# bucket = s3.bucket('bucket_for_kd_test_13', true, 'public-read')
|
475
|
+
# key.put('Woohoo!','public-read-write' )
|
476
|
+
#
|
477
|
+
# 2 . Use Grantee instances (the permission is a +String+ or an +Array+ of: 'READ', 'WRITE',
|
478
|
+
# 'READ_ACP', 'WRITE_ACP', 'FULL_CONTROL'):
|
479
|
+
#
|
480
|
+
# bucket = s3.bucket('my_awesome_bucket', true)
|
481
|
+
# grantee1 = RightAws::S3::Grantee.new(bucket, 'a123b...223c', FULL_CONTROL, :apply)
|
482
|
+
# grantee2 = RightAws::S3::Grantee.new(bucket, 'xy3v3...5fhp', [READ, WRITE], :apply)
|
483
|
+
#
|
484
|
+
# There is only one way to get and to remove permission (via Grantee instances):
|
485
|
+
#
|
486
|
+
# grantees = bucket.grantees # a list of Grantees that have any access for this bucket
|
487
|
+
# grantee1 = RightAws::S3::Grantee.new(bucket, 'a123b...223c')
|
488
|
+
# grantee1.perms #=> returns a list of perms for this grantee to that bucket
|
489
|
+
# ...
|
490
|
+
# grantee1.drop # remove all perms for this grantee
|
491
|
+
# grantee2.revoke('WRITE') # revoke write access only
|
492
|
+
#
|
493
|
+
class Grantee
|
494
|
+
# A bucket or a key the grantee has an access to.
|
495
|
+
attr_reader :thing
|
496
|
+
# Grantee Amazon id.
|
497
|
+
attr_reader :id
|
498
|
+
# Grantee display name.
|
499
|
+
attr_reader :name
|
500
|
+
# Array of permissions.
|
501
|
+
attr_accessor :perms
|
502
|
+
|
503
|
+
# Retrieve Owner information and a list of Grantee instances that have
|
504
|
+
# a access to this thing (bucket or key).
|
505
|
+
#
|
506
|
+
# bucket = s3.bucket('my_awesome_bucket', true, 'public-read')
|
507
|
+
# ...
|
508
|
+
# RightAws::S3::Grantee.owner_and_grantees(bucket) #=> [owner, grantees]
|
509
|
+
#
|
510
|
+
def self.owner_and_grantees(thing)
|
511
|
+
if thing.is_a?(Bucket)
|
512
|
+
bucket, key = thing, ''
|
513
|
+
else
|
514
|
+
bucket, key = thing.bucket, thing
|
515
|
+
end
|
516
|
+
hash = bucket.s3.interface.get_acl_parse(bucket.to_s, key.to_s)
|
517
|
+
owner = Owner.new(hash[:owner][:id], hash[:owner][:display_name])
|
518
|
+
|
519
|
+
grantees = []
|
520
|
+
hash[:grantees].each do |id, params|
|
521
|
+
grantees << new(thing, id, params[:permissions], nil, params[:display_name])
|
522
|
+
end
|
523
|
+
[owner, grantees]
|
524
|
+
end
|
525
|
+
|
526
|
+
# Retrieves a list of Grantees instances that have an access to this thing(bucket or key).
|
527
|
+
#
|
528
|
+
# bucket = s3.bucket('my_awesome_bucket', true, 'public-read')
|
529
|
+
# ...
|
530
|
+
# RightAws::S3::Grantee.grantees(bucket) #=> grantees
|
531
|
+
#
|
532
|
+
def self.grantees(thing)
|
533
|
+
owner_and_grantees(thing)[1]
|
534
|
+
end
|
535
|
+
|
536
|
+
def self.put_acl(thing, owner, grantees) #:nodoc:
|
537
|
+
if thing.is_a?(Bucket)
|
538
|
+
bucket, key = thing, ''
|
539
|
+
else
|
540
|
+
bucket, key = thing.bucket, thing
|
541
|
+
end
|
542
|
+
body = "<AccessControlPolicy>" +
|
543
|
+
"<Owner>" +
|
544
|
+
"<ID>#{owner.id}</ID>" +
|
545
|
+
"<DisplayName>#{owner.name}</DisplayName>" +
|
546
|
+
"</Owner>" +
|
547
|
+
"<AccessControlList>" +
|
548
|
+
grantees.map{|grantee| grantee.to_xml}.join +
|
549
|
+
"</AccessControlList>" +
|
550
|
+
"</AccessControlPolicy>"
|
551
|
+
bucket.s3.interface.put_acl(bucket.to_s, key.to_s, body)
|
552
|
+
end
|
553
|
+
|
554
|
+
# Create a new Grantee instance.
|
555
|
+
# Grantee +id+ must exist on S3. If +action+ == :refresh, then retrieve
|
556
|
+
# permissions from S3 and update @perms. If +action+ == :apply, then apply
|
557
|
+
# perms to +thing+ at S3. The default action is :refresh.
|
558
|
+
#
|
559
|
+
# bucket = s3.bucket('my_awesome_bucket', true, 'public-read')
|
560
|
+
# grantee1 = RightAws::S3::Grantee.new(bucket, 'a123b...223c', FULL_CONTROL)
|
561
|
+
# ...
|
562
|
+
# grantee2 = RightAws::S3::Grantee.new(bucket, 'abcde...asdf', [FULL_CONTROL, READ], :apply)
|
563
|
+
#
|
564
|
+
#
|
565
|
+
def initialize(thing, id, perms=[], action=:refresh, name=nil)
|
566
|
+
@thing = thing
|
567
|
+
@id = id
|
568
|
+
@name = name
|
569
|
+
@perms = perms.to_a
|
570
|
+
case action
|
571
|
+
when :apply; apply
|
572
|
+
when :refresh; refresh
|
573
|
+
end
|
574
|
+
end
|
575
|
+
|
576
|
+
# Return Grantee type (+String+): "Group" or "CanonicalUser".
|
577
|
+
def type
|
578
|
+
@id[/^http:/] ? "Group" : "CanonicalUser"
|
579
|
+
end
|
580
|
+
|
581
|
+
# Return a name or an id.
|
582
|
+
def to_s
|
583
|
+
@name || @id
|
584
|
+
end
|
585
|
+
|
586
|
+
# Add permissions for grantee.
|
587
|
+
# Permissions: 'READ', 'WRITE', 'READ_ACP', 'WRITE_ACP', 'FULL_CONTROL'.
|
588
|
+
# See http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingPermissions.html .
|
589
|
+
# Returns +true+.
|
590
|
+
#
|
591
|
+
# grantee.grant('FULL_CONTROL') #=> true
|
592
|
+
#
|
593
|
+
def grant(permission)
|
594
|
+
return true if @perms.include?(permission)
|
595
|
+
@perms += permission.to_a
|
596
|
+
apply
|
597
|
+
end
|
598
|
+
|
599
|
+
# Revoke permissions for grantee.
|
600
|
+
# Permissions: 'READ', 'WRITE', 'READ_ACP', 'WRITE_ACP', 'FULL_CONTROL'
|
601
|
+
# See http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingPermissions.html .
|
602
|
+
# Default value is 'FULL_CONTROL'.
|
603
|
+
# Returns +true+.
|
604
|
+
#
|
605
|
+
# grantee.revoke #=> true
|
606
|
+
#
|
607
|
+
def revoke(permission)
|
608
|
+
return true unless @perms.include?(permission)
|
609
|
+
@perms -= permission.to_a
|
610
|
+
apply
|
611
|
+
end
|
612
|
+
|
613
|
+
# Revoke all permissions for this grantee.
|
614
|
+
# Returns +true+.
|
615
|
+
#
|
616
|
+
# grantee.drop #=> true
|
617
|
+
#
|
618
|
+
def drop
|
619
|
+
@perms = []
|
620
|
+
apply
|
621
|
+
end
|
622
|
+
|
623
|
+
# Refresh grantee perms for its +thing+.
|
624
|
+
# Returns +true+ if the grantee has perms for this +thing+ or
|
625
|
+
# +false+ otherwise, and updates @perms value as a side-effect.
|
626
|
+
#
|
627
|
+
# grantee.grant('FULL_CONTROL') #=> true
|
628
|
+
# grantee.refresh #=> true
|
629
|
+
# grantee.drop #=> true
|
630
|
+
# grantee.refresh #=> false
|
631
|
+
#
|
632
|
+
def refresh
|
633
|
+
@perms = []
|
634
|
+
self.class.grantees(@thing).each do |grantee|
|
635
|
+
if @id == grantee.id
|
636
|
+
@name = grantee.name
|
637
|
+
@perms = grantee.perms
|
638
|
+
return true
|
639
|
+
end
|
640
|
+
end
|
641
|
+
false
|
642
|
+
end
|
643
|
+
|
644
|
+
# Apply current grantee @perms to +thing+. This method is called internally by the +grant+
|
645
|
+
# and +revoke+ methods. In normal use this method should not
|
646
|
+
# be called directly.
|
647
|
+
#
|
648
|
+
# grantee.perms = ['FULL_CONTROL']
|
649
|
+
# grantee.apply #=> true
|
650
|
+
#
|
651
|
+
def apply
|
652
|
+
owner, grantees = self.class.owner_and_grantees(@thing)
|
653
|
+
grantees.map! do |grantee|
|
654
|
+
grantee.id == @id ? self : grantee
|
655
|
+
end
|
656
|
+
self.class.put_acl(@thing, owner, grantees)
|
657
|
+
end
|
658
|
+
|
659
|
+
def to_xml # :nodoc:
|
660
|
+
id_str = @id[/^http/] ? "<URI>#{@id}</URI>" : "<ID>#{@id}</ID>"
|
661
|
+
grants = ''
|
662
|
+
@perms.each do |perm|
|
663
|
+
grants << "<Grant>" +
|
664
|
+
"<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
665
|
+
"xsi:type=\"#{type}\">#{id_str}</Grantee>" +
|
666
|
+
"<Permission>#{perm}</Permission>" +
|
667
|
+
"</Grant>"
|
668
|
+
end
|
669
|
+
grants
|
670
|
+
end
|
671
|
+
|
672
|
+
end
|
673
|
+
|
674
|
+
end
|
675
|
+
|
676
|
+
# RightAws::S3Generator and RightAws::S3Generator::Bucket methods:
|
677
|
+
#
|
678
|
+
# s3g = RightAws::S3Generator.new('1...2', 'nx...Y6') #=> #<RightAws::S3Generator:0xb7b5cc94>
|
679
|
+
#
|
680
|
+
# # List all buckets(method 'GET'):
|
681
|
+
# buckets_list = s3g.buckets #=> 'https://s3.amazonaws.com:443/?Signature=Y...D&Expires=1180941864&AWSAccessKeyId=1...2'
|
682
|
+
# # Create bucket link (method 'PUT'):
|
683
|
+
# bucket = s3g.bucket('my_awesome_bucket') #=> #<RightAws::S3Generator::Bucket:0xb7bcbda8>
|
684
|
+
# link_to_create = bucket.create_link(1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=4...D&Expires=1180942132&AWSAccessKeyId=1...2
|
685
|
+
# # ... or:
|
686
|
+
# bucket = RightAws::S3Generator::Bucket.create(s3g, 'my_awesome_bucket') #=> #<RightAws::S3Generator::Bucket:0xb7bcbda8>
|
687
|
+
# link_to_create = bucket.create_link(1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=4...D&Expires=1180942132&AWSAccessKeyId=1...2
|
688
|
+
# # ... or:
|
689
|
+
# bucket = RightAws::S3Generator::Bucket.new(s3g, 'my_awesome_bucket') #=> #<RightAws::S3Generator::Bucket:0xb7bcbda8>
|
690
|
+
# link_to_create = bucket.create_link(1.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=4...D&Expires=1180942132&AWSAccessKeyId=1...2
|
691
|
+
# # List bucket(method 'GET'):
|
692
|
+
# bucket.keys(1.day) #=> https://s3.amazonaws.com:443/my_awesome_bucket?Signature=i...D&Expires=1180942620&AWSAccessKeyId=1...2
|
693
|
+
# # Create/put key (method 'PUT'):
|
694
|
+
# bucket.put('my_cool_key') #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=q...D&Expires=1180943094&AWSAccessKeyId=1...2
|
695
|
+
# # Get key data (method 'GET'):
|
696
|
+
# 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
|
697
|
+
# # Delete bucket (method 'DELETE'):
|
698
|
+
# bucket.delete(2.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=4...D&Expires=1180820032&AWSAccessKeyId=1...2
|
699
|
+
#
|
700
|
+
# RightAws::S3Generator::Key methods:
|
701
|
+
#
|
702
|
+
# # Create Key instance:
|
703
|
+
# key = RightAws::S3Generator::Key.new(bicket, 'my_cool_key') #=> #<RightAws::S3Generator::Key:0xb7b7394c>
|
704
|
+
# # Put key data (method 'PUT'):
|
705
|
+
# key.put #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=2...D&Expires=1180943302&AWSAccessKeyId=1...2
|
706
|
+
# # Get key data (method 'GET'):
|
707
|
+
# key.get #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=a...D&Expires=1180820032&AWSAccessKeyId=1...2
|
708
|
+
# # Head key (method 'HEAD'):
|
709
|
+
# key.head #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=b...D&Expires=1180820032&AWSAccessKeyId=1...2
|
710
|
+
# # Delete key (method 'DELETE'):
|
711
|
+
# key.delete #=> https://s3.amazonaws.com:443/my_awesome_bucket/my_cool_key?Signature=x...D&Expires=1180820032&AWSAccessKeyId=1...2
|
712
|
+
#
|
713
|
+
class S3Generator
|
714
|
+
attr_reader :interface
|
715
|
+
|
716
|
+
def initialize(aws_access_key_id, aws_secret_access_key, params={})
|
717
|
+
@interface = S3Interface.new(aws_access_key_id, aws_secret_access_key, params)
|
718
|
+
end
|
719
|
+
|
720
|
+
# Generate link to list all buckets
|
721
|
+
#
|
722
|
+
# s3.buckets(1.hour)
|
723
|
+
#
|
724
|
+
def buckets(expires=nil, headers={})
|
725
|
+
@interface.list_all_my_buckets_link(expires, headers)
|
726
|
+
end
|
727
|
+
|
728
|
+
# Create new S3LinkBucket instance and generate link to create it at S3.
|
729
|
+
#
|
730
|
+
# bucket= s3.bucket('my_owesome_bucket')
|
731
|
+
#
|
732
|
+
def bucket(name, expires=nil, headers={})
|
733
|
+
Bucket.create(self, name.to_s)
|
734
|
+
end
|
735
|
+
|
736
|
+
class Bucket
|
737
|
+
attr_reader :s3, :name
|
738
|
+
|
739
|
+
def to_s
|
740
|
+
@name
|
741
|
+
end
|
742
|
+
alias_method :full_name, :to_s
|
743
|
+
|
744
|
+
# Return a public link to bucket.
|
745
|
+
#
|
746
|
+
# bucket.public_link #=> 'https://s3.amazonaws.com:443/my_awesome_bucket'
|
747
|
+
#
|
748
|
+
def public_link
|
749
|
+
params = @s3.interface.params
|
750
|
+
"#{params[:protocol]}://#{params[:server]}:#{params[:port]}/#{full_name}"
|
751
|
+
end
|
752
|
+
|
753
|
+
# Create new S3LinkBucket instance and generate creation link for it.
|
754
|
+
def self.create(s3, name, expires=nil, headers={})
|
755
|
+
new(s3, name.to_s)
|
756
|
+
end
|
757
|
+
|
758
|
+
# Create new S3LinkBucket instance.
|
759
|
+
def initialize(s3, name)
|
760
|
+
@s3, @name = s3, name.to_s
|
761
|
+
end
|
762
|
+
|
763
|
+
# Return a link to create this bucket.
|
764
|
+
#
|
765
|
+
def create_link(expires=nil, headers={})
|
766
|
+
@s3.interface.create_bucket_link(@name, expires, headers)
|
767
|
+
end
|
768
|
+
|
769
|
+
# Generate link to list keys.
|
770
|
+
#
|
771
|
+
# bucket.keys
|
772
|
+
# bucket.keys('prefix'=>'logs')
|
773
|
+
#
|
774
|
+
def keys(options=nil, expires=nil, headers={})
|
775
|
+
@s3.interface.list_bucket_link(@name, options, expires, headers)
|
776
|
+
end
|
777
|
+
|
778
|
+
# Return a S3Generator::Key instance.
|
779
|
+
#
|
780
|
+
# 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
|
781
|
+
# 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
|
782
|
+
#
|
783
|
+
def key(name)
|
784
|
+
Key.new(self, name)
|
785
|
+
end
|
786
|
+
|
787
|
+
# Generates link to PUT key data.
|
788
|
+
#
|
789
|
+
# puts bucket.put('logs/today/1.log', 2.hour)
|
790
|
+
#
|
791
|
+
def put(key, meta_headers={}, expires=nil, headers={})
|
792
|
+
meta = RightAws::S3::Key.add_meta_prefix(meta_headers)
|
793
|
+
@s3.interface.put_link(@name, key.to_s, nil, expires, meta.merge(headers))
|
794
|
+
end
|
795
|
+
|
796
|
+
# Generate link to GET key data.
|
797
|
+
#
|
798
|
+
# bucket.get('logs/today/1.log', 1.hour)
|
799
|
+
#
|
800
|
+
def get(key, expires=nil, headers={})
|
801
|
+
@s3.interface.get_link(@name, key.to_s, expires, headers)
|
802
|
+
end
|
803
|
+
|
804
|
+
# Generate link to delete bucket.
|
805
|
+
#
|
806
|
+
# bucket.delete(2.hour)
|
807
|
+
#
|
808
|
+
def delete(expires=nil, headers={})
|
809
|
+
@s3.interface.delete_bucket_link(@name, expires, headers)
|
810
|
+
end
|
811
|
+
end
|
812
|
+
|
813
|
+
|
814
|
+
class Key
|
815
|
+
attr_reader :bucket, :name
|
816
|
+
|
817
|
+
def to_s
|
818
|
+
@name
|
819
|
+
end
|
820
|
+
|
821
|
+
# Return a full S# name (bucket/key).
|
822
|
+
#
|
823
|
+
# key.full_name #=> 'my_awesome_bucket/cool_key'
|
824
|
+
#
|
825
|
+
def full_name(separator='/')
|
826
|
+
"#{@bucket.to_s}#{separator}#{@name}"
|
827
|
+
end
|
828
|
+
|
829
|
+
# Return a public link to key.
|
830
|
+
#
|
831
|
+
# key.public_link #=> 'https://s3.amazonaws.com:443/my_awesome_bucket/cool_key'
|
832
|
+
#
|
833
|
+
def public_link
|
834
|
+
params = @bucket.s3.interface.params
|
835
|
+
"#{params[:protocol]}://#{params[:server]}:#{params[:port]}/#{full_name('/')}"
|
836
|
+
end
|
837
|
+
|
838
|
+
def initialize(bucket, name, meta_headers={})
|
839
|
+
@bucket = bucket
|
840
|
+
@name = name.to_s
|
841
|
+
@meta_headers = meta_headers
|
842
|
+
raise 'Key name can not be empty.' if @name.blank?
|
843
|
+
end
|
844
|
+
|
845
|
+
# Generate link to PUT key data.
|
846
|
+
#
|
847
|
+
# 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
|
848
|
+
#
|
849
|
+
def put(expires=nil, headers={})
|
850
|
+
@bucket.put(@name.to_s, @meta_headers, expires, headers)
|
851
|
+
end
|
852
|
+
|
853
|
+
# Generate link to GET key data.
|
854
|
+
#
|
855
|
+
# 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
|
856
|
+
#
|
857
|
+
def get(expires=nil, headers={})
|
858
|
+
@bucket.s3.interface.get_link(@bucket.to_s, @name, expires, headers)
|
859
|
+
end
|
860
|
+
|
861
|
+
# Generate link to delete key.
|
862
|
+
#
|
863
|
+
# bucket.delete(2.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=4...D&Expires=1180820032&AWSAccessKeyId=1...2
|
864
|
+
#
|
865
|
+
def delete(expires=nil, headers={})
|
866
|
+
@bucket.s3.interface.delete_link(@bucket.to_s, @name, expires, headers)
|
867
|
+
end
|
868
|
+
|
869
|
+
# Generate link to head key.
|
870
|
+
#
|
871
|
+
# bucket.head(2.hour) #=> https://s3.amazonaws.com:443/my_awesome_bucket/logs%2Ftoday%2F1.log?Signature=4...D&Expires=1180820032&AWSAccessKeyId=1...2
|
872
|
+
#
|
873
|
+
def head(expires=nil, headers={})
|
874
|
+
@bucket.s3.interface.head_link(@bucket.to_s, @name, expires, headers)
|
875
|
+
end
|
876
|
+
end
|
877
|
+
end
|
878
|
+
|
879
|
+
end
|