s3 0.3.2 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +2 -5
- data/lib/s3/bucket.rb +1 -1
- data/lib/s3/service.rb +2 -2
- data/lib/s3/signature.rb +78 -34
- data/lib/s3/version.rb +1 -1
- data/s3.gemspec +1 -2
- data/test/signature_test.rb +62 -0
- metadata +13 -27
- data/bin/s3 +0 -187
data/Gemfile.lock
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
s3 (0.3.
|
4
|
+
s3 (0.3.3)
|
5
5
|
proxies
|
6
|
-
trollop
|
7
6
|
|
8
7
|
GEM
|
9
8
|
remote: http://rubygems.org/
|
10
9
|
specs:
|
11
10
|
mocha (0.9.8)
|
12
11
|
rake
|
13
|
-
proxies (0.
|
12
|
+
proxies (0.2.1)
|
14
13
|
rake (0.8.7)
|
15
14
|
test-unit (2.1.1)
|
16
|
-
trollop (1.16.2)
|
17
15
|
|
18
16
|
PLATFORMS
|
19
17
|
ruby
|
@@ -24,4 +22,3 @@ DEPENDENCIES
|
|
24
22
|
proxies
|
25
23
|
s3!
|
26
24
|
test-unit (>= 2.0)
|
27
|
-
trollop
|
data/lib/s3/bucket.rb
CHANGED
@@ -85,7 +85,7 @@ module S3
|
|
85
85
|
# Returns the objects in the bucket and caches the result (see
|
86
86
|
# #reload method).
|
87
87
|
def objects
|
88
|
-
|
88
|
+
Proxy.new(lambda { list_bucket }, :owner => self, :extend => ObjectsExtension)
|
89
89
|
end
|
90
90
|
|
91
91
|
def inspect #:nodoc:
|
data/lib/s3/service.rb
CHANGED
@@ -28,7 +28,7 @@ module S3
|
|
28
28
|
@use_ssl = options.fetch(:use_ssl, false)
|
29
29
|
@timeout = options.fetch(:timeout, 60)
|
30
30
|
@debug = options.fetch(:debug, false)
|
31
|
-
|
31
|
+
|
32
32
|
raise ArgumentError, "Missing proxy settings. Must specify at least :host." if options[:proxy] && !options[:proxy][:host]
|
33
33
|
@proxy = options.fetch(:proxy, nil)
|
34
34
|
end
|
@@ -36,7 +36,7 @@ module S3
|
|
36
36
|
# Returns all buckets in the service and caches the result (see
|
37
37
|
# +reload+)
|
38
38
|
def buckets
|
39
|
-
|
39
|
+
Proxy.new(lambda { list_all_my_buckets}, :owner => self, :extend => BucketsExtension)
|
40
40
|
end
|
41
41
|
|
42
42
|
# Returns "http://" or "https://", depends on <tt>:use_ssl</tt>
|
data/lib/s3/signature.rb
CHANGED
@@ -23,64 +23,108 @@ module S3
|
|
23
23
|
# Generated signature string for given hostname and request
|
24
24
|
def self.generate(options)
|
25
25
|
request = options[:request]
|
26
|
-
host = options[:host]
|
27
26
|
access_key_id = options[:access_key_id]
|
28
|
-
secret_access_key = options[:secret_access_key]
|
29
|
-
|
30
|
-
http_verb = request.method
|
31
|
-
content_md5 = request["content-md5"] || ""
|
32
|
-
content_type = request["content-type"] || ""
|
33
|
-
date = request["x-amz-date"].nil? ? request["date"] : ""
|
34
|
-
canonicalized_resource = canonicalized_resource(host, request)
|
35
|
-
canonicalized_amz_headers = canonicalized_amz_headers(request)
|
36
27
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
string_to_sign << content_md5
|
41
|
-
string_to_sign << "\n"
|
42
|
-
string_to_sign << content_type
|
43
|
-
string_to_sign << "\n"
|
44
|
-
string_to_sign << date
|
45
|
-
string_to_sign << "\n"
|
46
|
-
string_to_sign << canonicalized_amz_headers
|
47
|
-
string_to_sign << canonicalized_resource
|
28
|
+
options.merge!(:headers => request,
|
29
|
+
:method => request.method,
|
30
|
+
:resource => request.path)
|
48
31
|
|
49
|
-
|
50
|
-
hmac = OpenSSL::HMAC.digest(digest, secret_access_key, string_to_sign)
|
51
|
-
base64 = Base64.encode64(hmac)
|
52
|
-
signature = base64.chomp
|
32
|
+
signature = canonicalized_signature(options)
|
53
33
|
|
54
34
|
"AWS #{access_key_id}:#{signature}"
|
55
35
|
end
|
56
36
|
|
57
|
-
# Generates temporary URL for given resource
|
37
|
+
# Generates temporary URL signature for given resource
|
58
38
|
#
|
59
39
|
# ==== Options
|
60
40
|
# * <tt>:bucket</tt> - Bucket in which the resource resides
|
61
41
|
# * <tt>:resource</tt> - Path to the resouce you want to create
|
62
|
-
# a
|
42
|
+
# a temporary link to
|
63
43
|
# * <tt>:secret_access_key</tt> - Secret access key
|
64
|
-
# * <tt>:
|
44
|
+
# * <tt>:expires_at</tt> - Unix time stamp of when the resouce
|
65
45
|
# link will expire
|
46
|
+
# * <tt>:method</tt> - HTTP request method you want to use on
|
47
|
+
# the resource, defaults to GET
|
48
|
+
# * <tt>:headers</tt> - Any additional HTTP headers you intend
|
49
|
+
# to use when requesting the resource
|
66
50
|
def self.generate_temporary_url_signature(options)
|
67
51
|
bucket = options[:bucket]
|
68
52
|
resource = options[:resource]
|
69
53
|
secret_access_key = options[:secret_access_key]
|
70
54
|
expires = options[:expires_at]
|
71
55
|
|
72
|
-
|
56
|
+
headers = options[:headers] || {}
|
57
|
+
headers.merge!('date' => expires.to_i.to_s)
|
73
58
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
signature =
|
59
|
+
options.merge!(:resource => "/#{bucket}/#{resource}",
|
60
|
+
:method => options[:method] || :get,
|
61
|
+
:headers => headers)
|
62
|
+
signature = canonicalized_signature(options)
|
78
63
|
|
79
64
|
CGI.escape(signature)
|
80
65
|
end
|
81
66
|
|
67
|
+
# Generates temporary URL for given resource
|
68
|
+
#
|
69
|
+
# ==== Options
|
70
|
+
# * <tt>:bucket</tt> - Bucket in which the resource resides
|
71
|
+
# * <tt>:resource</tt> - Path to the resouce you want to create
|
72
|
+
# a temporary link to
|
73
|
+
# * <tt>:access_key</tt> - Access key
|
74
|
+
# * <tt>:secret_access_key</tt> - Secret access key
|
75
|
+
# * <tt>:expires_at</tt> - Unix time stamp of when the resouce
|
76
|
+
# link will expire
|
77
|
+
# * <tt>:method</tt> - HTTP request method you want to use on
|
78
|
+
# the resource, defaults to GET
|
79
|
+
# * <tt>:headers</tt> - Any additional HTTP headers you intend
|
80
|
+
# to use when requesting the resource
|
81
|
+
def self.generate_temporary_url(options)
|
82
|
+
bucket = options[:bucket]
|
83
|
+
resource = options[:resource]
|
84
|
+
access_key = options[:access_key]
|
85
|
+
expires = options[:expires_at].to_i
|
86
|
+
signature = generate_temporary_url_signature(options)
|
87
|
+
|
88
|
+
url = "http://#{S3::HOST}/#{bucket}/#{resource}"
|
89
|
+
url << "?AWSAccessKeyId=#{access_key}"
|
90
|
+
url << "&Expires=#{expires}"
|
91
|
+
url << "&Signature=#{signature}"
|
92
|
+
end
|
93
|
+
|
82
94
|
private
|
83
95
|
|
96
|
+
def self.canonicalized_signature(options)
|
97
|
+
headers = options[:headers] || {}
|
98
|
+
host = options[:host] || ""
|
99
|
+
resource = options[:resource]
|
100
|
+
access_key_id = options[:access_key_id]
|
101
|
+
secret_access_key = options[:secret_access_key]
|
102
|
+
|
103
|
+
http_verb = options[:method].to_s.upcase
|
104
|
+
content_md5 = headers["content-md5"] || ""
|
105
|
+
content_type = headers["content-type"] || ""
|
106
|
+
date = headers["x-amz-date"].nil? ? headers["date"] : ""
|
107
|
+
canonicalized_resource = canonicalized_resource(host, resource)
|
108
|
+
canonicalized_amz_headers = canonicalized_amz_headers(headers)
|
109
|
+
|
110
|
+
string_to_sign = ""
|
111
|
+
string_to_sign << http_verb
|
112
|
+
string_to_sign << "\n"
|
113
|
+
string_to_sign << content_md5
|
114
|
+
string_to_sign << "\n"
|
115
|
+
string_to_sign << content_type
|
116
|
+
string_to_sign << "\n"
|
117
|
+
string_to_sign << date
|
118
|
+
string_to_sign << "\n"
|
119
|
+
string_to_sign << canonicalized_amz_headers
|
120
|
+
string_to_sign << canonicalized_resource
|
121
|
+
|
122
|
+
digest = OpenSSL::Digest::Digest.new('sha1')
|
123
|
+
hmac = OpenSSL::HMAC.digest(digest, secret_access_key, string_to_sign)
|
124
|
+
base64 = Base64.encode64(hmac)
|
125
|
+
base64.chomp
|
126
|
+
end
|
127
|
+
|
84
128
|
# Helper method for extracting header fields from Net::HTTPRequest
|
85
129
|
# and preparing them for singing in #generate method
|
86
130
|
#
|
@@ -157,7 +201,7 @@ module S3
|
|
157
201
|
#
|
158
202
|
# ==== Returns
|
159
203
|
# String containing extracted canonicalized resource
|
160
|
-
def self.canonicalized_resource(host,
|
204
|
+
def self.canonicalized_resource(host, resource)
|
161
205
|
# 1. Start with the empty string ("").
|
162
206
|
string = ""
|
163
207
|
|
@@ -172,7 +216,7 @@ module S3
|
|
172
216
|
|
173
217
|
# 3. Append the path part of the un-decoded HTTP Request-URI,
|
174
218
|
# up-to but not including the query string.
|
175
|
-
uri = URI.parse(
|
219
|
+
uri = URI.parse(resource)
|
176
220
|
string << uri.path
|
177
221
|
|
178
222
|
# 4. If the request addresses a sub-resource, like ?location,
|
data/lib/s3/version.rb
CHANGED
data/s3.gemspec
CHANGED
@@ -9,13 +9,12 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ["Jakub Kuźma"]
|
10
10
|
s.email = ["qoobaa@gmail.com"]
|
11
11
|
s.homepage = "http://jah.pl/projects/s3.html"
|
12
|
-
s.summary = "Library for accessing S3 objects and buckets
|
12
|
+
s.summary = "Library for accessing S3 objects and buckets"
|
13
13
|
s.description = "S3 library provides access to Amazon's Simple Storage Service. It supports both: European and US buckets through REST API."
|
14
14
|
|
15
15
|
s.required_rubygems_version = ">= 1.3.6"
|
16
16
|
s.rubyforge_project = "s3"
|
17
17
|
|
18
|
-
s.add_dependency "trollop"
|
19
18
|
s.add_dependency "proxies"
|
20
19
|
s.add_development_dependency "test-unit", ">= 2.0"
|
21
20
|
s.add_development_dependency "mocha"
|
data/test/signature_test.rb
CHANGED
@@ -140,4 +140,66 @@ class SignatureTest < Test::Unit::TestCase
|
|
140
140
|
expected = "AWS 0PN5J17HBGZHT7JJ3X82:dxhSBHoI6eVSPcXJqEghlUzZMnY="
|
141
141
|
assert_equal expected, actual
|
142
142
|
end
|
143
|
+
|
144
|
+
test "temporary signature for object get" do
|
145
|
+
actual = S3::Signature.generate_temporary_url_signature(
|
146
|
+
:bucket => "johnsmith",
|
147
|
+
:resource => "photos/puppy.jpg",
|
148
|
+
:secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o",
|
149
|
+
:expires_at => 1175046589
|
150
|
+
)
|
151
|
+
expected = "gs6xNznrLJ4Bd%2B1y9pcy2HOSVeg%3D"
|
152
|
+
assert_equal expected, actual
|
153
|
+
end
|
154
|
+
|
155
|
+
test "temporary signature for object post" do
|
156
|
+
actual = S3::Signature.generate_temporary_url_signature(
|
157
|
+
:bucket => "johnsmith",
|
158
|
+
:resource => "photos/puppy.jpg",
|
159
|
+
:secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o",
|
160
|
+
:expires_at => 1175046589,
|
161
|
+
:method => :post
|
162
|
+
)
|
163
|
+
expected = "duIzwO2KTEMIlbSYbFFS86Wj0LI%3D"
|
164
|
+
assert_equal expected, actual
|
165
|
+
end
|
166
|
+
|
167
|
+
test "temporary signature for object put with headers" do
|
168
|
+
actual = S3::Signature.generate_temporary_url_signature(
|
169
|
+
:bucket => "johnsmith",
|
170
|
+
:resource => "photos/puppy.jpg",
|
171
|
+
:secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o",
|
172
|
+
:expires_at => 1175046589,
|
173
|
+
:method => :put,
|
174
|
+
:headers => {'x-amz-acl' => 'public-read'}
|
175
|
+
)
|
176
|
+
expected = "SDMxjIkOKIVR47nWfJ57UNPXxFM%3D"
|
177
|
+
assert_equal expected, actual
|
178
|
+
end
|
179
|
+
|
180
|
+
test "temporary signature for object delete" do
|
181
|
+
actual = S3::Signature.generate_temporary_url_signature(
|
182
|
+
:bucket => "johnsmith",
|
183
|
+
:resource => "photos/puppy.jpg",
|
184
|
+
:secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o",
|
185
|
+
:expires_at => 1175046589,
|
186
|
+
:method => :delete
|
187
|
+
)
|
188
|
+
expected = "5Vg7A4HxgS6tVCYzBx%2BkMR8sztY%3D"
|
189
|
+
assert_equal expected, actual
|
190
|
+
end
|
191
|
+
|
192
|
+
test "temporary url for object put with headers" do
|
193
|
+
actual = S3::Signature.generate_temporary_url(
|
194
|
+
:bucket => "johnsmith",
|
195
|
+
:resource => "photos/puppy.jpg",
|
196
|
+
:access_key => '0PN5J17HBGZHT7JJ3X82',
|
197
|
+
:secret_access_key => "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o",
|
198
|
+
:expires_at => 1175046589,
|
199
|
+
:method => :put,
|
200
|
+
:headers => {'x-amz-acl' => 'public-read'}
|
201
|
+
)
|
202
|
+
expected = "http://s3.amazonaws.com/johnsmith/photos/puppy.jpg?AWSAccessKeyId=0PN5J17HBGZHT7JJ3X82&Expires=1175046589&Signature=SDMxjIkOKIVR47nWfJ57UNPXxFM%3D"
|
203
|
+
assert_equal expected, actual
|
204
|
+
end
|
143
205
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 4
|
9
|
+
version: 0.3.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- "Jakub Ku\xC5\xBAma"
|
@@ -14,11 +14,11 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-09-
|
17
|
+
date: 2010-09-25 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
name:
|
21
|
+
name: proxies
|
22
22
|
prerelease: false
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
24
|
none: false
|
@@ -30,23 +30,10 @@ dependencies:
|
|
30
30
|
version: "0"
|
31
31
|
type: :runtime
|
32
32
|
version_requirements: *id001
|
33
|
-
- !ruby/object:Gem::Dependency
|
34
|
-
name: proxies
|
35
|
-
prerelease: false
|
36
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
-
none: false
|
38
|
-
requirements:
|
39
|
-
- - ">="
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
segments:
|
42
|
-
- 0
|
43
|
-
version: "0"
|
44
|
-
type: :runtime
|
45
|
-
version_requirements: *id002
|
46
33
|
- !ruby/object:Gem::Dependency
|
47
34
|
name: test-unit
|
48
35
|
prerelease: false
|
49
|
-
requirement: &
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
50
37
|
none: false
|
51
38
|
requirements:
|
52
39
|
- - ">="
|
@@ -56,11 +43,11 @@ dependencies:
|
|
56
43
|
- 0
|
57
44
|
version: "2.0"
|
58
45
|
type: :development
|
59
|
-
version_requirements: *
|
46
|
+
version_requirements: *id002
|
60
47
|
- !ruby/object:Gem::Dependency
|
61
48
|
name: mocha
|
62
49
|
prerelease: false
|
63
|
-
requirement: &
|
50
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
64
51
|
none: false
|
65
52
|
requirements:
|
66
53
|
- - ">="
|
@@ -69,11 +56,11 @@ dependencies:
|
|
69
56
|
- 0
|
70
57
|
version: "0"
|
71
58
|
type: :development
|
72
|
-
version_requirements: *
|
59
|
+
version_requirements: *id003
|
73
60
|
- !ruby/object:Gem::Dependency
|
74
61
|
name: bundler
|
75
62
|
prerelease: false
|
76
|
-
requirement: &
|
63
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
77
64
|
none: false
|
78
65
|
requirements:
|
79
66
|
- - ">="
|
@@ -84,12 +71,12 @@ dependencies:
|
|
84
71
|
- 0
|
85
72
|
version: 1.0.0
|
86
73
|
type: :development
|
87
|
-
version_requirements: *
|
74
|
+
version_requirements: *id004
|
88
75
|
description: "S3 library provides access to Amazon's Simple Storage Service. It supports both: European and US buckets through REST API."
|
89
76
|
email:
|
90
77
|
- qoobaa@gmail.com
|
91
|
-
executables:
|
92
|
-
|
78
|
+
executables: []
|
79
|
+
|
93
80
|
extensions: []
|
94
81
|
|
95
82
|
extra_rdoc_files: []
|
@@ -101,7 +88,6 @@ files:
|
|
101
88
|
- LICENSE
|
102
89
|
- README.rdoc
|
103
90
|
- Rakefile
|
104
|
-
- bin/s3
|
105
91
|
- extra/s3_attachment_fu.rb
|
106
92
|
- extra/s3_paperclip.rb
|
107
93
|
- lib/s3.rb
|
@@ -155,6 +141,6 @@ rubyforge_project: s3
|
|
155
141
|
rubygems_version: 1.3.7
|
156
142
|
signing_key:
|
157
143
|
specification_version: 3
|
158
|
-
summary: Library for accessing S3 objects and buckets
|
144
|
+
summary: Library for accessing S3 objects and buckets
|
159
145
|
test_files: []
|
160
146
|
|
data/bin/s3
DELETED
@@ -1,187 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
$: << File.expand_path(File.dirname(__FILE__) + "/../lib")
|
4
|
-
|
5
|
-
require "trollop"
|
6
|
-
require "s3"
|
7
|
-
|
8
|
-
# HELPER METHODS
|
9
|
-
|
10
|
-
include S3
|
11
|
-
|
12
|
-
def list_buckets(service)
|
13
|
-
service.buckets.each do |bucket|
|
14
|
-
puts bucket.name
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def create_bucket(service, name, location)
|
19
|
-
service.buckets.build(name).save(location)
|
20
|
-
end
|
21
|
-
|
22
|
-
def destroy_bucket(service, name)
|
23
|
-
service.buckets.find(name).destroy
|
24
|
-
end
|
25
|
-
|
26
|
-
def show_bucket(service, name, options = {})
|
27
|
-
service.buckets.find(name).objects.find_all.each do |object|
|
28
|
-
puts "#{name}/#{object.key}"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def list_objects(service)
|
33
|
-
service.buckets.each do |bucket|
|
34
|
-
bucket.objects.each do |object|
|
35
|
-
puts "#{bucket.name}/#{object.key}"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def create_object(service, name, file_name, options = {})
|
41
|
-
bucket_name, object_name = name.split("/", 2)
|
42
|
-
object = service.buckets.find(bucket_name).objects.build(object_name)
|
43
|
-
object.content_type = options[:type]
|
44
|
-
object.content_encoding = options[:encoding]
|
45
|
-
object.content_disposition = options[:disposition]
|
46
|
-
object.acl = options[:acl]
|
47
|
-
object.content = File.new(file_name)
|
48
|
-
object.save
|
49
|
-
end
|
50
|
-
|
51
|
-
def destroy_object(service, name)
|
52
|
-
bucket_name, object_name = name.split("/", 2)
|
53
|
-
object = service.buckets.find(bucket_name).objects.find(object_name)
|
54
|
-
object.destroy
|
55
|
-
end
|
56
|
-
|
57
|
-
def show_object(service, name, file_name = nil)
|
58
|
-
bucket_name, object_name = name.split("/", 2)
|
59
|
-
object = service.buckets.find(bucket_name).objects.find_first(object_name)
|
60
|
-
puts " object: #{object.name}/#{object.key}"
|
61
|
-
puts " content type: #{object.content_type}"
|
62
|
-
puts " size: #{object.size}"
|
63
|
-
puts " etag: #{object.etag}"
|
64
|
-
puts " last modified: #{object.last_modified}"
|
65
|
-
if file_name
|
66
|
-
if file_name == "-"
|
67
|
-
puts object.content
|
68
|
-
else
|
69
|
-
File.open(file_name, "wb") do |file|
|
70
|
-
file.write(object.content)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# COMMAND LINE PARSER
|
77
|
-
|
78
|
-
ACCESS_KEY_ID = ENV["ACCESS_KEY_ID"]
|
79
|
-
SECRET_ACCESS_KEY = ENV["SECRET_ACCESS_KEY"]
|
80
|
-
COMMANDS = %w(bucket object)
|
81
|
-
BUCKET_SUBCOMMANDS = %w(add remove show)
|
82
|
-
OBJECT_SUBCOMMANDS = %w(add remove show)
|
83
|
-
|
84
|
-
global_options = Trollop::options do
|
85
|
-
banner "s3 command line tool"
|
86
|
-
opt :access_key_id, "Your access key id to AWS", :type => :string, :default => ACCESS_KEY_ID
|
87
|
-
opt :secret_access_key, "Your secret access key to AWS", :type => :string, :default => SECRET_ACCESS_KEY
|
88
|
-
opt :debug, "Debug mode", :type => :flag, :default => false
|
89
|
-
stop_on COMMANDS
|
90
|
-
end
|
91
|
-
|
92
|
-
Trollop::die "No access key id given" unless global_options[:access_key_id]
|
93
|
-
Trollop::die "No secret access key given" unless global_options[:secret_access_key]
|
94
|
-
|
95
|
-
service = Service.new(:access_key_id => global_options[:access_key_id],
|
96
|
-
:secret_access_key => global_options[:secret_access_key],
|
97
|
-
:debug => global_options[:debug])
|
98
|
-
|
99
|
-
command = ARGV.shift
|
100
|
-
|
101
|
-
begin
|
102
|
-
case command
|
103
|
-
when "bucket"
|
104
|
-
command_options = Trollop::options do
|
105
|
-
banner "manage buckets"
|
106
|
-
stop_on BUCKET_SUBCOMMANDS
|
107
|
-
end
|
108
|
-
subcommand = ARGV.shift
|
109
|
-
case subcommand
|
110
|
-
when "add"
|
111
|
-
subcommand_options = Trollop::options do
|
112
|
-
banner "add bucket"
|
113
|
-
opt :location, "Location of the bucket - EU or US", :default => "US", :type => :string
|
114
|
-
end
|
115
|
-
name = ARGV.shift
|
116
|
-
Trollop::die "Bucket has not been added because of unknown error" unless create_bucket(service, name, subcommand_options[:location])
|
117
|
-
when "remove"
|
118
|
-
subcommand_options = Trollop::options do
|
119
|
-
banner "remove bucket"
|
120
|
-
end
|
121
|
-
name = ARGV.shift
|
122
|
-
Trollop::die "Bucket name must be given" if name.nil? or name.empty?
|
123
|
-
Trollop::die "Bucket has not been removed because of unknown error" unless destroy_bucket(service, name)
|
124
|
-
when "show"
|
125
|
-
subcommand_options = Trollop::options do
|
126
|
-
banner "show bucket"
|
127
|
-
opt :prefix, "Limits the response to keys which begin with the indicated prefix", :type => :string
|
128
|
-
opt :marker, "Indicates where in the bucket to begin listing", :type => :string
|
129
|
-
opt :max_keys, "The maximum number of keys you'd like to see", :type => :integer
|
130
|
-
opt :delimiter, "Causes keys that contain the same string between the prefix and the first occurrence of the delimiter to be rolled up into a single result element", :type => :string
|
131
|
-
end
|
132
|
-
name = ARGV.shift
|
133
|
-
Trollop::die "Bucket name must be given" if name.nil? or name.empty?
|
134
|
-
show_bucket(service, name, subcommand_options)
|
135
|
-
when nil
|
136
|
-
list_buckets(service)
|
137
|
-
else
|
138
|
-
Trollop::die "Unknown subcommand: #{subcommand.inspect}"
|
139
|
-
end
|
140
|
-
when "object"
|
141
|
-
command_options = Trollop::options do
|
142
|
-
banner "manage objects"
|
143
|
-
stop_on OBJECT_SUBCOMMANDS
|
144
|
-
end
|
145
|
-
subcommand = ARGV.shift
|
146
|
-
case subcommand
|
147
|
-
when "add"
|
148
|
-
subcommand_options = Trollop::options do
|
149
|
-
banner "object add s3_object_name local_file_name"
|
150
|
-
opt :type, "A standard MIME type describing the format of the contents", :default => "binary/octet-stream"
|
151
|
-
opt :disposition, "Specifies presentational information for the object", :type => :string
|
152
|
-
opt :encoding, "Specifies what content encodings have been applied to the object and thus what decoding mechanisms must be applied in order to obtain the media-type referenced by the Content-Type header field", :type => :string
|
153
|
-
opt :acl, "The canned ACL to apply to the object. Options include private, public-read, public-read-write, and authenticated-read", :type => :string
|
154
|
-
end
|
155
|
-
name = ARGV.shift
|
156
|
-
Trollop::die "No object name given" if name.nil? or name.empty?
|
157
|
-
file_name = ARGV.shift
|
158
|
-
Trollop::die "No file name given" if file_name.nil? or file_name.empty?
|
159
|
-
Trollop::die "Object has not been added because of unknown error" unless create_object(service, name, file_name, subcommand_options)
|
160
|
-
when "remove"
|
161
|
-
subcommand_options = Trollop::options do
|
162
|
-
banner "object remove s3_object_name"
|
163
|
-
end
|
164
|
-
name = ARGV.shift
|
165
|
-
Trollop::die "No object name given" if name.nil? or name.empty?
|
166
|
-
Trollop::die "Object has not been removed because of unknown error" unless destroy_object(service, name)
|
167
|
-
when "show"
|
168
|
-
subcommand_options = Trollop::options do
|
169
|
-
banner "object show s3_object_name optional_file_name"
|
170
|
-
end
|
171
|
-
name = ARGV.shift
|
172
|
-
Trollop::die "No object name given" if name.nil? or name.empty?
|
173
|
-
file_name = ARGV.shift
|
174
|
-
show_object(service, name, file_name)
|
175
|
-
when nil
|
176
|
-
list_objects(service)
|
177
|
-
else
|
178
|
-
Trollop::die "Unknown subcommand: #{subcommand.inspect}"
|
179
|
-
end
|
180
|
-
when nil
|
181
|
-
Trollop::die "No command given"
|
182
|
-
else
|
183
|
-
Trollop::die "Unknown command #{command.inspect}"
|
184
|
-
end
|
185
|
-
rescue Error::ResponseError => e
|
186
|
-
Trollop::die e.message.sub(/\.+\Z/, "")
|
187
|
-
end
|