s3 0.2.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.
@@ -0,0 +1,164 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ class ObjectTest < Test::Unit::TestCase
5
+ def setup
6
+ @service = Stree::Service.new(
7
+ :access_key_id => "1234",
8
+ :secret_access_key => "1337"
9
+ )
10
+ @bucket_images = Stree::Bucket.new(@service, "images")
11
+ @object_lena = Stree::Object.new(@bucket_images, "Lena.png")
12
+ @object_lena.content = "test"
13
+ @object_carmen = Stree::Object.new(@bucket_images, "Carmen.png")
14
+
15
+ @response_binary = Net::HTTPOK.new("1.1", "200", "OK")
16
+ stub(@response_binary).body { "test".force_encoding(Encoding::BINARY) }
17
+ @response_binary["etag"] = ""
18
+ @response_binary["content-type"] = "image/png"
19
+ @response_binary["content-disposition"] = "inline"
20
+ @response_binary["content-encoding"] = nil
21
+ @response_binary["last-modified"] = Time.now.httpdate
22
+ @response_binary["content-length"] = 20
23
+
24
+ @xml_body = <<-EOXML
25
+ <?xml version="1.0" encoding="UTF-8"?>
26
+ <CopyObjectResult> <LastModified>timestamp</LastModified> <ETag>"etag"</ETag> </CopyObjectResult>
27
+ EOXML
28
+ @response_xml = Net::HTTPOK.new("1.1", "200", "OK")
29
+ stub(@response_xml).body { @xml_body }
30
+ end
31
+
32
+ def test_initilalize
33
+ assert_raise ArgumentError do Stree::Object.new(nil, "") end # should not allow empty key
34
+ assert_raise ArgumentError do Stree::Object.new(nil, "//") end # should not allow key with double slash
35
+
36
+ assert_nothing_raised do
37
+ Stree::Object.new(nil, "Lena.png")
38
+ Stree::Object.new(nil, "Lena playboy.png")
39
+ Stree::Object.new(nil, "Lena Söderberg.png")
40
+ Stree::Object.new(nil, "/images/pictures/test images/Lena not full.png")
41
+ end
42
+ end
43
+
44
+ def test_full_key
45
+ expected = "images/Lena.png"
46
+ actual = @object_lena.full_key
47
+ assert_equal expected, actual
48
+ end
49
+
50
+ def test_url
51
+ bucket1 = Stree::Bucket.new(@service, "images")
52
+
53
+ object11 = Stree::Object.new(bucket1, "Lena.png")
54
+ expected = "http://images.s3.amazonaws.com/Lena.png"
55
+ actual = object11.url
56
+ assert_equal expected, actual
57
+
58
+ object12 = Stree::Object.new(bucket1, "Lena Söderberg.png")
59
+ expected = "http://images.s3.amazonaws.com/Lena%20S%C3%B6derberg.png"
60
+ actual = object12.url
61
+ assert_equal expected, actual
62
+
63
+ bucket2 = Stree::Bucket.new(@service, "images_new")
64
+
65
+ object21 = Stree::Object.new(bucket2, "Lena.png")
66
+ expected = "http://s3.amazonaws.com/images_new/Lena.png"
67
+ actual = object21.url
68
+ assert_equal expected, actual
69
+ end
70
+
71
+ def test_cname_url
72
+ bucket1 = Stree::Bucket.new(@service, "images.example.com")
73
+
74
+ object11 = Stree::Object.new(bucket1, "Lena.png")
75
+ expected = "http://images.example.com/Lena.png"
76
+ actual = object11.cname_url
77
+ assert_equal expected, actual
78
+
79
+ object12 = Stree::Object.new(bucket1, "Lena Söderberg.png")
80
+ expected = "http://images.example.com/Lena%20S%C3%B6derberg.png"
81
+ actual = object12.cname_url
82
+ assert_equal expected, actual
83
+
84
+ bucket2 = Stree::Bucket.new(@service, "images_new")
85
+
86
+ object21 = Stree::Object.new(bucket2, "Lena.png")
87
+ expected = nil
88
+ actual = object21.cname_url
89
+ assert_equal expected, actual
90
+ end
91
+
92
+ def test_destroy
93
+ mock(@object_lena).object_request(:delete) {}
94
+ assert @object_lena.destroy
95
+ end
96
+
97
+ def test_save
98
+ mock(@object_lena).object_request(
99
+ :put, :body=>"test",
100
+ :headers=>{ :x_amz_acl=>"public-read", :content_type=>"application/octet-stream" }
101
+ ) { @response_binary }
102
+
103
+ assert @object_lena.save
104
+ end
105
+
106
+ def test_content_and_parse_headers
107
+ mock(@object_lena).object_request(:get) { @response_binary }
108
+
109
+ expected = /test/n
110
+ actual = @object_lena.content(true) # wtf? don't work with false, maybe is not fully cleaned
111
+ assert_match expected, actual
112
+ assert_equal "image/png", @object_lena.content_type
113
+
114
+ stub(@object_lena).object_request(:get) { flunk "should not use connection" }
115
+
116
+ assert @object_lena.content
117
+
118
+ mock(@object_lena).object_request(:get) { @response_binary }
119
+ assert @object_lena.content(true)
120
+ end
121
+
122
+ def test_retrieve
123
+ mock(@object_lena).object_request(:get, :headers=>{:range=>0..0}) { @response_binary }
124
+ assert @object_lena.retrieve
125
+ end
126
+
127
+ def test_exists
128
+ mock(@object_lena).retrieve { true }
129
+ assert @object_lena.exists?
130
+
131
+ mock(@object_carmen).retrieve { raise Stree::Error::NoSuchKey.new(nil, nil) }
132
+ assert ! @object_carmen.exists?
133
+ end
134
+
135
+ def test_acl_writer
136
+ expected = nil
137
+ actual = @object_lena.acl
138
+ assert_equal expected, actual
139
+
140
+ assert @object_lena.acl = :public_read
141
+
142
+ expected = "public-read"
143
+ actual = @object_lena.acl
144
+ assert_equal expected, actual
145
+
146
+ assert @object_lena.acl = :private
147
+
148
+ expected = "private"
149
+ actual = @object_lena.acl
150
+ assert_equal expected, actual
151
+ end
152
+
153
+ def test_copy
154
+ mock(@bucket_images).bucket_request(
155
+ :put, :path=>"Lena.png",
156
+ :headers=>{:x_amz_acl=>"public-read", :content_type=>"application/octet-stream", :x_amz_copy_source=>"images/Lena.png", :x_amz_metadata_directive=>"REPLACE"}
157
+ ) { @response_xml }
158
+
159
+ new_object = @object_lena.copy
160
+
161
+ assert_equal @object_lena, new_object
162
+ assert ! @object_lena.eql?(new_object)
163
+ end
164
+ end
@@ -0,0 +1,128 @@
1
+ require 'test_helper'
2
+
3
+ class ServiceTest < Test::Unit::TestCase
4
+ def setup
5
+ @service_empty_buckets_list = Stree::Service.new(
6
+ :access_key_id => "12345678901234567890",
7
+ :secret_access_key => "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDF"
8
+ )
9
+ @response_empty_buckets_list = Net::HTTPOK.new("1.1", "200", "OK")
10
+ stub(@service_empty_buckets_list).service_request { @response_empty_buckets_list }
11
+ stub(@response_empty_buckets_list).body { @buckets_empty_list_body }
12
+
13
+ @service_buckets_list = Stree::Service.new(
14
+ :access_key_id => "12345678901234567890",
15
+ :secret_access_key => "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDF"
16
+ )
17
+ @response_buckets_list = Net::HTTPOK.new("1.1", "200", "OK")
18
+ stub(@service_buckets_list).service_request { @response_buckets_list }
19
+ stub(@response_buckets_list).body { @buckets_list_body }
20
+
21
+ @service_bucket_exists = Stree::Service.new(
22
+ :access_key_id => "12345678901234567890",
23
+ :secret_access_key => "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDF"
24
+ )
25
+ @response_bucket_exists = Net::HTTPNotFound.new("1.1", "200", "OK")
26
+ stub(@service_bucket_exists).service_request { @response_bucket_exists }
27
+ stub(@response_bucket_exists).body { @bucket_exists }
28
+
29
+ @service_bucket_not_exists = Stree::Service.new(
30
+ :access_key_id => "12345678901234567890",
31
+ :secret_access_key => "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDF"
32
+ )
33
+ @response_bucket_not_exists = Net::HTTPNotFound.new("1.1", "404", "Not Found")
34
+ stub(@service_bucket_not_exists).service_request { raise Stree::Error::NoSuchBucket.new(404, @response_bucket_not_exists) }
35
+ stub(@response_bucket_not_exists).body { @bucket_not_exists }
36
+
37
+ @buckets_empty_list = []
38
+ @buckets_empty_list_body = <<-EOEmptyBuckets
39
+ <?xml version="1.0" encoding="UTF-8"?>\n<ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <Owner> <ID>123u1odhkhfoadf</ID> <DisplayName>JohnDoe</DisplayName> </Owner> <Buckets> </Buckets> </ListAllMyBucketsResult>
40
+ EOEmptyBuckets
41
+
42
+ @buckets_list = [
43
+ Stree::Bucket.new(@service_buckets_list, "data.example.com"),
44
+ Stree::Bucket.new(@service_buckets_list, "images")
45
+ ]
46
+ @buckets_list_body = <<-EOBuckets
47
+ <?xml version="1.0" encoding="UTF-8"?>\n<ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <Owner> <ID>123u1odhkhfoadf</ID> <DisplayName>JohnDoe</DisplayName> </Owner> <Buckets> <Bucket> <Name>data.example.com</Name> <CreationDate>2009-07-02T11:56:58.000Z</CreationDate> </Bucket> <Bucket> <Name>images</Name> <CreationDate>2009-06-05T12:26:33.000Z</CreationDate> </Bucket> </Buckets> </ListAllMyBucketsResult>
48
+ EOBuckets
49
+
50
+ @bucket_not_exists = <<-EOBucketNoexists
51
+ <?xml version="1.0" encoding="UTF-8"?>\n<Error> <Code>NoSuchBucket</Code> <Message>The specified bucket does not exists</Message> <BucketName>data2.example.com</BucketName> <RequestId>8D7519AAE74E9E99</RequestId> <HostId>DvKnnNSMnPHd1oXukyRaFNv8Lg/bpwhuUtY8Kj7eDLbaIrIT8JebSnHwi89AK1P+</HostId> </Error>
52
+ EOBucketNoexists
53
+
54
+ @bucket_exists = <<-EOBucketexists
55
+ <?xml version="1.0" encoding="UTF-8"?>\n<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <Name>data.synergypeople.net</Name> <Prefix></Prefix> <Marker></Marker> <MaxKeys>1000</MaxKeys> <IsTruncated>false</IsTruncated> </ListBucketResult>
56
+ EOBucketexists
57
+ end
58
+
59
+ def test_buckets_and_parse_buckets_empty
60
+ expected = @buckets_empty_list
61
+ actual = @service_empty_buckets_list.buckets
62
+ assert_equal expected.length, actual.length
63
+ assert_equal expected, actual
64
+ end
65
+
66
+ def test_buckets_and_parse_buckets
67
+ expected = @buckets_list
68
+ # ugly hack
69
+ actual = @service_buckets_list.buckets(true).map { |obj| obj }
70
+ assert_equal expected, actual
71
+ end
72
+
73
+ def test_buckets_reload
74
+ @service = @service_empty_buckets_list
75
+
76
+ expected = @buckets_empty_list
77
+ assert @service.buckets, "retrive buckets"
78
+ actual = @service.buckets
79
+ assert_equal expected.length, actual.length, "deliver from cache"
80
+
81
+ stub(@service).service_request { @response_buckets_list }
82
+ expected = @buckets_empty_list
83
+ actual = @service.buckets
84
+ assert_equal expected.length, actual.length, "deliver from cache"
85
+
86
+ expected = @buckets_list
87
+ actual = @service.buckets(true)
88
+ assert_equal expected.length, actual.length
89
+ end
90
+
91
+ def test_buckets_build
92
+ stub(@service_empty_buckets_list).service_request { flunk "should not connect to server" }
93
+
94
+ expected = "bucket_name"
95
+ actual = @service_empty_buckets_list.buckets.build("bucket_name")
96
+ assert_kind_of Stree::Bucket, actual
97
+ assert_equal expected, actual.name
98
+ end
99
+
100
+ def test_buckets_find_first
101
+ assert_nothing_raised do
102
+ actual = @service_buckets_list.buckets.find_first("data.example.com")
103
+ assert_equal "data.example.com", actual.name
104
+ end
105
+ end
106
+
107
+ def test_buckets_find_first_fail
108
+ assert_raise Stree::Error::NoSuchBucket do
109
+ @service_bucket_not_exists.buckets.find_first("data2.example.com")
110
+ end
111
+ end
112
+
113
+ def test_buckets_find_all_on_empty_list
114
+ assert_nothing_raised do
115
+ expected = @buckets_empty_list
116
+ actual = @service_empty_buckets_list.buckets.find_all
117
+ assert_equal expected, actual
118
+ end
119
+ end
120
+
121
+ def test_buckets_find_all
122
+ assert_nothing_raised do
123
+ expected = @buckets_list
124
+ actual = @service_buckets_list.buckets.find_all
125
+ assert_equal expected, actual
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,143 @@
1
+ require 'test_helper'
2
+
3
+ class SignatureTest < Test::Unit::TestCase
4
+ # from http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html
5
+ def test_signature_for_object_get
6
+ request = Net::HTTP::Get.new("/photos/puppy.jpg")
7
+ request["host"] = "johnsmith.s3.amazonaws.com"
8
+ request["date"] = "Tue, 27 Mar 2007 19:36:42 +0000"
9
+
10
+ actual = Stree::Signature.generate(
11
+ :host => request["host"],
12
+ :request => request,
13
+ :access_key_id => "0PN5J17HBGZHT7JJ3X82",
14
+ :secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"
15
+ )
16
+ expected = "AWS 0PN5J17HBGZHT7JJ3X82:xXjDGYUmKxnwqr5KXNPGldn5LbA="
17
+ assert_equal expected, actual
18
+ end
19
+
20
+ def test_signature_for_object_put
21
+ request = Net::HTTP::Put.new("/photos/puppy.jpg");
22
+ request["content-type"] = "image/jpeg"
23
+ request["content-length"] = "94328"
24
+ request["host"] = "johnsmith.s3.amazonaws.com"
25
+ request["date"] = "Tue, 27 Mar 2007 21:15:45 +0000"
26
+
27
+ actual = Stree::Signature.generate(
28
+ :host => request["host"],
29
+ :request => request,
30
+ :access_key_id => "0PN5J17HBGZHT7JJ3X82",
31
+ :secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"
32
+ )
33
+ expected = "AWS 0PN5J17HBGZHT7JJ3X82:hcicpDDvL9SsO6AkvxqmIWkmOuQ="
34
+ assert_equal expected, actual
35
+ end
36
+
37
+ def test_signature_for_list
38
+ request = Net::HTTP::Get.new("/?prefix=photos&max-keys=50&marker=puppy");
39
+ request["user-agent"] = "Mozilla/5.0"
40
+ request["host"] = "johnsmith.s3.amazonaws.com"
41
+ request["date"] = "Tue, 27 Mar 2007 19:42:41 +0000"
42
+
43
+ actual = Stree::Signature.generate(
44
+ :host => request["host"],
45
+ :request => request,
46
+ :access_key_id => "0PN5J17HBGZHT7JJ3X82",
47
+ :secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"
48
+ )
49
+ expected = "AWS 0PN5J17HBGZHT7JJ3X82:jsRt/rhG+Vtp88HrYL706QhE4w4="
50
+ assert_equal expected, actual
51
+ end
52
+
53
+ def test_signature_for_fetch
54
+ request = Net::HTTP::Get.new("/?acl");
55
+ request["host"] = "johnsmith.s3.amazonaws.com"
56
+ request["date"] = "Tue, 27 Mar 2007 19:44:46 +0000"
57
+
58
+ actual = Stree::Signature.generate(
59
+ :host => request["host"],
60
+ :request => request,
61
+ :access_key_id => "0PN5J17HBGZHT7JJ3X82",
62
+ :secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"
63
+ )
64
+ expected = "AWS 0PN5J17HBGZHT7JJ3X82:thdUi9VAkzhkniLj96JIrOPGi0g="
65
+ assert_equal expected, actual
66
+ end
67
+
68
+ def test_signature_for_delete
69
+ request = Net::HTTP::Delete.new("/johnsmith/photos/puppy.jpg");
70
+ request["user-agent"] = "dotnet"
71
+ request["host"] = "s3.amazonaws.com"
72
+ request["date"] = "Tue, 27 Mar 2007 21:20:27 +0000"
73
+ request["x-amz-date"] = "Tue, 27 Mar 2007 21:20:26 +0000"
74
+
75
+ actual = Stree::Signature.generate(
76
+ :host => request["host"],
77
+ :request => request,
78
+ :access_key_id => "0PN5J17HBGZHT7JJ3X82",
79
+ :secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"
80
+ )
81
+ expected = "AWS 0PN5J17HBGZHT7JJ3X82:k3nL7gH3+PadhTEVn5Ip83xlYzk="
82
+ assert_equal expected, actual
83
+ end
84
+
85
+ def test_signature_for_upload
86
+ request = Net::HTTP::Put.new("/db-backup.dat.gz");
87
+ request["user-agent"] = "curl/7.15.5"
88
+ request["host"] = "static.johnsmith.net:8080"
89
+ request["date"] = "Tue, 27 Mar 2007 21:06:08 +0000"
90
+ request["x-amz-acl"] = "public-read"
91
+ request["content-type"] = "application/x-download"
92
+ request["content-MD5"] = "4gJE4saaMU4BqNR0kLY+lw=="
93
+ # TODO:
94
+ # was:
95
+ #request["x-amz-meta-reviewedby"] = "joe@johnsmith.net"
96
+ #request["x-amz-meta-reviewedby"] = "jane@johnsmith.net"
97
+ request["x-amz-meta-reviewedby"] = "joe@johnsmith.net,jane@johnsmith.net"
98
+ request["x-amz-meta-filechecksum"] = "0x02661779"
99
+ request["x-amz-meta-checksumalgorithm"] = "crc32"
100
+ request["content-disposition"] = "attachment; filename=database.dat"
101
+ request["content-encoding"] = "gzip"
102
+ request["content-length"] = "5913339"
103
+
104
+ actual = Stree::Signature.generate(
105
+ :host => "static.johnsmith.net",
106
+ :request => request,
107
+ :access_key_id => "0PN5J17HBGZHT7JJ3X82",
108
+ :secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"
109
+ )
110
+ expected = "AWS 0PN5J17HBGZHT7JJ3X82:C0FlOtU8Ylb9KDTpZqYkZPX91iI="
111
+ assert_equal expected, actual
112
+ end
113
+
114
+ def test_signature_for_list_all_my_buckets
115
+ request = Net::HTTP::Get.new("/");
116
+ request["host"] = "s3.amazonaws.com"
117
+ request["date"] = "Wed, 28 Mar 2007 01:29:59 +0000"
118
+
119
+ actual = Stree::Signature.generate(
120
+ :host => request["host"],
121
+ :request => request,
122
+ :access_key_id => "0PN5J17HBGZHT7JJ3X82",
123
+ :secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"
124
+ )
125
+ expected = "AWS 0PN5J17HBGZHT7JJ3X82:Db+gepJSUbZKwpx1FR0DLtEYoZA="
126
+ assert_equal expected, actual
127
+ end
128
+
129
+ def test_signature_for_unicode_keys
130
+ request = Net::HTTP::Get.new("/dictionary/fran%C3%A7ais/pr%c3%a9f%c3%a8re");
131
+ request["host"] = "s3.amazonaws.com"
132
+ request["date"] = "Wed, 28 Mar 2007 01:49:49 +0000"
133
+
134
+ actual = Stree::Signature.generate(
135
+ :host => request["host"],
136
+ :request => request,
137
+ :access_key_id => "0PN5J17HBGZHT7JJ3X82",
138
+ :secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"
139
+ )
140
+ expected = "AWS 0PN5J17HBGZHT7JJ3X82:dxhSBHoI6eVSPcXJqEghlUzZMnY="
141
+ assert_equal expected, actual
142
+ end
143
+ end
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'rr'
4
+
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ require 'stree'
8
+
9
+ class Test::Unit::TestCase
10
+ include RR::Adapters::TestUnit
11
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: s3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - "Jakub Ku\xC5\xBAma"
8
+ - "Miros\xC5\x82aw Boruta"
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-10-09 00:00:00 +02:00
14
+ default_executable: stree
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: trollop
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "1.14"
25
+ version:
26
+ description:
27
+ email: qoobaa@gmail.com
28
+ executables:
29
+ - stree
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - LICENSE
34
+ - README.rdoc
35
+ files:
36
+ - .document
37
+ - .gitignore
38
+ - LICENSE
39
+ - README.rdoc
40
+ - Rakefile
41
+ - VERSION
42
+ - bin/stree
43
+ - extra/stree_backend.rb
44
+ - lib/stree.rb
45
+ - lib/stree/bucket.rb
46
+ - lib/stree/connection.rb
47
+ - lib/stree/exceptions.rb
48
+ - lib/stree/object.rb
49
+ - lib/stree/parser.rb
50
+ - lib/stree/roxy/moxie.rb
51
+ - lib/stree/roxy/proxy.rb
52
+ - lib/stree/service.rb
53
+ - lib/stree/signature.rb
54
+ - test/bucket_test.rb
55
+ - test/connection_test.rb
56
+ - test/object_test.rb
57
+ - test/service_test.rb
58
+ - test/signature_test.rb
59
+ - test/test_helper.rb
60
+ has_rdoc: true
61
+ homepage: http://github.com/qoobaa/stree
62
+ licenses: []
63
+
64
+ post_install_message:
65
+ rdoc_options:
66
+ - --charset=UTF-8
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ requirements: []
82
+
83
+ rubyforge_project:
84
+ rubygems_version: 1.3.5
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: Library for accessing S3 objects and buckets, with command line tool
88
+ test_files:
89
+ - test/bucket_test.rb
90
+ - test/service_test.rb
91
+ - test/signature_test.rb
92
+ - test/connection_test.rb
93
+ - test/test_helper.rb
94
+ - test/object_test.rb