rackspace-cloudfiles 1.3.0.7 → 1.4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|