rackspace-cloudfiles 1.3.0.7 → 1.4.0.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/README.rdoc +2 -2
- data/Rakefile +3 -3
- data/cloudfiles.gemspec +5 -5
- data/lib/cloudfiles.rb +2 -2
- data/lib/cloudfiles/authentication.rb +4 -0
- data/lib/cloudfiles/connection.rb +29 -15
- data/lib/cloudfiles/container.rb +34 -9
- data/lib/cloudfiles/storage_object.rb +13 -10
- data/test/cloudfiles_authentication_test.rb +1 -1
- data/test/cloudfiles_connection_test.rb +14 -14
- data/test/cloudfiles_container_test.rb +20 -16
- data/test/cloudfiles_storage_object_test.rb +42 -3
- metadata +5 -5
data/README.rdoc
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
=
|
1
|
+
= Rackspace Cloud Files
|
2
2
|
|
3
3
|
== Description
|
4
4
|
|
5
|
-
This is a Ruby interface into the Rackspace[http://rackspace.com/] {
|
5
|
+
This is a Ruby interface into the Rackspace[http://rackspace.com/] {Cloud Files}[http://www.rackspacecloud.com/cloud_hosting_products/files] service. Cloud Files is reliable, scalable and affordable web-based storage hosting for backing up and archiving all your static content. Cloud Files is the first and only cloud service that leverages a tier one CDN provider to create such an easy and complete storage-to-delivery solution for media content.
|
6
6
|
|
7
7
|
== Installation
|
8
8
|
|
data/Rakefile
CHANGED
@@ -7,9 +7,9 @@ echoe = Echoe.new('cloudfiles') do |p|
|
|
7
7
|
p.author = ["H. Wade Minter", "Rackspace Hosting"]
|
8
8
|
p.email = 'wade.minter@rackspace.com'
|
9
9
|
p.version = CloudFiles::VERSION
|
10
|
-
p.summary = "A Ruby API into
|
11
|
-
p.description = 'A Ruby version of the
|
12
|
-
p.url = "http://www.
|
10
|
+
p.summary = "A Ruby API into Rackspace Cloud Files"
|
11
|
+
p.description = 'A Ruby version of the Rackspace Cloud Files API.'
|
12
|
+
p.url = "http://www.rackspacecloud.com/cloud_hosting_products/files"
|
13
13
|
p.runtime_dependencies = ["mime-types >=1.0"]
|
14
14
|
end
|
15
15
|
|
data/cloudfiles.gemspec
CHANGED
@@ -2,22 +2,22 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{cloudfiles}
|
5
|
-
s.version = "1.
|
5
|
+
s.version = "1.4.0.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["H. Wade Minter, Rackspace Hosting"]
|
9
|
-
s.date = %q{2009-
|
10
|
-
s.description = %q{A Ruby version of the
|
9
|
+
s.date = %q{2009-08-08}
|
10
|
+
s.description = %q{A Ruby version of the Rackspace Cloud Files API.}
|
11
11
|
s.email = %q{wade.minter@rackspace.com}
|
12
12
|
s.extra_rdoc_files = ["lib/cloudfiles/authentication.rb", "lib/cloudfiles/connection.rb", "lib/cloudfiles/container.rb", "lib/cloudfiles/storage_object.rb", "lib/cloudfiles.rb", "README.rdoc", "TODO"]
|
13
13
|
s.files = ["cloudfiles.gemspec", "lib/cloudfiles/authentication.rb", "lib/cloudfiles/connection.rb", "lib/cloudfiles/container.rb", "lib/cloudfiles/storage_object.rb", "lib/cloudfiles.rb", "Manifest", "Rakefile", "README.rdoc", "test/cf-testunit.rb", "test/cloudfiles_authentication_test.rb", "test/cloudfiles_connection_test.rb", "test/cloudfiles_container_test.rb", "test/cloudfiles_storage_object_test.rb", "test/test_helper.rb", "TODO"]
|
14
14
|
s.has_rdoc = true
|
15
|
-
s.homepage = %q{http://www.
|
15
|
+
s.homepage = %q{http://www.rackspacecloud.com/cloud_hosting_products/files}
|
16
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Cloudfiles", "--main", "README.rdoc"]
|
17
17
|
s.require_paths = ["lib"]
|
18
18
|
s.rubyforge_project = %q{cloudfiles}
|
19
19
|
s.rubygems_version = %q{1.3.1}
|
20
|
-
s.summary = %q{A Ruby API into
|
20
|
+
s.summary = %q{A Ruby API into Rackspace Cloud Files}
|
21
21
|
s.test_files = ["test/cloudfiles_authentication_test.rb", "test/cloudfiles_connection_test.rb", "test/cloudfiles_container_test.rb", "test/cloudfiles_storage_object_test.rb", "test/test_helper.rb"]
|
22
22
|
|
23
23
|
if s.respond_to? :specification_version then
|
data/lib/cloudfiles.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
#
|
3
3
|
# == Cloud Files API
|
4
|
-
# ==== Connects Ruby Applications to Rackspace's {
|
4
|
+
# ==== Connects Ruby Applications to Rackspace's {Cloud Files service}[http://www.rackspacecloud.com/cloud_hosting_products/files]
|
5
5
|
# Initial work by Major Hayden <major.hayden@rackspace.com>
|
6
6
|
#
|
7
7
|
# Subsequent work by H. Wade Minter <wade.minter@rackspace.com>
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# To create a new CloudFiles connection, use the CloudFiles::Connection.new('user_name', 'api_key') method.
|
19
19
|
module CloudFiles
|
20
20
|
|
21
|
-
VERSION = '1.
|
21
|
+
VERSION = '1.4.0.0'
|
22
22
|
require 'net/http'
|
23
23
|
require 'net/https'
|
24
24
|
require 'rexml/document'
|
@@ -24,8 +24,12 @@ module CloudFiles
|
|
24
24
|
if (response.code == "204")
|
25
25
|
connection.cdnmgmthost = URI.parse(response["x-cdn-management-url"]).host
|
26
26
|
connection.cdnmgmtpath = URI.parse(response["x-cdn-management-url"]).path
|
27
|
+
connection.cdnmgmtport = URI.parse(response["x-cdn-management-url"]).port
|
28
|
+
connection.cdnmgmtscheme = URI.parse(response["x-cdn-management-url"]).scheme
|
27
29
|
connection.storagehost = URI.parse(response["x-storage-url"]).host
|
28
30
|
connection.storagepath = URI.parse(response["x-storage-url"]).path
|
31
|
+
connection.storageport = URI.parse(response["x-storage-url"]).port
|
32
|
+
connection.storagescheme = URI.parse(response["x-storage-url"]).scheme
|
29
33
|
connection.authtoken = response["x-auth-token"]
|
30
34
|
connection.authok = true
|
31
35
|
else
|
@@ -17,6 +17,12 @@ module CloudFiles
|
|
17
17
|
|
18
18
|
# Path for managing containers on the CDN management server
|
19
19
|
attr_accessor :cdnmgmtpath
|
20
|
+
|
21
|
+
# Port number for the CDN server
|
22
|
+
attr_accessor :cdnmgmtport
|
23
|
+
|
24
|
+
# URI scheme for the CDN server
|
25
|
+
attr_accessor :cdnmgmtscheme
|
20
26
|
|
21
27
|
# Hostname of the storage server
|
22
28
|
attr_accessor :storagehost
|
@@ -24,6 +30,12 @@ module CloudFiles
|
|
24
30
|
# Path for managing containers/objects on the storage server
|
25
31
|
attr_accessor :storagepath
|
26
32
|
|
33
|
+
# Port for managing the storage server
|
34
|
+
attr_accessor :storageport
|
35
|
+
|
36
|
+
# URI scheme for the storage server
|
37
|
+
attr_accessor :storagescheme
|
38
|
+
|
27
39
|
# Instance variable that is set when authorization succeeds
|
28
40
|
attr_accessor :authok
|
29
41
|
|
@@ -34,7 +46,7 @@ module CloudFiles
|
|
34
46
|
attr_reader :count
|
35
47
|
|
36
48
|
# Creates a new CloudFiles::Connection object. Uses CloudFiles::Authentication to perform the login for the connection.
|
37
|
-
# The authuser is the
|
49
|
+
# The authuser is the Rackspace Cloud username, the authkey is the Rackspace Cloud API key.
|
38
50
|
#
|
39
51
|
# Setting the optional retry_auth variable to false will cause an exception to be thrown if your authorization token expires.
|
40
52
|
# Otherwise, it will attempt to reauthenticate.
|
@@ -78,7 +90,7 @@ module CloudFiles
|
|
78
90
|
# cf.bytes
|
79
91
|
# => 42438527
|
80
92
|
def get_info
|
81
|
-
response = cfreq("HEAD",@storagehost,@storagepath)
|
93
|
+
response = cfreq("HEAD",@storagehost,@storagepath,@storageport,@storagescheme)
|
82
94
|
raise InvalidResponseException, "Unable to obtain account size" unless (response.code == "204")
|
83
95
|
@bytes = response["x-account-bytes-used"].to_i
|
84
96
|
@count = response["x-account-container-count"].to_i
|
@@ -102,7 +114,7 @@ module CloudFiles
|
|
102
114
|
paramarr << ["limit=#{URI.encode(limit.to_s).gsub(/&/,'%26')}"] if limit.to_i > 0
|
103
115
|
paramarr << ["offset=#{URI.encode(marker.to_s).gsub(/&/,'%26')}"] unless marker.to_s.empty?
|
104
116
|
paramstr = (paramarr.size > 0)? paramarr.join("&") : "" ;
|
105
|
-
response = cfreq("GET",@storagehost,"#{@storagepath}?#{paramstr}")
|
117
|
+
response = cfreq("GET",@storagehost,"#{@storagepath}?#{paramstr}",@storageport,@storagescheme)
|
106
118
|
return [] if (response.code == "204")
|
107
119
|
raise InvalidResponseException, "Invalid response code #{response.code}" unless (response.code == "200")
|
108
120
|
CloudFiles.lines(response.body)
|
@@ -124,7 +136,7 @@ module CloudFiles
|
|
124
136
|
paramarr << ["limit=#{URI.encode(limit.to_s).gsub(/&/,'%26')}"] if limit.to_i > 0
|
125
137
|
paramarr << ["offset=#{URI.encode(marker.to_s).gsub(/&/,'%26')}"] unless marker.to_s.empty?
|
126
138
|
paramstr = (paramarr.size > 0)? paramarr.join("&") : "" ;
|
127
|
-
response = cfreq("GET",@storagehost,"#{@storagepath}?format=xml&#{paramstr}")
|
139
|
+
response = cfreq("GET",@storagehost,"#{@storagepath}?format=xml&#{paramstr}",@storageport,@storagescheme)
|
128
140
|
return {} if (response.code == "204")
|
129
141
|
raise InvalidResponseException, "Invalid response code #{response.code}" unless (response.code == "200")
|
130
142
|
doc = REXML::Document.new(response.body)
|
@@ -145,7 +157,7 @@ module CloudFiles
|
|
145
157
|
# cf.container_exists?('bad_container')
|
146
158
|
# => false
|
147
159
|
def container_exists?(containername)
|
148
|
-
response = cfreq("HEAD",@storagehost,"#{@storagepath}/#{containername}")
|
160
|
+
response = cfreq("HEAD",@storagehost,"#{@storagepath}/#{containername}",@storageport,@storagescheme)
|
149
161
|
return (response.code == "204")? true : false ;
|
150
162
|
end
|
151
163
|
|
@@ -164,7 +176,7 @@ module CloudFiles
|
|
164
176
|
def create_container(containername)
|
165
177
|
raise SyntaxException, "Container name cannot contain the characters '/' or '?'" if containername.match(/[\/\?]/)
|
166
178
|
raise SyntaxException, "Container name is limited to 256 characters" if containername.length > 256
|
167
|
-
response = cfreq("PUT",@storagehost,"#{@storagepath}/#{containername}")
|
179
|
+
response = cfreq("PUT",@storagehost,"#{@storagepath}/#{containername}",@storageport,@storagescheme)
|
168
180
|
raise InvalidResponseException, "Unable to create container #{containername}" unless (response.code == "201" || response.code == "202")
|
169
181
|
CloudFiles::Container.new(self,containername)
|
170
182
|
end
|
@@ -181,7 +193,7 @@ module CloudFiles
|
|
181
193
|
# cf.delete_container('nonexistent')
|
182
194
|
# => NoSuchContainerException: Container nonexistent does not exist
|
183
195
|
def delete_container(containername)
|
184
|
-
response = cfreq("DELETE",@storagehost,"#{@storagepath}/#{containername}")
|
196
|
+
response = cfreq("DELETE",@storagehost,"#{@storagepath}/#{containername}",@storageport,@storagescheme)
|
185
197
|
raise NonEmptyContainerException, "Container #{containername} is not empty" if (response.code == "409")
|
186
198
|
raise NoSuchContainerException, "Container #{containername} does not exist" unless (response.code == "204")
|
187
199
|
true
|
@@ -198,18 +210,18 @@ module CloudFiles
|
|
198
210
|
# => ["video", "webpics"]
|
199
211
|
def public_containers(enabled_only = false)
|
200
212
|
paramstr = enabled_only == true ? "enabled_only=true" : ""
|
201
|
-
response = cfreq("GET",@cdnmgmthost,"#{@cdnmgmtpath}?#{paramstr}")
|
213
|
+
response = cfreq("GET",@cdnmgmthost,"#{@cdnmgmtpath}?#{paramstr}",@cdnmgmtport,@cdnmgmtscheme)
|
202
214
|
return [] if (response.code == "204")
|
203
215
|
raise InvalidResponseException, "Invalid response code #{response.code}" unless (response.code == "200")
|
204
216
|
CloudFiles.lines(response.body)
|
205
217
|
end
|
206
218
|
|
207
219
|
# This method actually makes the HTTP calls out to the server
|
208
|
-
def cfreq(method,server,path,headers = {},data = nil,attempts = 0,&block) # :nodoc:
|
220
|
+
def cfreq(method,server,path,port,scheme,headers = {},data = nil,attempts = 0,&block) # :nodoc:
|
209
221
|
start = Time.now
|
210
222
|
headers['Transfer-Encoding'] = "chunked" if data.is_a?(IO)
|
211
223
|
hdrhash = headerprep(headers)
|
212
|
-
start_http(server,path,hdrhash)
|
224
|
+
start_http(server,path,port,scheme,hdrhash)
|
213
225
|
request = Net::HTTP.const_get(method.to_s.capitalize).new(path,hdrhash)
|
214
226
|
if data
|
215
227
|
if data.respond_to?(:read)
|
@@ -231,7 +243,7 @@ module CloudFiles
|
|
231
243
|
raise ConnectionException, "Unable to reconnect to #{server} after #{count} attempts" if attempts >= 5
|
232
244
|
attempts += 1
|
233
245
|
@http[server].finish
|
234
|
-
start_http(server,path,headers)
|
246
|
+
start_http(server,path,port,scheme,headers)
|
235
247
|
retry
|
236
248
|
rescue ExpiredAuthTokenException
|
237
249
|
raise ConnectionException, "Authentication token expired and you have requested not to retry" if @retry_auth == false
|
@@ -252,12 +264,14 @@ module CloudFiles
|
|
252
264
|
end
|
253
265
|
|
254
266
|
# Starts (or restarts) the HTTP connection
|
255
|
-
def start_http(server,path,headers) # :nodoc:
|
267
|
+
def start_http(server,path,port,scheme,headers) # :nodoc:
|
256
268
|
if (@http[server].nil?)
|
257
269
|
begin
|
258
|
-
@http[server] = Net::HTTP.new(server,
|
259
|
-
|
260
|
-
|
270
|
+
@http[server] = Net::HTTP.new(server,port)
|
271
|
+
if scheme == "https"
|
272
|
+
@http[server].use_ssl = true
|
273
|
+
@http[server].verify_mode = OpenSSL::SSL::VERIFY_NONE
|
274
|
+
end
|
261
275
|
@http[server].start
|
262
276
|
rescue
|
263
277
|
raise ConnectionException, "Unable to connect to #{server}"
|
data/lib/cloudfiles/container.rb
CHANGED
@@ -33,8 +33,12 @@ module CloudFiles
|
|
33
33
|
@name = name
|
34
34
|
@storagehost = self.connection.storagehost
|
35
35
|
@storagepath = self.connection.storagepath + "/" + URI.encode(@name).gsub(/&/,'%26')
|
36
|
+
@storageport = self.connection.storageport
|
37
|
+
@storagescheme = self.connection.storagescheme
|
36
38
|
@cdnmgmthost = self.connection.cdnmgmthost
|
37
39
|
@cdnmgmtpath = self.connection.cdnmgmtpath + "/" + URI.encode(@name).gsub(/&/,'%26')
|
40
|
+
@cdnmgmtport = self.connection.cdnmgmtport
|
41
|
+
@cdnmgmtscheme = self.connection.cdnmgmtscheme
|
38
42
|
populate
|
39
43
|
end
|
40
44
|
|
@@ -52,20 +56,41 @@ module CloudFiles
|
|
52
56
|
# => 3
|
53
57
|
def populate
|
54
58
|
# Get the size and object count
|
55
|
-
response = self.connection.cfreq("HEAD",@storagehost,@storagepath+"/")
|
59
|
+
response = self.connection.cfreq("HEAD",@storagehost,@storagepath+"/",@storageport,@storagescheme)
|
56
60
|
raise NoSuchContainerException, "Container #{@name} does not exist" unless (response.code == "204")
|
57
61
|
@bytes = response["x-container-bytes-used"].to_i
|
58
62
|
@count = response["x-container-object-count"].to_i
|
59
63
|
|
60
64
|
# Get the CDN-related details
|
61
|
-
response = self.connection.cfreq("HEAD",@cdnmgmthost,@cdnmgmtpath)
|
65
|
+
response = self.connection.cfreq("HEAD",@cdnmgmthost,@cdnmgmtpath,@cdnmgmtport,@cdnmgmtscheme)
|
62
66
|
@cdn_enabled = ((response["x-cdn-enabled"] || "").downcase == "true") ? true : false
|
63
67
|
@cdn_ttl = @cdn_enabled ? response["x-ttl"] : false
|
64
68
|
@cdn_url = @cdn_enabled ? response["x-cdn-uri"] : false
|
69
|
+
if @cdn_enabled
|
70
|
+
@cdn_log = response["x-log-retention"] == "False" ? false : true
|
71
|
+
else
|
72
|
+
@cdn_log = false
|
73
|
+
end
|
65
74
|
|
66
75
|
true
|
67
76
|
end
|
68
77
|
alias :refresh :populate
|
78
|
+
|
79
|
+
# Returns true if log retention is enabled on this container, false otherwise
|
80
|
+
def log_retention?
|
81
|
+
@cdn_log
|
82
|
+
end
|
83
|
+
|
84
|
+
# Change the log retention status for this container. Values are true or false.
|
85
|
+
#
|
86
|
+
# These logs will be periodically (at unpredictable intervals) compressed and uploaded
|
87
|
+
# to a “.CDN_ACCESS_LOGS” container in the form of “container_name.YYYYMMDDHH-XXXX.gz”.
|
88
|
+
def log_retention=(value)
|
89
|
+
response = self.connection.cfreq("POST",@cdnmgmthost,@cdnmgmtpath,@cdnmgmtport,@cdnmgmtscheme,{"x-log-retention" => value.to_s.capitalize})
|
90
|
+
raise InvalidResponseException, "Invalid response code #{response.code}" unless (response.code == "201" or response.code == "202")
|
91
|
+
return true
|
92
|
+
end
|
93
|
+
|
69
94
|
|
70
95
|
# Returns the CloudFiles::StorageObject for the named object. Refer to the CloudFiles::StorageObject class for available
|
71
96
|
# methods. If the object exists, it will be returned. If the object does not exist, a NoSuchObjectException will be thrown.
|
@@ -105,7 +130,7 @@ module CloudFiles
|
|
105
130
|
paramarr << ["prefix=#{URI.encode(params[:prefix]).gsub(/&/,'%26')}"] if params[:prefix]
|
106
131
|
paramarr << ["path=#{URI.encode(params[:path]).gsub(/&/,'%26')}"] if params[:path]
|
107
132
|
paramstr = (paramarr.size > 0)? paramarr.join("&") : "" ;
|
108
|
-
response = self.connection.cfreq("GET",@storagehost,"#{@storagepath}?#{paramstr}")
|
133
|
+
response = self.connection.cfreq("GET",@storagehost,"#{@storagepath}?#{paramstr}",@storageport,@storagescheme)
|
109
134
|
return [] if (response.code == "204")
|
110
135
|
raise InvalidResponseException, "Invalid response code #{response.code}" unless (response.code == "200")
|
111
136
|
return CloudFiles.lines(response.body)
|
@@ -136,7 +161,7 @@ module CloudFiles
|
|
136
161
|
paramarr << ["prefix=#{URI.encode(params[:prefix]).gsub(/&/,'%26')}"] if params[:prefix]
|
137
162
|
paramarr << ["path=#{URI.encode(params[:path]).gsub(/&/,'%26')}"] if params[:path]
|
138
163
|
paramstr = (paramarr.size > 0)? paramarr.join("&") : "" ;
|
139
|
-
response = self.connection.cfreq("GET",@storagehost,"#{@storagepath}?#{paramstr}")
|
164
|
+
response = self.connection.cfreq("GET",@storagehost,"#{@storagepath}?#{paramstr}",@storageport,@storagescheme)
|
140
165
|
return {} if (response.code == "204")
|
141
166
|
raise InvalidResponseException, "Invalid response code #{response.code}" unless (response.code == "200")
|
142
167
|
doc = REXML::Document.new(response.body)
|
@@ -179,7 +204,7 @@ module CloudFiles
|
|
179
204
|
# container.object_exists?('badfile.txt')
|
180
205
|
# => false
|
181
206
|
def object_exists?(objectname)
|
182
|
-
response = self.connection.cfreq("HEAD",@storagehost,"#{@storagepath}/#{URI.encode(objectname).gsub(/&/,'%26')}")
|
207
|
+
response = self.connection.cfreq("HEAD",@storagehost,"#{@storagepath}/#{URI.encode(objectname).gsub(/&/,'%26')}",@storageport,@storagescheme)
|
183
208
|
return (response.code == "204")? true : false
|
184
209
|
end
|
185
210
|
|
@@ -204,7 +229,7 @@ module CloudFiles
|
|
204
229
|
# container.delete_object('nonexistent_file.txt')
|
205
230
|
# => NoSuchObjectException: Object nonexistent_file.txt does not exist
|
206
231
|
def delete_object(objectname)
|
207
|
-
response = self.connection.cfreq("DELETE",@storagehost,"#{@storagepath}/#{URI.encode(objectname).gsub(/&/,'%26')}")
|
232
|
+
response = self.connection.cfreq("DELETE",@storagehost,"#{@storagepath}/#{URI.encode(objectname).gsub(/&/,'%26')}",@storageport,@storagescheme)
|
208
233
|
raise NoSuchObjectException, "Object #{objectname} does not exist" if (response.code == "404")
|
209
234
|
raise InvalidResponseException, "Invalid response code #{response.code}" unless (response.code == "204")
|
210
235
|
true
|
@@ -218,11 +243,11 @@ module CloudFiles
|
|
218
243
|
# container.make_public(432000)
|
219
244
|
# => true
|
220
245
|
def make_public(ttl = 86400)
|
221
|
-
response = self.connection.cfreq("PUT",@cdnmgmthost,@cdnmgmtpath)
|
246
|
+
response = self.connection.cfreq("PUT",@cdnmgmthost,@cdnmgmtpath,@cdnmgmtport,@cdnmgmtscheme)
|
222
247
|
raise NoSuchContainerException, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202")
|
223
248
|
|
224
249
|
headers = { "X-TTL" => ttl.to_s }
|
225
|
-
response = self.connection.cfreq("POST",@cdnmgmthost,@cdnmgmtpath,headers)
|
250
|
+
response = self.connection.cfreq("POST",@cdnmgmthost,@cdnmgmtpath,@cdnmgmtport,@cdnmgmtscheme,headers)
|
226
251
|
raise NoSuchContainerException, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202")
|
227
252
|
true
|
228
253
|
end
|
@@ -236,7 +261,7 @@ module CloudFiles
|
|
236
261
|
# => true
|
237
262
|
def make_private
|
238
263
|
headers = { "X-CDN-Enabled" => "False" }
|
239
|
-
response = self.connection.cfreq("POST",@cdnmgmthost,@cdnmgmtpath,headers)
|
264
|
+
response = self.connection.cfreq("POST",@cdnmgmthost,@cdnmgmtpath,@cdnmgmtport,@cdnmgmtscheme,headers)
|
240
265
|
raise NoSuchContainerException, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202")
|
241
266
|
true
|
242
267
|
end
|
@@ -34,6 +34,8 @@ module CloudFiles
|
|
34
34
|
@make_path = make_path
|
35
35
|
@storagehost = self.container.connection.storagehost
|
36
36
|
@storagepath = self.container.connection.storagepath+"/#{URI.encode(@containername).gsub(/&/,'%26')}/#{URI.encode(@name).gsub(/&/,'%26')}"
|
37
|
+
@storageport = self.container.connection.storageport
|
38
|
+
@storagescheme = self.container.connection.storagescheme
|
37
39
|
if container.object_exists?(objectname)
|
38
40
|
populate
|
39
41
|
else
|
@@ -44,14 +46,14 @@ module CloudFiles
|
|
44
46
|
# Caches data about the CloudFiles::StorageObject for fast retrieval. This method is automatically called when the
|
45
47
|
# class is initialized, but it can be called again if the data needs to be updated.
|
46
48
|
def populate
|
47
|
-
response = self.container.connection.cfreq("HEAD",@storagehost,@storagepath)
|
49
|
+
response = self.container.connection.cfreq("HEAD",@storagehost,@storagepath,@storageport,@storagescheme)
|
48
50
|
raise NoSuchObjectException, "Object #{@name} does not exist" if (response.code != "204")
|
49
51
|
@bytes = response["content-length"]
|
50
52
|
@last_modified = Time.parse(response["last-modified"])
|
51
53
|
@etag = response["etag"]
|
52
54
|
@content_type = response["content-type"]
|
53
55
|
resphash = {}
|
54
|
-
response.to_hash.select { |k,v| k.match(/^x-object-meta/) }.each { |x| resphash[x[0]] = x[1]
|
56
|
+
response.to_hash.select { |k,v| k.match(/^x-object-meta/) }.each { |x| resphash[x[0]] = x[1].to_s }
|
55
57
|
@metadata = resphash
|
56
58
|
true
|
57
59
|
end
|
@@ -70,7 +72,7 @@ module CloudFiles
|
|
70
72
|
range = sprintf("bytes=%d-%d", offset.to_i, (offset.to_i + size.to_i) - 1)
|
71
73
|
headers['Range'] = range
|
72
74
|
end
|
73
|
-
response = self.container.connection.cfreq("GET",@storagehost,@storagepath,headers)
|
75
|
+
response = self.container.connection.cfreq("GET",@storagehost,@storagepath,@storageport,@storagescheme,headers)
|
74
76
|
raise NoSuchObjectException, "Object #{@name} does not exist" unless (response.code =~ /^20/)
|
75
77
|
response.body.chomp
|
76
78
|
end
|
@@ -93,7 +95,7 @@ module CloudFiles
|
|
93
95
|
range = sprintf("bytes=%d-%d", offset.to_i, (offset.to_i + size.to_i) - 1)
|
94
96
|
headers['Range'] = range
|
95
97
|
end
|
96
|
-
self.container.connection.cfreq("GET",@storagehost,@storagepath,headers,nil) do |response|
|
98
|
+
self.container.connection.cfreq("GET",@storagehost,@storagepath,@storageport,@storagescheme,headers,nil) do |response|
|
97
99
|
raise NoSuchObjectException, "Object #{@name} does not exist" unless (response.code == "200")
|
98
100
|
response.read_body(&block)
|
99
101
|
end
|
@@ -118,7 +120,7 @@ module CloudFiles
|
|
118
120
|
def set_metadata(metadatahash)
|
119
121
|
headers = {}
|
120
122
|
metadatahash.each{|key, value| headers['X-Object-Meta-' + key.to_s.capitalize] = value.to_s}
|
121
|
-
response = self.container.connection.cfreq("POST",@storagehost,@storagepath,headers)
|
123
|
+
response = self.container.connection.cfreq("POST",@storagehost,@storagepath,@storageport,@storagescheme,headers)
|
122
124
|
raise NoSuchObjectException, "Object #{@name} does not exist" if (response.code == "404")
|
123
125
|
raise InvalidResponseException, "Invalid response code #{response.code}" unless (response.code == "202")
|
124
126
|
true
|
@@ -164,10 +166,11 @@ module CloudFiles
|
|
164
166
|
end
|
165
167
|
# If we're taking data from standard input, send that IO object to cfreq
|
166
168
|
data = $stdin if (data.nil? && $stdin.tty? == false)
|
167
|
-
response = self.container.connection.cfreq("PUT",@storagehost,"#{@storagepath}",headers,data)
|
168
|
-
|
169
|
-
raise
|
170
|
-
raise
|
169
|
+
response = self.container.connection.cfreq("PUT",@storagehost,"#{@storagepath}",@storageport,@storagescheme,headers,data)
|
170
|
+
code = response.code
|
171
|
+
raise InvalidResponseException, "Invalid content-length header sent" if (code == "412")
|
172
|
+
raise MisMatchedChecksumException, "Mismatched etag" if (code == "422")
|
173
|
+
raise InvalidResponseException, "Invalid response code #{code}" unless (code == "201")
|
171
174
|
make_path(File.dirname(self.name)) if @make_path == true
|
172
175
|
self.populate
|
173
176
|
true
|
@@ -223,7 +226,7 @@ module CloudFiles
|
|
223
226
|
# If the parent container is public (CDN-enabled), returns the CDN URL to this object. Otherwise, return nil
|
224
227
|
#
|
225
228
|
# public_object.public_url
|
226
|
-
# => "http://cdn.cloudfiles.
|
229
|
+
# => "http://c0001234.cdn.cloudfiles.rackspacecloud.com/myfile.jpg"
|
227
230
|
#
|
228
231
|
# private_object.public_url
|
229
232
|
# => nil
|
@@ -9,7 +9,7 @@ class CloudfilesAuthenticationTest < Test::Unit::TestCase
|
|
9
9
|
server = mock(:use_ssl= => true, :verify_mode= => true, :start => true, :finish => true)
|
10
10
|
server.stubs(:get).returns(response)
|
11
11
|
Net::HTTP.stubs(:new).returns(server)
|
12
|
-
@connection = stub(:authuser => 'dummy_user', :authkey => 'dummy_key', :cdnmgmthost= => true, :cdnmgmtpath= => true, :storagehost= => true, :storagepath= => true, :authtoken= => true, :authok= => true)
|
12
|
+
@connection = stub(:authuser => 'dummy_user', :authkey => 'dummy_key', :cdnmgmthost= => true, :cdnmgmtpath= => true, :cdnmgmtport= => true, :cdnmgmtscheme= => true, :storagehost= => true, :storagepath= => true, :storageport= => true, :storagescheme= => true, :authtoken= => true, :authok= => true)
|
13
13
|
result = CloudFiles::Authentication.new(@connection)
|
14
14
|
assert_equal result.class, CloudFiles::Authentication
|
15
15
|
end
|
@@ -26,35 +26,35 @@ class CloudfilesConnectionTest < Test::Unit::TestCase
|
|
26
26
|
def test_cfreq_get
|
27
27
|
build_net_http_object
|
28
28
|
assert_nothing_raised do
|
29
|
-
response = @connection.cfreq("GET", "test.server.example", "/dummypath")
|
29
|
+
response = @connection.cfreq("GET", "test.server.example", "/dummypath", "80", "http")
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
def test_cfreq_post
|
34
34
|
build_net_http_object
|
35
35
|
assert_nothing_raised do
|
36
|
-
response = @connection.cfreq("POST", "test.server.example", "/dummypath")
|
36
|
+
response = @connection.cfreq("POST", "test.server.example", "/dummypath", "80", "http")
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
40
|
def test_cfreq_put
|
41
41
|
build_net_http_object
|
42
42
|
assert_nothing_raised do
|
43
|
-
response = @connection.cfreq("PUT", "test.server.example", "/dummypath")
|
43
|
+
response = @connection.cfreq("PUT", "test.server.example", "/dummypath", "80", "http")
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_cfreq_delete
|
48
48
|
build_net_http_object
|
49
49
|
assert_nothing_raised do
|
50
|
-
response = @connection.cfreq("DELETE", "test.server.example", "/dummypath")
|
50
|
+
response = @connection.cfreq("DELETE", "test.server.example", "/dummypath", "80", "http")
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
54
|
def test_cfreq_with_static_data
|
55
55
|
build_net_http_object
|
56
56
|
assert_nothing_raised do
|
57
|
-
response = @connection.cfreq("PUT", "test.server.example", "/dummypath", {}, "This is string data")
|
57
|
+
response = @connection.cfreq("PUT", "test.server.example", "/dummypath", "80", "http", {}, "This is string data")
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -63,32 +63,32 @@ class CloudfilesConnectionTest < Test::Unit::TestCase
|
|
63
63
|
require 'tempfile'
|
64
64
|
file = Tempfile.new("test")
|
65
65
|
assert_nothing_raised do
|
66
|
-
response = @connection.cfreq("PUT", "test.server.example", "/dummypath", {}, file)
|
66
|
+
response = @connection.cfreq("PUT", "test.server.example", "/dummypath", "80", "http", {}, file)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
def test_cfreq_head
|
71
71
|
build_net_http_object
|
72
72
|
assert_nothing_raised do
|
73
|
-
response = @connection.cfreq("HEAD", "test.server.example", "/dummypath")
|
73
|
+
response = @connection.cfreq("HEAD", "test.server.example", "/dummypath", "80", "http")
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
77
|
def test_net_http_raises_connection_exception
|
78
78
|
Net::HTTP.expects(:new).raises(ConnectionException)
|
79
79
|
assert_raises(ConnectionException) do
|
80
|
-
response = @connection.cfreq("GET", "test.server.example", "/dummypath")
|
80
|
+
response = @connection.cfreq("GET", "test.server.example", "/dummypath", "80", "http")
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
84
|
def test_net_http_raises_one_eof_exception
|
85
85
|
response = {'x-cdn-management-url' => 'http://cdn.example.com/path', 'x-storage-url' => 'http://cdn.example.com/storage', 'authtoken' => 'dummy_token'}
|
86
86
|
response.stubs(:code).returns('204')
|
87
|
-
server =
|
87
|
+
server = stub(:use_ssl= => true, :verify_mode= => true, :start => true, :finish => true)
|
88
88
|
server.stubs(:request).raises(EOFError).then.returns(response)
|
89
89
|
Net::HTTP.stubs(:new).returns(server)
|
90
90
|
assert_nothing_raised do
|
91
|
-
response = @connection.cfreq("GET", "test.server.example", "/dummypath")
|
91
|
+
response = @connection.cfreq("GET", "test.server.example", "/dummypath", "443", "https")
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
@@ -96,23 +96,23 @@ class CloudfilesConnectionTest < Test::Unit::TestCase
|
|
96
96
|
CloudFiles::Authentication.expects(:new).returns(true)
|
97
97
|
response = {'x-cdn-management-url' => 'http://cdn.example.com/path', 'x-storage-url' => 'http://cdn.example.com/storage', 'authtoken' => 'dummy_token'}
|
98
98
|
response.stubs(:code).returns('401').then.returns('204')
|
99
|
-
server =
|
99
|
+
server = stub(:use_ssl= => true, :verify_mode= => true, :start => true)
|
100
100
|
server.stubs(:request).returns(response)
|
101
101
|
Net::HTTP.stubs(:new).returns(server)
|
102
102
|
assert_nothing_raised do
|
103
|
-
response = @connection.cfreq("GET", "test.server.example", "/dummypath")
|
103
|
+
response = @connection.cfreq("GET", "test.server.example", "/dummypath", "80", "http")
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
107
|
def test_net_http_raises_continual_eof_exceptions
|
108
108
|
response = {'x-cdn-management-url' => 'http://cdn.example.com/path', 'x-storage-url' => 'http://cdn.example.com/storage', 'authtoken' => 'dummy_token'}
|
109
109
|
response.stubs(:code).returns('204')
|
110
|
-
server =
|
110
|
+
server = stub(:use_ssl= => true, :verify_mode= => true, :start => true)
|
111
111
|
server.stubs(:finish).returns(true)
|
112
112
|
server.stubs(:request).raises(EOFError)
|
113
113
|
Net::HTTP.stubs(:new).returns(server)
|
114
114
|
assert_raises(ConnectionException) do
|
115
|
-
response = @connection.cfreq("GET", "test.server.example", "/dummypath")
|
115
|
+
response = @connection.cfreq("GET", "test.server.example", "/dummypath", "80", "http")
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/test_helper'
|
|
3
3
|
class CloudfilesContainerTest < Test::Unit::TestCase
|
4
4
|
|
5
5
|
def test_object_creation
|
6
|
-
connection = mock(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path')
|
6
|
+
connection = mock(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
7
7
|
response = {'x-container-bytes-used' => '42', 'x-container-object-count' => '5'}
|
8
8
|
response.stubs(:code).returns('204')
|
9
9
|
connection.stubs(:cfreq => response)
|
@@ -16,7 +16,7 @@ class CloudfilesContainerTest < Test::Unit::TestCase
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def test_object_creation_no_such_container
|
19
|
-
connection = mock(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path')
|
19
|
+
connection = mock(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
20
20
|
response = {'x-container-bytes-used' => '42', 'x-container-object-count' => '5'}
|
21
21
|
response.stubs(:code).returns('999')
|
22
22
|
connection.stubs(:cfreq => response)
|
@@ -26,7 +26,7 @@ class CloudfilesContainerTest < Test::Unit::TestCase
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_object_creation_with_cdn
|
29
|
-
connection = mock(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path')
|
29
|
+
connection = mock(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
30
30
|
response = {'x-container-bytes-used' => '42', 'x-container-object-count' => '5', 'x-cdn-enabled' => 'True', 'x-cdn-uri' => 'http://cdn.test.example/container', 'x-ttl' => '86400'}
|
31
31
|
response.stubs(:code).returns('204')
|
32
32
|
connection.stubs(:cfreq => response)
|
@@ -72,7 +72,7 @@ class CloudfilesContainerTest < Test::Unit::TestCase
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def test_empty_is_false
|
75
|
-
connection = mock(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path')
|
75
|
+
connection = mock(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
76
76
|
response = {'x-container-bytes-used' => '42', 'x-container-object-count' => '5'}
|
77
77
|
response.stubs(:code).returns('204')
|
78
78
|
connection.stubs(:cfreq => response)
|
@@ -81,7 +81,7 @@ class CloudfilesContainerTest < Test::Unit::TestCase
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def test_empty_is_true
|
84
|
-
connection = mock(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path')
|
84
|
+
connection = mock(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
85
85
|
response = {'x-container-bytes-used' => '0', 'x-container-object-count' => '0'}
|
86
86
|
response.stubs(:code).returns('204')
|
87
87
|
connection.stubs(:cfreq => response)
|
@@ -89,6 +89,15 @@ class CloudfilesContainerTest < Test::Unit::TestCase
|
|
89
89
|
assert_equal @container.empty?, true
|
90
90
|
end
|
91
91
|
|
92
|
+
def test_log_retention_is_true
|
93
|
+
connection = mock(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
94
|
+
response = {'x-container-bytes-used' => '0', 'x-container-object-count' => '0', 'x-cdn-enabled' => 'True', 'x-log-retention' => 'True'}
|
95
|
+
response.stubs(:code).returns('204')
|
96
|
+
connection.stubs(:cfreq => response)
|
97
|
+
@container = CloudFiles::Container.new(connection, 'test_container')
|
98
|
+
assert_equal @container.log_retention?, true
|
99
|
+
end
|
100
|
+
|
92
101
|
def test_object_fetch
|
93
102
|
build_net_http_object(:code => '204', :response => {'last-modified' => 'Wed, 28 Jan 2009 16:16:26 GMT'})
|
94
103
|
object = @container.object('good_object')
|
@@ -166,26 +175,21 @@ class CloudfilesContainerTest < Test::Unit::TestCase
|
|
166
175
|
end
|
167
176
|
end
|
168
177
|
|
178
|
+
def test_setting_log_retention
|
179
|
+
build_net_http_object(:code => '201')
|
180
|
+
assert(@container.log_retention='false')
|
181
|
+
end
|
182
|
+
|
169
183
|
private
|
170
184
|
|
171
185
|
def build_net_http_object(args={:code => '204' })
|
172
186
|
CloudFiles::Container.any_instance.stubs(:populate).returns(true)
|
173
|
-
connection = stub(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path')
|
187
|
+
connection = stub(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
174
188
|
args[:response] = {} unless args[:response]
|
175
189
|
response = {'x-cdn-management-url' => 'http://cdn.example.com/path', 'x-storage-url' => 'http://cdn.example.com/storage', 'authtoken' => 'dummy_token', 'last-modified' => Time.now.to_s}.merge(args[:response])
|
176
190
|
response.stubs(:code).returns(args[:code])
|
177
191
|
response.stubs(:body).returns args[:body] || nil
|
178
192
|
connection.stubs(:cfreq => response)
|
179
|
-
#server = mock()
|
180
|
-
#server.stubs(:verify_mode= => true)
|
181
|
-
#server.stubs(:start => true)
|
182
|
-
#server.stubs(:use_ssl=).returns(true)
|
183
|
-
#server.stubs(:get).returns(response)
|
184
|
-
#server.stubs(:post).returns(response)
|
185
|
-
#server.stubs(:put).returns(response)
|
186
|
-
#server.stubs(:head).returns(response)
|
187
|
-
#server.stubs(:delete).returns(response)
|
188
|
-
#Net::HTTP.stubs(:new).returns(server)
|
189
193
|
@container = CloudFiles::Container.new(connection, 'test_container')
|
190
194
|
@container.stubs(:connection).returns(connection)
|
191
195
|
end
|
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/test_helper'
|
|
3
3
|
class CloudfilesStorageObjectTest < Test::Unit::TestCase
|
4
4
|
|
5
5
|
def test_object_creation
|
6
|
-
connection = stub(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path')
|
6
|
+
connection = stub(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
7
7
|
response = {'x-container-bytes-used' => '42', 'x-container-object-count' => '5', 'last-modified' => Time.now.to_s}
|
8
8
|
response.stubs(:code).returns('204')
|
9
9
|
connection.stubs(:cfreq => response)
|
@@ -15,7 +15,7 @@ class CloudfilesStorageObjectTest < Test::Unit::TestCase
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def test_object_creation_with_invalid_name
|
18
|
-
connection = stub(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path')
|
18
|
+
connection = stub(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
19
19
|
response = {'x-container-bytes-used' => '42', 'x-container-object-count' => '5', 'last-modified' => Time.now.to_s}
|
20
20
|
response.stubs(:code).returns('204')
|
21
21
|
connection.stubs(:cfreq => response)
|
@@ -41,6 +41,11 @@ class CloudfilesStorageObjectTest < Test::Unit::TestCase
|
|
41
41
|
assert_equal @object.data, 'This is good data'
|
42
42
|
end
|
43
43
|
|
44
|
+
def test_data_with_offset_succeeds
|
45
|
+
build_net_http_object(:code => '200', :body => 'Thi')
|
46
|
+
assert_equal @object.data(3), 'Thi'
|
47
|
+
end
|
48
|
+
|
44
49
|
def test_data_fails
|
45
50
|
build_net_http_object(:code => '999', :body => 'This is bad data')
|
46
51
|
assert_raise(NoSuchObjectException) do
|
@@ -58,6 +63,17 @@ class CloudfilesStorageObjectTest < Test::Unit::TestCase
|
|
58
63
|
end
|
59
64
|
end
|
60
65
|
|
66
|
+
def test_data_stream_with_offset_succeeds
|
67
|
+
build_net_http_object(:code => '200', :body => 'This ')
|
68
|
+
data = ""
|
69
|
+
assert_nothing_raised do
|
70
|
+
@object.data_stream(5) { |chunk|
|
71
|
+
data += chunk
|
72
|
+
}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Need to find a way to simulate this properly
|
61
77
|
def data_stream_fails
|
62
78
|
build_net_http_object(:code => '999', :body => 'This is bad data')
|
63
79
|
data = ""
|
@@ -90,6 +106,16 @@ class CloudfilesStorageObjectTest < Test::Unit::TestCase
|
|
90
106
|
end
|
91
107
|
end
|
92
108
|
|
109
|
+
def test_read_metadata_succeeds
|
110
|
+
connection = stub(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
111
|
+
response = {'x-container-bytes-used' => '42', 'x-container-object-count' => '5', 'x-object-meta-foo' => 'Bar', 'last-modified' => Time.now.to_s}
|
112
|
+
response.stubs(:code).returns('204')
|
113
|
+
connection.stubs(:cfreq => response)
|
114
|
+
container = CloudFiles::Container.new(connection, 'test_container')
|
115
|
+
@object = CloudFiles::StorageObject.new(container, 'test_object')
|
116
|
+
assert_equal @object.metadata, {'foo' => 'Bar'}
|
117
|
+
end
|
118
|
+
|
93
119
|
def test_write_succeeds
|
94
120
|
CloudFiles::StorageObject.any_instance.stubs(:populate).returns(true)
|
95
121
|
CloudFiles::Container.any_instance.stubs(:populate).returns(true)
|
@@ -99,6 +125,19 @@ class CloudfilesStorageObjectTest < Test::Unit::TestCase
|
|
99
125
|
end
|
100
126
|
end
|
101
127
|
|
128
|
+
def test_write_with_make_path
|
129
|
+
connection = stub(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
130
|
+
response = {'x-container-bytes-used' => '42', 'x-container-object-count' => '5', 'last-modified' => Time.now.to_s}
|
131
|
+
response.stubs(:code).returns('204').then.returns('204').then.returns('201').then.returns('204')
|
132
|
+
connection.stubs(:cfreq => response)
|
133
|
+
CloudFiles::Container.any_instance.stubs(:populate).returns(true)
|
134
|
+
container = CloudFiles::Container.new(connection, 'test_container')
|
135
|
+
@object = CloudFiles::StorageObject.new(container, 'path/to/my/test_object', false, true)
|
136
|
+
assert_nothing_raised do
|
137
|
+
@object.write("This is path test data")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
102
141
|
def test_load_from_filename_succeeds
|
103
142
|
require 'tempfile'
|
104
143
|
out = Tempfile.new('test')
|
@@ -153,7 +192,7 @@ class CloudfilesStorageObjectTest < Test::Unit::TestCase
|
|
153
192
|
|
154
193
|
def build_net_http_object(args={:code => '204' })
|
155
194
|
CloudFiles::Container.any_instance.stubs(:populate).returns(true)
|
156
|
-
connection = stub(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path')
|
195
|
+
connection = stub(:storagehost => 'test.storage.example', :storagepath => '/dummy/path', :storageport => 443, :storagescheme => 'https', :cdnmgmthost => 'cdm.test.example', :cdnmgmtpath => '/dummy/path', :cdnmgmtport => 443, :cdnmgmtscheme => 'https')
|
157
196
|
args[:response] = {} unless args[:response]
|
158
197
|
response = {'x-cdn-management-url' => 'http://cdn.example.com/path', 'x-storage-url' => 'http://cdn.example.com/storage', 'authtoken' => 'dummy_token', 'last-modified' => Time.now.to_s}.merge(args[:response])
|
159
198
|
response.stubs(:code).returns(args[:code])
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rackspace-cloudfiles
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- H. Wade Minter, Rackspace Hosting
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-08-08 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,7 +22,7 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: "1.0"
|
24
24
|
version:
|
25
|
-
description: A Ruby version of the
|
25
|
+
description: A Ruby version of the Rackspace Cloud Files API.
|
26
26
|
email: wade.minter@rackspace.com
|
27
27
|
executables: []
|
28
28
|
|
@@ -54,7 +54,7 @@ files:
|
|
54
54
|
- test/test_helper.rb
|
55
55
|
- TODO
|
56
56
|
has_rdoc: true
|
57
|
-
homepage: http://www.
|
57
|
+
homepage: http://www.rackspacecloud.com/cloud_hosting_products/files
|
58
58
|
licenses:
|
59
59
|
post_install_message:
|
60
60
|
rdoc_options:
|
@@ -84,7 +84,7 @@ rubyforge_project: cloudfiles
|
|
84
84
|
rubygems_version: 1.3.5
|
85
85
|
signing_key:
|
86
86
|
specification_version: 2
|
87
|
-
summary: A Ruby API into
|
87
|
+
summary: A Ruby API into Rackspace Cloud Files
|
88
88
|
test_files:
|
89
89
|
- test/cloudfiles_authentication_test.rb
|
90
90
|
- test/cloudfiles_connection_test.rb
|