s3 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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