s3 0.3.11 → 0.3.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile.lock +1 -1
- data/README.rdoc +27 -0
- data/lib/s3/bucket.rb +42 -7
- data/lib/s3/buckets_extension.rb +4 -1
- data/lib/s3/connection.rb +1 -1
- data/lib/s3/exceptions.rb +1 -0
- data/lib/s3/object.rb +15 -4
- data/lib/s3/parser.rb +38 -0
- data/lib/s3/signature.rb +22 -4
- data/lib/s3/version.rb +1 -1
- data/s3.gemspec +3 -3
- data/test/object_test.rb +5 -0
- data/test/service_test.rb +2 -4
- data/test/signature_test.rb +23 -0
- metadata +39 -32
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1e94aa6f4e9214e728160e133f28264d1bd00b25
|
4
|
+
data.tar.gz: e3e15a25e2ef8f5882f088ec487ebb177cbc56b9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2faf2eb87b1bf05b904dea7134e4efddd14b118963a7a0bb817d26e3277a43072c180bb4fe92a1bec92ac5fc97f42f558144e33e27d890487bdbffdfff4969fb
|
7
|
+
data.tar.gz: e19ef4917499f81051c263883660353a5a17c1c334cae53cc212f251c2ded50520d0cc1970debc09f76876bcd03b0818f93958d27f3e2b7bc152337e6cfc40a6
|
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -28,6 +28,15 @@ It supports both: European and US buckets through the {REST API}[http://docs.ama
|
|
28
28
|
first_bucket = service.buckets.find("first-bucket")
|
29
29
|
#=> #<S3::Bucket:first-bucket>
|
30
30
|
|
31
|
+
=== Create bucket
|
32
|
+
|
33
|
+
new_bucket = service.buckets.build("newbucketname")
|
34
|
+
new_bucket.save(:location => :eu)
|
35
|
+
|
36
|
+
Remember that bucket name for EU can't include "_" (underscore).
|
37
|
+
|
38
|
+
Please refer to: http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html for more information about bucket name restrictions.
|
39
|
+
|
31
40
|
=== List objects in a bucket
|
32
41
|
|
33
42
|
first_bucket.objects
|
@@ -67,6 +76,24 @@ It supports both: European and US buckets through the {REST API}[http://docs.ama
|
|
67
76
|
Please note that new objects are created with "public-read" ACL by
|
68
77
|
default.
|
69
78
|
|
79
|
+
=== Fetch ACL
|
80
|
+
|
81
|
+
object = bucket.objects.find('lenna.png')
|
82
|
+
object.request_acl # or bucket.request_acl
|
83
|
+
|
84
|
+
This will return hash with all users/groups and theirs permissions
|
85
|
+
|
86
|
+
=== Modify ACL
|
87
|
+
|
88
|
+
object = bucket.objects.find("lenna.png")
|
89
|
+
object.copy(:key => "lenna.png", :bucket => bucket, :acl => :private)
|
90
|
+
|
91
|
+
=== Upload file direct to amazon
|
92
|
+
|
93
|
+
==== Rails 3
|
94
|
+
|
95
|
+
To do that you just send file using proper form direct to amazon. You can create simple halper for that, for example like this one: https://gist.github.com/3169039
|
96
|
+
|
70
97
|
== See also
|
71
98
|
|
72
99
|
* rubygems[http://rubygems.org/gems/s3]
|
data/lib/s3/bucket.rb
CHANGED
@@ -4,14 +4,14 @@ module S3
|
|
4
4
|
include Proxies
|
5
5
|
extend Forwardable
|
6
6
|
|
7
|
-
attr_reader :name, :service
|
7
|
+
attr_reader :name, :service, :acl
|
8
8
|
|
9
9
|
def_instance_delegators :service, :service_request
|
10
10
|
private_class_method :new
|
11
11
|
|
12
12
|
# Retrieves the bucket information from the server. Raises an
|
13
13
|
# S3::Error exception if the bucket doesn't exist or you don't
|
14
|
-
# have access to it
|
14
|
+
# have access to it.
|
15
15
|
def retrieve
|
16
16
|
bucket_headers
|
17
17
|
self
|
@@ -30,11 +30,34 @@ module S3
|
|
30
30
|
self.name == other.name and self.service == other.service
|
31
31
|
end
|
32
32
|
|
33
|
+
# Retrieves acl for bucket from the server.
|
34
|
+
#
|
35
|
+
# Return:
|
36
|
+
# hash: user|group => permission
|
37
|
+
def request_acl
|
38
|
+
body = bucket_request(:get, :params => "acl").body
|
39
|
+
parse_acl(body)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Assigns a new ACL to the bucket. Please note that ACL is not
|
43
|
+
# retrieved from the server and set to "public-read" by default.
|
44
|
+
#
|
45
|
+
# Valid Values: :private | :public_read | :public_read_write | authenticated_read
|
46
|
+
#
|
47
|
+
# ==== Example
|
48
|
+
# bucket.acl = :public_read
|
49
|
+
def acl=(acl)
|
50
|
+
@acl = acl.to_s.gsub("_","-") if acl
|
51
|
+
end
|
52
|
+
|
33
53
|
# Similar to retrieve, but catches S3::Error::NoSuchBucket
|
34
|
-
# exceptions and returns false instead.
|
54
|
+
# exceptions and returns false instead. Also catch S3::Error::ForbiddenBucket
|
55
|
+
# and return true
|
35
56
|
def exists?
|
36
57
|
retrieve
|
37
58
|
true
|
59
|
+
rescue Error::ForbiddenBucket
|
60
|
+
true
|
38
61
|
rescue Error::NoSuchBucket
|
39
62
|
false
|
40
63
|
end
|
@@ -101,6 +124,14 @@ module S3
|
|
101
124
|
"#<#{self.class}:#{name}>"
|
102
125
|
end
|
103
126
|
|
127
|
+
def save_acl(options = {})
|
128
|
+
headers = {}
|
129
|
+
headers[:content_length] = 0
|
130
|
+
headers[:x_amz_acl] = options[:acl] || acl || "public-read"
|
131
|
+
|
132
|
+
response = bucket_request(:put, :headers => headers, :path => name)
|
133
|
+
end
|
134
|
+
|
104
135
|
private
|
105
136
|
|
106
137
|
attr_writer :service
|
@@ -135,10 +166,13 @@ module S3
|
|
135
166
|
def bucket_headers(options = {})
|
136
167
|
response = bucket_request(:head, :params => options)
|
137
168
|
rescue Error::ResponseError => e
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
169
|
+
case e.response.code.to_i
|
170
|
+
when 404
|
171
|
+
raise Error::ResponseError.exception("NoSuchBucket").new("The specified bucket does not exist.", nil)
|
172
|
+
when 403
|
173
|
+
raise Error::ResponseError.exception("ForbiddenBucket").new("The specified bucket exist but you do not have access to it.", nil)
|
174
|
+
else
|
175
|
+
raise e
|
142
176
|
end
|
143
177
|
end
|
144
178
|
|
@@ -174,5 +208,6 @@ module S3
|
|
174
208
|
def name_valid?(name)
|
175
209
|
name =~ /\A[a-z0-9][a-z0-9\._-]{2,254}\Z/i and name !~ /\A#{URI::REGEXP::PATTERN::IPV4ADDR}\Z/
|
176
210
|
end
|
211
|
+
|
177
212
|
end
|
178
213
|
end
|
data/lib/s3/buckets_extension.rb
CHANGED
@@ -5,10 +5,13 @@ module S3
|
|
5
5
|
Bucket.send(:new, proxy_owner, name)
|
6
6
|
end
|
7
7
|
|
8
|
-
# Finds the bucket with given name
|
8
|
+
# Finds the bucket with given name (only those which exist and You have access to it)
|
9
|
+
# return nil in case Error::NoSuchBucket or Error::ForbiddenBucket
|
9
10
|
def find_first(name)
|
10
11
|
bucket = build(name)
|
11
12
|
bucket.retrieve
|
13
|
+
rescue Error::ForbiddenBucket, Error::NoSuchBucket
|
14
|
+
nil
|
12
15
|
end
|
13
16
|
alias :find :find_first
|
14
17
|
|
data/lib/s3/connection.rb
CHANGED
@@ -128,7 +128,7 @@ module S3
|
|
128
128
|
# Hash of headers translated from symbol to string, containing
|
129
129
|
# only interesting headers
|
130
130
|
def self.parse_headers(headers)
|
131
|
-
interesting_keys = [:content_type, :cache_control, :x_amz_acl, :x_amz_storage_class, :range,
|
131
|
+
interesting_keys = [:content_type, :content_length, :cache_control, :x_amz_acl, :x_amz_storage_class, :range,
|
132
132
|
:if_modified_since, :if_unmodified_since,
|
133
133
|
:if_match, :if_none_match,
|
134
134
|
:content_disposition, :content_encoding,
|
data/lib/s3/exceptions.rb
CHANGED
@@ -52,6 +52,7 @@ module S3
|
|
52
52
|
class EntityTooSmall < ResponseError; end
|
53
53
|
class EntityTooLarge < ResponseError; end
|
54
54
|
class ExpiredToken < ResponseError; end
|
55
|
+
class ForbiddenBucket < ResponseError; end
|
55
56
|
class IncompleteBody < ResponseError; end
|
56
57
|
class IncorrectNumberOfFilesInPostRequestPOST < ResponseError; end
|
57
58
|
class InlineDataTooLarge < ResponseError; end
|
data/lib/s3/object.rb
CHANGED
@@ -52,9 +52,11 @@ module S3
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# Retrieves the object from the server. Method is used to download
|
55
|
-
# object information only (content type, size
|
56
|
-
# NOT download the content of the object
|
57
|
-
# to do it).
|
55
|
+
# object information only (content type, size).
|
56
|
+
# Notice: It does NOT download the content of the object
|
57
|
+
# (use the #content method to do it).
|
58
|
+
# Notice: this do not fetch acl information, use #request_acl
|
59
|
+
# method for that.
|
58
60
|
def retrieve
|
59
61
|
object_headers
|
60
62
|
self
|
@@ -70,6 +72,15 @@ module S3
|
|
70
72
|
false
|
71
73
|
end
|
72
74
|
|
75
|
+
# Retrieves acl for object from the server.
|
76
|
+
#
|
77
|
+
# Return:
|
78
|
+
# hash: user|group => permission
|
79
|
+
def request_acl
|
80
|
+
response = object_request(:get, :params => "acl")
|
81
|
+
parse_acl(response.body)
|
82
|
+
end
|
83
|
+
|
73
84
|
# Downloads the content of the object, and caches it. Pass true to
|
74
85
|
# clear the cache and download the object again.
|
75
86
|
def content(reload = false)
|
@@ -107,7 +118,7 @@ module S3
|
|
107
118
|
# Returns Object's URL using protocol specified in service,
|
108
119
|
# e.g. <tt>http://domain.com.s3.amazonaws.com/key/with/path.extension</tt>
|
109
120
|
def url
|
110
|
-
|
121
|
+
"#{protocol}#{host}/#{path_prefix}#{URI.escape(key, /[^#{URI::REGEXP::PATTERN::UNRESERVED}\/]/)}"
|
111
122
|
end
|
112
123
|
|
113
124
|
# Returns a temporary url to the object that expires on the
|
data/lib/s3/parser.rb
CHANGED
@@ -48,5 +48,43 @@ module S3
|
|
48
48
|
def parse_is_truncated xml
|
49
49
|
rexml_document(xml).elements["ListBucketResult/IsTruncated"].text =='true'
|
50
50
|
end
|
51
|
+
|
52
|
+
|
53
|
+
# Parse acl response and return hash with grantee and their permissions
|
54
|
+
def parse_acl(xml)
|
55
|
+
grants = {}
|
56
|
+
rexml_document(xml).elements.each("AccessControlPolicy/AccessControlList/Grant") do |grant|
|
57
|
+
grants.merge!(extract_grantee(grant))
|
58
|
+
end
|
59
|
+
grants
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def convert_uri_to_group_name(uri)
|
65
|
+
case uri
|
66
|
+
when "http://acs.amazonaws.com/groups/global/AllUsers"
|
67
|
+
return "Everyone"
|
68
|
+
when "http://acs.amazonaws.com/groups/global/AuthenticatedUsers"
|
69
|
+
return "Authenticated Users"
|
70
|
+
when "http://acs.amazonaws.com/groups/s3/LogDelivery"
|
71
|
+
return "Log Delivery"
|
72
|
+
else
|
73
|
+
return uri
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def extract_grantee(grant)
|
78
|
+
grants = {}
|
79
|
+
grant.each_element_with_attribute("xsi:type", "Group") do |grantee|
|
80
|
+
group_name = convert_uri_to_group_name(grantee.get_text("URI").value)
|
81
|
+
grants[group_name] = grant.get_text("Permission").value
|
82
|
+
end
|
83
|
+
grant.each_element_with_attribute("xsi:type", "CanonicalUser") do |grantee|
|
84
|
+
user_name = grantee.get_text("DisplayName").value
|
85
|
+
grants[user_name] = grant.get_text("Permission").value
|
86
|
+
end
|
87
|
+
grants
|
88
|
+
end
|
51
89
|
end
|
52
90
|
end
|
data/lib/s3/signature.rb
CHANGED
@@ -25,7 +25,9 @@ module S3
|
|
25
25
|
request = options[:request]
|
26
26
|
access_key_id = options[:access_key_id]
|
27
27
|
|
28
|
-
options.merge!(:headers => request,
|
28
|
+
options.merge!(:headers => request,
|
29
|
+
:method => request.method,
|
30
|
+
:resource => request.path)
|
29
31
|
|
30
32
|
signature = canonicalized_signature(options)
|
31
33
|
|
@@ -45,6 +47,8 @@ module S3
|
|
45
47
|
# the resource, defaults to GET
|
46
48
|
# * <tt>:headers</tt> - Any additional HTTP headers you intend
|
47
49
|
# to use when requesting the resource
|
50
|
+
# * <tt>:add_bucket_to_host</tt> - Use in case of virtual-host style,
|
51
|
+
# defaults to false
|
48
52
|
def self.generate_temporary_url_signature(options)
|
49
53
|
bucket = options[:bucket]
|
50
54
|
resource = options[:resource]
|
@@ -54,7 +58,10 @@ module S3
|
|
54
58
|
headers = options[:headers] || {}
|
55
59
|
headers.merge!("date" => expires.to_i.to_s)
|
56
60
|
|
57
|
-
|
61
|
+
resource = "/#{URI.escape(resource, /[^#{URI::REGEXP::PATTERN::UNRESERVED}\/]/)}"
|
62
|
+
resource = "/#{bucket}" + resource unless options[:add_bucket_to_host]
|
63
|
+
|
64
|
+
options.merge!(:resource => resource,
|
58
65
|
:method => options[:method] || :get,
|
59
66
|
:headers => headers)
|
60
67
|
signature = canonicalized_signature(options)
|
@@ -76,14 +83,25 @@ module S3
|
|
76
83
|
# the resource, defaults to GET
|
77
84
|
# * <tt>:headers</tt> - Any additional HTTP headers you intend
|
78
85
|
# to use when requesting the resource
|
86
|
+
# * <tt>:add_bucket_to_host</tt> - Use in case of virtual-host style,
|
87
|
+
# defaults to false
|
79
88
|
def self.generate_temporary_url(options)
|
80
89
|
bucket = options[:bucket]
|
81
90
|
resource = options[:resource]
|
82
91
|
access_key = options[:access_key]
|
83
92
|
expires = options[:expires_at].to_i
|
93
|
+
host = S3::HOST
|
94
|
+
|
95
|
+
if options[:add_bucket_to_host]
|
96
|
+
host = bucket + '.' + host
|
97
|
+
url = "http://#{host}/#{resource}"
|
98
|
+
else
|
99
|
+
url = "http://#{host}/#{bucket}/#{resource}"
|
100
|
+
end
|
101
|
+
|
102
|
+
options[:host] = host
|
84
103
|
signature = generate_temporary_url_signature(options)
|
85
104
|
|
86
|
-
url = "http://#{S3::HOST}/#{bucket}/#{resource}"
|
87
105
|
url << "?AWSAccessKeyId=#{access_key}"
|
88
106
|
url << "&Expires=#{expires}"
|
89
107
|
url << "&Signature=#{signature}"
|
@@ -209,7 +227,7 @@ module S3
|
|
209
227
|
# requests that don't address a bucket, do nothing. For more
|
210
228
|
# information on virtual hosted-style requests, see Virtual
|
211
229
|
# Hosting of Buckets.
|
212
|
-
bucket_name = host.sub(
|
230
|
+
bucket_name = host.sub(/\.?#{S3::HOST}\Z/, "")
|
213
231
|
string << "/#{bucket_name}" unless bucket_name.empty?
|
214
232
|
|
215
233
|
# 3. Append the path part of the un-decoded HTTP Request-URI,
|
data/lib/s3/version.rb
CHANGED
data/s3.gemspec
CHANGED
@@ -9,9 +9,9 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.name = "s3"
|
10
10
|
s.version = S3::VERSION
|
11
11
|
s.platform = Gem::Platform::RUBY
|
12
|
-
s.authors = ["
|
13
|
-
s.email = ["
|
14
|
-
s.homepage = "http://
|
12
|
+
s.authors = ["Kuba Kuźma"]
|
13
|
+
s.email = ["kuba@jah.pl"]
|
14
|
+
s.homepage = "http://github.com/qoobaa/s3"
|
15
15
|
s.summary = "Library for accessing S3 objects and buckets"
|
16
16
|
s.description = "S3 library provides access to Amazon's Simple Storage Service. It supports both: European and US buckets through REST API."
|
17
17
|
|
data/test/object_test.rb
CHANGED
@@ -68,6 +68,11 @@ class ObjectTest < Test::Unit::TestCase
|
|
68
68
|
expected = "http://images.s3.amazonaws.com/Lena%20S%C3%B6derberg.png"
|
69
69
|
actual = object12.url
|
70
70
|
assert_equal expected, actual
|
71
|
+
|
72
|
+
object13 = S3::Object.send(:new, bucket1, :key => "Lena Söderberg [1].png")
|
73
|
+
expected = "http://images.s3.amazonaws.com/Lena%20S%C3%B6derberg%20%5B1%5D.png"
|
74
|
+
actual = object13.url
|
75
|
+
assert_equal expected, actual
|
71
76
|
|
72
77
|
bucket2 = S3::Bucket.send(:new, @service, "images_new")
|
73
78
|
|
data/test/service_test.rb
CHANGED
@@ -87,10 +87,8 @@ class ServiceTest < Test::Unit::TestCase
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
-
test "buckets find first
|
91
|
-
|
92
|
-
@service_bucket_not_exists.buckets.find_first("data2.example.com")
|
93
|
-
end
|
90
|
+
test "buckets find first return nil" do
|
91
|
+
assert_equal nil, @service_bucket_not_exists.buckets.find_first("data2.example.com")
|
94
92
|
end
|
95
93
|
|
96
94
|
test "buckets find all on empty list" do
|
data/test/signature_test.rb
CHANGED
@@ -151,6 +151,17 @@ class SignatureTest < Test::Unit::TestCase
|
|
151
151
|
expected = "gs6xNznrLJ4Bd%2B1y9pcy2HOSVeg%3D"
|
152
152
|
assert_equal expected, actual
|
153
153
|
end
|
154
|
+
|
155
|
+
test "temporary signature for object get with non-unreserved URI characters" do
|
156
|
+
actual = S3::Signature.generate_temporary_url_signature(
|
157
|
+
:bucket => "johnsmith",
|
158
|
+
:resource => "photos/puppy[1].jpg",
|
159
|
+
:secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o",
|
160
|
+
:expires_at => 1175046589
|
161
|
+
)
|
162
|
+
expected = "gwCM0mVb9IrEPiUf8iaml6EISPc%3D"
|
163
|
+
assert_equal expected, actual
|
164
|
+
end
|
154
165
|
|
155
166
|
test "temporary signature for object post" do
|
156
167
|
actual = S3::Signature.generate_temporary_url_signature(
|
@@ -189,6 +200,18 @@ class SignatureTest < Test::Unit::TestCase
|
|
189
200
|
assert_equal expected, actual
|
190
201
|
end
|
191
202
|
|
203
|
+
test "temporary url for object get with bucket in the hostname" do
|
204
|
+
actual = S3::Signature.generate_temporary_url(
|
205
|
+
:bucket => "johnsmith",
|
206
|
+
:resource => "photos/puppy.jpg",
|
207
|
+
:secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o",
|
208
|
+
:expires_at => 1175046589,
|
209
|
+
:add_bucket_to_host => true
|
210
|
+
)
|
211
|
+
expected = "http://johnsmith.s3.amazonaws.com/photos/puppy.jpg?AWSAccessKeyId=&Expires=1175046589&Signature=gs6xNznrLJ4Bd%2B1y9pcy2HOSVeg%3D"
|
212
|
+
assert_equal expected, actual
|
213
|
+
end
|
214
|
+
|
192
215
|
test "temporary url for object put with headers" do
|
193
216
|
actual = S3::Signature.generate_temporary_url(
|
194
217
|
:bucket => "johnsmith",
|
metadata
CHANGED
@@ -1,64 +1,75 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: s3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.12
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
|
-
-
|
7
|
+
- Kuba Kuźma
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-06-05 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: proxies
|
16
|
-
requirement:
|
17
|
-
none: false
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 0.2.0
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
|
-
version_requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.2.0
|
25
27
|
- !ruby/object:Gem::Dependency
|
26
28
|
name: test-unit
|
27
|
-
requirement:
|
28
|
-
none: false
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
29
30
|
requirements:
|
30
|
-
- -
|
31
|
+
- - '>='
|
31
32
|
- !ruby/object:Gem::Version
|
32
33
|
version: '2.0'
|
33
34
|
type: :development
|
34
35
|
prerelease: false
|
35
|
-
version_requirements:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
36
41
|
- !ruby/object:Gem::Dependency
|
37
42
|
name: mocha
|
38
|
-
requirement:
|
39
|
-
none: false
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
40
44
|
requirements:
|
41
|
-
- -
|
45
|
+
- - '>='
|
42
46
|
- !ruby/object:Gem::Version
|
43
47
|
version: '0'
|
44
48
|
type: :development
|
45
49
|
prerelease: false
|
46
|
-
version_requirements:
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
47
55
|
- !ruby/object:Gem::Dependency
|
48
56
|
name: bundler
|
49
|
-
requirement:
|
50
|
-
none: false
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
51
58
|
requirements:
|
52
|
-
- -
|
59
|
+
- - '>='
|
53
60
|
- !ruby/object:Gem::Version
|
54
61
|
version: 1.0.0
|
55
62
|
type: :development
|
56
63
|
prerelease: false
|
57
|
-
version_requirements:
|
58
|
-
|
59
|
-
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.0.0
|
69
|
+
description: 'S3 library provides access to Amazon''s Simple Storage Service. It supports
|
70
|
+
both: European and US buckets through REST API.'
|
60
71
|
email:
|
61
|
-
-
|
72
|
+
- kuba@jah.pl
|
62
73
|
executables: []
|
63
74
|
extensions: []
|
64
75
|
extra_rdoc_files: []
|
@@ -88,31 +99,27 @@ files:
|
|
88
99
|
- test/service_test.rb
|
89
100
|
- test/signature_test.rb
|
90
101
|
- test/test_helper.rb
|
91
|
-
homepage: http://
|
102
|
+
homepage: http://github.com/qoobaa/s3
|
92
103
|
licenses: []
|
104
|
+
metadata: {}
|
93
105
|
post_install_message:
|
94
106
|
rdoc_options: []
|
95
107
|
require_paths:
|
96
108
|
- lib
|
97
109
|
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
-
none: false
|
99
110
|
requirements:
|
100
|
-
- -
|
111
|
+
- - '>='
|
101
112
|
- !ruby/object:Gem::Version
|
102
113
|
version: '0'
|
103
|
-
segments:
|
104
|
-
- 0
|
105
|
-
hash: -3173124590106976282
|
106
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
-
none: false
|
108
115
|
requirements:
|
109
|
-
- -
|
116
|
+
- - '>='
|
110
117
|
- !ruby/object:Gem::Version
|
111
118
|
version: 1.3.6
|
112
119
|
requirements: []
|
113
120
|
rubyforge_project: s3
|
114
|
-
rubygems_version:
|
121
|
+
rubygems_version: 2.0.2
|
115
122
|
signing_key:
|
116
|
-
specification_version:
|
123
|
+
specification_version: 4
|
117
124
|
summary: Library for accessing S3 objects and buckets
|
118
125
|
test_files: []
|