cloudfiles 1.4.18 → 1.5.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.
@@ -30,7 +30,6 @@ module CloudFiles
30
30
  require 'digest/md5'
31
31
  require 'time'
32
32
  require 'rubygems'
33
- require 'mime/types'
34
33
 
35
34
  unless "".respond_to? :each_char
36
35
  require "jcode"
@@ -38,6 +37,7 @@ module CloudFiles
38
37
  end
39
38
 
40
39
  $:.unshift(File.dirname(__FILE__))
40
+ require 'client'
41
41
  require 'cloudfiles/version'
42
42
  require 'cloudfiles/exception'
43
43
  require 'cloudfiles/authentication'
@@ -8,54 +8,39 @@ module CloudFiles
8
8
  # cdmmgmtpath, storagehost, storagepath, authtoken, and authok variables on the connection. If it fails, it raises
9
9
  # an CloudFiles::Exception::Authentication exception.
10
10
  #
11
- # Should probably never be called directly.
11
+ # Should never be called directly.
12
12
  def initialize(connection)
13
- parsed_auth_url = URI.parse(connection.auth_url)
14
- path = parsed_auth_url.path
15
- hdrhash = { "X-Auth-User" => connection.authuser, "X-Auth-Key" => connection.authkey }
16
13
  begin
17
- server = get_server(connection, parsed_auth_url)
18
-
19
- if parsed_auth_url.scheme == "https"
20
- server.use_ssl = true
21
- server.verify_mode = OpenSSL::SSL::VERIFY_NONE
22
- end
23
- server.start
24
- rescue Exception => e
14
+ storage_url, auth_token, headers = SwiftClient.get_auth(connection.auth_url, connection.authuser, connection.authkey, connection.snet?)
15
+ rescue => e
25
16
  # uncomment if you suspect a problem with this branch of code
26
- # $stderr.puts "got error #{e.class}: #{e.message.inspect}\n" << e.traceback.map{|n| "\t#{n}"}.join("\n")
27
- raise CloudFiles::Exception::Connection, "Unable to connect to #{server.address}", caller
17
+ # $stderr.puts "got error #{e.class}: #{e.message.inspect}\n" << e.traceback.map{|n| "\t#{n}"}.join("\n")
18
+ raise CloudFiles::Exception::Connection, "Unable to connect to #{connection.auth_url}", caller
28
19
  end
29
- response = server.get(path, hdrhash)
30
- if (response.code =~ /^20./)
31
- if response["x-cdn-management-url"]
20
+ if auth_token
21
+ if headers["x-cdn-management-url"]
32
22
  connection.cdn_available = true
33
- parsed_cdn_url = URI.parse(response["x-cdn-management-url"])
23
+ parsed_cdn_url = URI.parse(headers["x-cdn-management-url"])
34
24
  connection.cdnmgmthost = parsed_cdn_url.host
35
25
  connection.cdnmgmtpath = parsed_cdn_url.path
36
26
  connection.cdnmgmtport = parsed_cdn_url.port
37
27
  connection.cdnmgmtscheme = parsed_cdn_url.scheme
38
28
  end
39
- parsed_storage_url = URI.parse(response["x-storage-url"])
29
+ parsed_storage_url = URI.parse(headers["x-storage-url"])
40
30
  connection.storagehost = set_snet(connection, parsed_storage_url.host)
41
31
  connection.storagepath = parsed_storage_url.path
42
32
  connection.storageport = parsed_storage_url.port
43
33
  connection.storagescheme = parsed_storage_url.scheme
44
- connection.authtoken = response["x-auth-token"]
34
+ connection.authtoken = headers["x-auth-token"]
45
35
  connection.authok = true
46
36
  else
47
37
  connection.authtoken = false
48
38
  raise CloudFiles::Exception::Authentication, "Authentication failed"
49
39
  end
50
- server.finish
51
40
  end
52
41
 
53
42
  private
54
43
 
55
- def get_server(connection, parsed_auth_url)
56
- Net::HTTP::Proxy(connection.proxy_host, connection.proxy_port).new(parsed_auth_url.host, parsed_auth_url.port)
57
- end
58
-
59
44
  def set_snet(connection, hostname)
60
45
  if connection.snet?
61
46
  "snet-#{hostname}"
@@ -132,12 +132,18 @@ module CloudFiles
132
132
  # => {:count=>8, :bytes=>42438527}
133
133
  # cf.bytes
134
134
  # => 42438527
135
+ # Hostname of the storage server
136
+
135
137
  def get_info
136
- response = storage_request("HEAD")
137
- raise CloudFiles::Exception::InvalidResponse, "Unable to obtain account size" unless (response.code == "204")
138
- @bytes = response["x-account-bytes-used"].to_i
139
- @count = response["x-account-container-count"].to_i
140
- {:bytes => @bytes, :count => @count}
138
+ begin
139
+ raise CloudFiles::Exception::AuthenticationException, "Not authenticated" unless self.authok?
140
+ response = SwiftClient.head_account(storageurl, self.authtoken)
141
+ @bytes = response["x-account-bytes-used"].to_i
142
+ @count = response["x-account-container-count"].to_i
143
+ {:bytes => @bytes, :count => @count}
144
+ rescue ClientException => e
145
+ raise CloudFiles::Exception::InvalidResponse, "Unable to obtain account size" unless (e.status.to_s == "204")
146
+ end
141
147
  end
142
148
 
143
149
  # The total size in bytes under this connection
@@ -162,14 +168,13 @@ module CloudFiles
162
168
  #
163
169
  # cf.containers(2,'cftest')
164
170
  # => ["test", "video"]
165
- def containers(limit = 0, marker = "")
166
- query = []
167
- query << "limit=#{CloudFiles.escape limit.to_s}" if limit.to_i > 0
168
- query << "marker=#{CloudFiles.escape marker.to_s}" unless marker.to_s.empty?
169
- response = storage_request("GET", "?#{query.join('&')}")
170
- return [] if (response.code == "204")
171
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "200")
172
- CloudFiles.lines(response.body)
171
+ def containers(limit = nil, marker = nil)
172
+ begin
173
+ response = SwiftClient.get_account(storageurl, self.authtoken, marker, limit)
174
+ response[1].collect{|c| c['name']}
175
+ rescue ClientException => e
176
+ raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{e.status.to_s}" unless (e.status.to_s == "200")
177
+ end
173
178
  end
174
179
  alias :list_containers :containers
175
180
 
@@ -183,20 +188,13 @@ module CloudFiles
183
188
  # cf.containers_detail
184
189
  # => { "container1" => { :bytes => "36543", :count => "146" },
185
190
  # "container2" => { :bytes => "105943", :count => "25" } }
186
- def containers_detail(limit = 0, marker = "")
187
- query = ['format=xml']
188
- query << "limit=#{CloudFiles.escape limit.to_s}" if limit.to_i > 0
189
- query << "marker=#{CloudFiles.escape marker.to_s}" unless marker.to_s.empty?
190
- response = storage_request("GET", "?#{query.join('&')}")
191
- return {} if (response.code == "204")
192
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "200")
193
- doc = REXML::Document.new(response.body)
194
- detailhash = {}
195
- doc.elements.each("account/container/") { |c|
196
- detailhash[c.elements["name"].text] = { :bytes => c.elements["bytes"].text, :count => c.elements["count"].text }
197
- }
198
- doc = nil
199
- return detailhash
191
+ def containers_detail(limit = nil, marker = nil)
192
+ begin
193
+ response = SwiftClient.get_account(storageurl, self.authtoken, marker, limit)
194
+ Hash[*response[1].collect{|c| [c['name'], {:bytes => c['bytes'], :count => c['count']}]}.flatten]
195
+ rescue ClientException => e
196
+ raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{e.status.to_s}" unless (e.status.to_s == "200")
197
+ end
200
198
  end
201
199
  alias :list_containers_info :containers_detail
202
200
 
@@ -208,14 +206,18 @@ module CloudFiles
208
206
  # cf.container_exists?('bad_container')
209
207
  # => false
210
208
  def container_exists?(containername)
211
- response = storage_request("HEAD", CloudFiles.escape(containername))
212
- return (response.code == "204")? true : false ;
209
+ begin
210
+ response = SwiftClient.head_container(storageurl, self.authtoken, containername)
211
+ true
212
+ rescue ClientException => e
213
+ false
214
+ end
213
215
  end
214
216
 
215
217
  # Creates a new container and returns the CloudFiles::Container object. Throws an InvalidResponseException if the
216
218
  # request fails.
217
219
  #
218
- # Slash (/) and question mark (?) are invalid characters, and will be stripped out. The container name is limited to
220
+ # "/" is not valid in a container name. The container name is limited to
219
221
  # 256 characters or less.
220
222
  #
221
223
  # container = cf.create_container('new_container')
@@ -223,13 +225,16 @@ module CloudFiles
223
225
  # => "new_container"
224
226
  #
225
227
  # container = cf.create_container('bad/name')
226
- # => SyntaxException: Container name cannot contain the characters '/' or '?'
228
+ # => SyntaxException: Container name cannot contain '/'
227
229
  def create_container(containername)
228
- raise CloudFiles::Exception::Syntax, "Container name cannot contain the characters '/' or '?'" if containername.match(/[\/\?]/)
230
+ raise CloudFiles::Exception::Syntax, "Container name cannot contain '/'" if containername.match("/")
229
231
  raise CloudFiles::Exception::Syntax, "Container name is limited to 256 characters" if containername.length > 256
230
- response = storage_request("PUT", CloudFiles.escape(containername))
231
- raise CloudFiles::Exception::InvalidResponse, "Unable to create container #{containername}" unless (response.code == "201" || response.code == "202")
232
- CloudFiles::Container.new(self, containername)
232
+ begin
233
+ SwiftClient.put_container(storageurl, self.authtoken, containername)
234
+ CloudFiles::Container.new(self, containername)
235
+ rescue ClientException => e
236
+ raise CloudFiles::Exception::InvalidResponse, "Unable to create container #{containername}" unless (e.status.to_s == "201" || e.status.to_s == "202")
237
+ end
233
238
  end
234
239
 
235
240
  # Deletes a container from the account. Throws a NonEmptyContainerException if the container still contains
@@ -244,9 +249,12 @@ module CloudFiles
244
249
  # cf.delete_container('nonexistent')
245
250
  # => NoSuchContainerException: Container nonexistent does not exist
246
251
  def delete_container(containername)
247
- response = storage_request("DELETE", CloudFiles.escape(containername))
248
- raise CloudFiles::Exception::NonEmptyContainer, "Container #{containername} is not empty" if (response.code == "409")
249
- raise CloudFiles::Exception::NoSuchContainer, "Container #{containername} does not exist" unless (response.code == "204")
252
+ begin
253
+ SwiftClient.delete_container(storageurl, self.authtoken, containername)
254
+ rescue ClientException => e
255
+ raise CloudFiles::Exception::NonEmptyContainer, "Container #{containername} is not empty" if (e.status.to_s == "409")
256
+ raise CloudFiles::Exception::NoSuchContainer, "Container #{containername} does not exist" unless (e.status.to_s == "204")
257
+ end
250
258
  true
251
259
  end
252
260
 
@@ -260,95 +268,19 @@ module CloudFiles
260
268
  # cf.public_containers
261
269
  # => ["video", "webpics"]
262
270
  def public_containers(enabled_only = false)
263
- paramstr = enabled_only == true ? "enabled_only=true" : ""
264
- response = cdn_request("GET", "?#{paramstr}")
265
- return [] if (response.code == "204")
266
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "200")
267
- CloudFiles.lines(response.body)
268
- end
269
-
270
- def storage_request(method, path = "", headers = {}, data = nil, attempts = 0, &block)
271
- path = "#{@storagepath}/#{path}" unless (path[0,1] == '/')
272
- cfreq(method, @storagehost, path, @storageport, @storagescheme, headers, data, attempts, &block)
273
- end
274
-
275
- def cdn_request(method, path = "", headers = {}, data = nil, attempts = 0, &block)
276
- path = "#{@cdnmgmtpath}/#{path}" unless (path[0,1] == '/')
277
- cfreq(method, @cdnmgmthost, path, @cdnmgmtport, @cdnmgmtscheme, headers, data, attempts, &block)
278
- end
279
-
280
- # This method actually makes the HTTP calls out to the server
281
- def cfreq(method, server, path, port, scheme, headers = {}, data = nil, attempts = 0, &block) # :nodoc:
282
- start = Time.now
283
- headers['Transfer-Encoding'] = "chunked" if data.respond_to?(:read)
284
- hdrhash = headerprep(headers)
285
- start_http(server, path, port, scheme, hdrhash)
286
- request = Net::HTTP.const_get(method.to_s.capitalize).new(path, hdrhash)
287
- data.rewind if data.respond_to?(:rewind)
288
- if data
289
- if data.respond_to?(:read)
290
- request.body_stream = data
291
- else
292
- request.body = data
293
- end
294
- unless data.is_a?(IO)
295
- request.content_length = data.respond_to?(:lstat) ? data.stat.size : data.size
296
- end
297
- else
298
- request.content_length = 0
299
- end
300
- response = @http[server].request(request, &block)
301
- raise CloudFiles::Exception::ExpiredAuthToken if response.code == "401"
302
- response
303
- rescue Errno::EPIPE, Timeout::Error, Errno::EINVAL, EOFError, IOError
304
- # Server closed the connection, retry
305
- if attempts >= 5
306
- host_str = server.respond_to?(:address) ? server.address : server
307
- raise CloudFiles::Exception::Connection, "Unable to reconnect to #{host_str} after #{attempts} attempts", caller
308
- end
309
-
310
- attempts += 1
311
271
  begin
312
- @http[server].finish
313
- rescue
314
- nil
272
+ response = SwiftClient.get_account(cdnurl, self.authtoken)
273
+ response[1].collect{|c| c['name']}
274
+ rescue ClientException => e
275
+ raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{e.status.to_s}" unless (e.status.to_s == "200")
315
276
  end
316
- start_http(server, path, port, scheme, headers)
317
- retry
318
- rescue ExpiredAuthTokenException
319
- raise CloudFiles::Exception::Connection, "Authentication token expired and you have requested not to retry", caller if @retry_auth == false
320
- CloudFiles::Authentication.new(self)
321
- retry
322
277
  end
323
-
324
- private
325
-
326
- # Sets up standard HTTP headers
327
- def headerprep(headers = {}) # :nodoc:
328
- default_headers = {}
329
- default_headers["X-Auth-Token"] = @authtoken if (authok? && @account.nil?)
330
- default_headers["X-Storage-Token"] = @authtoken if (authok? && !@account.nil?)
331
- default_headers["Connection"] = "Keep-Alive"
332
- default_headers["User-Agent"] = "CloudFiles Ruby API #{VERSION}"
333
- default_headers.merge(headers)
278
+
279
+ def storageurl
280
+ "#{self.storagescheme}://#{self.storagehost}:#{self.storageport.to_s}#{self.storagepath}"
334
281
  end
335
-
336
- # Starts (or restarts) the HTTP connection
337
- def start_http(server, path, port, scheme, headers) # :nodoc:
338
- if (@http[server].nil?)
339
- begin
340
- @http[server] = Net::HTTP::Proxy(self.proxy_host, self.proxy_port).new(server, port)
341
- if scheme == "https"
342
- @http[server].use_ssl = true
343
- @http[server].verify_mode = OpenSSL::SSL::VERIFY_NONE
344
- end
345
- @http[server].start
346
- rescue Exception
347
- raise CloudFiles::Exception::Connection, "Unable to connect to #{server.address}", caller
348
- end
349
- end
282
+ def cdnurl
283
+ "#{self.cdnmgmtscheme}://#{self.cdnmgmthost}:#{self.cdnmgmtport.to_s}#{self.cdnmgmtpath}"
350
284
  end
351
-
352
285
  end
353
-
354
286
  end
@@ -41,11 +41,14 @@ module CloudFiles
41
41
  # Retrieves Metadata for the container
42
42
  def container_metadata
43
43
  @metadata ||= (
44
- response = self.connection.storage_request("HEAD", "#{escaped_name}/")
45
- raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code =~ /^20/)
46
- resphash = {}
47
- response.to_hash.select { |k,v| k.match(/^x-container-meta/) }.each { |x| resphash[x[0]] = x[1].to_s }
48
- {:bytes => response["x-container-bytes-used"].to_i, :count => response["x-container-object-count"].to_i, :metadata => resphash, :container_read => response["x-container-read"], :container_write => response["x-container-write"]}
44
+ begin
45
+ response = SwiftClient.head_container(self.connection.storageurl, self.connection.authtoken, escaped_name)
46
+ resphash = {}
47
+ response.to_hash.select { |k,v| k.match(/^x-container-meta/) }.each { |x| resphash[x[0]] = x[1].to_s }
48
+ {:bytes => response["x-container-bytes-used"].to_i, :count => response["x-container-object-count"].to_i, :metadata => resphash, :container_read => response["x-container-read"], :container_write => response["x-container-write"]}
49
+ rescue ClientException => e
50
+ raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (e.status.to_s =~ /^20/)
51
+ end
49
52
  )
50
53
  end
51
54
 
@@ -54,18 +57,20 @@ module CloudFiles
54
57
  return @cdn_metadata if @cdn_metadata
55
58
  if cdn_available?
56
59
  @cdn_metadata = (
57
- response = self.connection.cdn_request("HEAD", escaped_name)
58
- cdn_enabled = ((response["x-cdn-enabled"] || "").downcase == "true") ? true : false
59
- {
60
- :cdn_enabled => cdn_enabled,
61
- :cdn_ttl => cdn_enabled ? response["x-ttl"].to_i : nil,
62
- :cdn_url => cdn_enabled ? response["x-cdn-uri"] : nil,
63
- :cdn_ssl_url => cdn_enabled ? response["x-cdn-ssl-uri"] : nil,
64
- :cdn_streaming_url => cdn_enabled ? response["x-cdn-streaming-uri"] : nil,
65
- :user_agent_acl => response["x-user-agent-acl"],
66
- :referrer_acl => response["x-referrer-acl"],
67
- :cdn_log => (cdn_enabled and response["x-log-retention"] == "True") ? true : false
68
- }
60
+ begin
61
+ response = SwiftClient.head_container(self.connection.cdnurl, self.connection.authtoken, escaped_name)
62
+ cdn_enabled = ((response["x-cdn-enabled"] || "").downcase == "true") ? true : false
63
+ {
64
+ :cdn_enabled => cdn_enabled,
65
+ :cdn_ttl => cdn_enabled ? response["x-ttl"].to_i : nil,
66
+ :cdn_url => cdn_enabled ? response["x-cdn-uri"] : nil,
67
+ :cdn_ssl_url => cdn_enabled ? response["x-cdn-ssl-uri"] : nil,
68
+ :cdn_streaming_url => cdn_enabled ? response["x-cdn-streaming-uri"] : nil,
69
+ :cdn_log => (cdn_enabled and response["x-log-retention"] == "True") ? true : false
70
+ }
71
+ rescue ClientException => e
72
+ raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (e.status.to_s =~ /^20/)
73
+ end
69
74
  )
70
75
  else
71
76
  @cdn_metadata = {}
@@ -91,10 +96,14 @@ module CloudFiles
91
96
  def set_metadata(metadatahash)
92
97
  headers = {}
93
98
  metadatahash.each{ |key, value| headers['X-Container-Meta-' + CloudFiles.escape(key.to_s.capitalize)] = value.to_s }
94
- response = self.connection.storage_request("POST", escaped_name, headers)
95
- raise CloudFiles::Exception::NoSuchObject, "Container #{@name} does not exist" if (response.code == "404")
96
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code =~ /^20/)
97
- true
99
+ begin
100
+ SwiftClient.post_container(self.connection.storageurl, self.connection.authtoken, escaped_name, headers)
101
+ self.refresh
102
+ true
103
+ rescue ClientException => e
104
+ raise CloudFiles::Exception::NoSuchObject, "Container #{@name} does not exist" if (e.status.to_s == "404")
105
+ raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{e.status}" unless (e.status.to_s =~ /^20/)
106
+ end
98
107
  end
99
108
 
100
109
  # Size of the container (in bytes)
@@ -136,21 +145,12 @@ module CloudFiles
136
145
  def cdn_ssl_url
137
146
  self.cdn_metadata[:cdn_ssl_url]
138
147
  end
148
+
139
149
  # CDN Streaming container URL (if container is public)
140
- def cdn_ssl_url
150
+ def cdn_streaming_url
141
151
  self.cdn_metadata[:cdn_streaming_url]
142
152
  end
143
153
 
144
- # The container ACL on the User Agent
145
- def user_agent_acl
146
- self.cdn_metadata[:user_agent_acl]
147
- end
148
-
149
- # The container ACL on the site Referrer
150
- def referrer_acl
151
- self.cdn_metadata[:referrer_acl]
152
- end
153
-
154
154
  #used by openstack swift
155
155
  def read_acl
156
156
  self.container_metadata[:container_read]
@@ -168,15 +168,19 @@ module CloudFiles
168
168
  alias :log_retention? :cdn_log
169
169
  alias :cdn_log? :cdn_log
170
170
 
171
+
171
172
  # Change the log retention status for this container. Values are true or false.
172
173
  #
173
174
  # These logs will be periodically (at unpredictable intervals) compressed and uploaded
174
175
  # to a ".CDN_ACCESS_LOGS" container in the form of "container_name.YYYYMMDDHH-XXXX.gz".
175
176
  def log_retention=(value)
176
177
  raise Exception::CDNNotAvailable unless cdn_available?
177
- response = self.connection.cdn_request("POST", escaped_name, {"x-log-retention" => value.to_s.capitalize})
178
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "201" or response.code == "202")
179
- return true
178
+ begin
179
+ SwiftClient.post_container(self.connection.cdnurl, self.connection.authtoken, escaped_name, {"x-log-retention" => value.to_s.capitalize})
180
+ true
181
+ rescue ClientException => e
182
+ raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{e.status}" unless (e.status.to_s == "201" or e.status.to_s == "202")
183
+ end
180
184
  end
181
185
 
182
186
 
@@ -221,10 +225,12 @@ module CloudFiles
221
225
  query << "#{param}=#{CloudFiles.escape(value.to_s)}"
222
226
  end
223
227
  end
224
- response = self.connection.storage_request("GET", "#{escaped_name}?#{query.join '&'}")
225
- return [] if (response.code == "204")
226
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "200")
227
- return CloudFiles.lines(response.body)
228
+ begin
229
+ response = SwiftClient.get_container(self.connection.storageurl, self.connection.authtoken, escaped_name, params[:marker], params[:limit], params[:prefix], params[:delimiter])
230
+ return response[1].collect{|o| o['name']}
231
+ rescue ClientException => e
232
+ raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{e.status}" unless (e.status.to_s == "200")
233
+ end
228
234
  end
229
235
  alias :list_objects :objects
230
236
 
@@ -254,16 +260,12 @@ module CloudFiles
254
260
  query << "#{param}=#{CloudFiles.escape(value.to_s)}"
255
261
  end
256
262
  end
257
- response = self.connection.storage_request("GET", "#{escaped_name}?#{query.join '&'}")
258
- return {} if (response.code == "204")
259
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "200")
260
- doc = REXML::Document.new(response.body)
261
- detailhash = {}
262
- doc.elements.each("container/object") { |o|
263
- detailhash[o.elements["name"].text] = { :bytes => o.elements["bytes"].text, :hash => o.elements["hash"].text, :content_type => o.elements["content_type"].text, :last_modified => DateTime.parse(o.elements["last_modified"].text) }
264
- }
265
- doc = nil
266
- return detailhash
263
+ begin
264
+ response = SwiftClient.get_container(self.connection.storageurl, self.connection.authtoken, escaped_name, params[:marker], params[:limit], params[:prefix], params[:delimiter])
265
+ return Hash[*response[1].collect{|o| [o['name'],{ :bytes => o["bytes"], :hash => o["hash"], :content_type => o["content_type"], :last_modified => DateTime.parse(o["last_modified"])}] }.flatten]
266
+ rescue ClientException => e
267
+ raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{e.status}" unless (e.status.to_s == "200")
268
+ end
267
269
  end
268
270
  alias :list_objects_info :objects_detail
269
271
 
@@ -286,8 +288,12 @@ module CloudFiles
286
288
  # container.object_exists?('badfile.txt')
287
289
  # => false
288
290
  def object_exists?(objectname)
289
- response = self.connection.storage_request("HEAD", "#{escaped_name}/#{CloudFiles.escape objectname}")
290
- return (response.code =~ /^20/)? true : false
291
+ begin
292
+ response = SwiftClient.head_object(self.connection.storageurl, self.connection.authtoken, escaped_name, objectname)
293
+ true
294
+ rescue ClientException => e
295
+ false
296
+ end
291
297
  end
292
298
 
293
299
  # Creates a new CloudFiles::StorageObject in the current container.
@@ -311,10 +317,13 @@ module CloudFiles
311
317
  # container.delete_object('nonexistent_file.txt')
312
318
  # => NoSuchObjectException: Object nonexistent_file.txt does not exist
313
319
  def delete_object(objectname)
314
- response = self.connection.storage_request("DELETE", "#{escaped_name}/#{CloudFiles.escape objectname}")
315
- raise CloudFiles::Exception::NoSuchObject, "Object #{objectname} does not exist" if (response.code == "404")
316
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code =~ /^20/)
317
- true
320
+ begin
321
+ SwiftClient.delete_object(self.connection.storageurl, self.connection.authtoken, escaped_name, objectname)
322
+ true
323
+ rescue ClientException => e
324
+ raise CloudFiles::Exception::NoSuchObject, "Object #{objectname} does not exist" if (e.status.to_s == "404")
325
+ raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{e.status}" unless (e.status.to_s =~ /^20/)
326
+ end
318
327
  end
319
328
 
320
329
  # Makes a container publicly available via the Cloud Files CDN and returns true upon success. Throws NoSuchContainerException
@@ -338,14 +347,17 @@ module CloudFiles
338
347
  options = {:ttl => ttl}
339
348
  end
340
349
 
341
- response = self.connection.cdn_request("PUT", escaped_name)
342
- raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202")
343
-
350
+ begin
351
+ SwiftClient.put_container(self.connection.cdnurl, self.connection.authtoken, escaped_name)
352
+ rescue ClientException => e
353
+ raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (e.status.to_s == "201" || e.status.to_s == "202")
354
+ end
344
355
  headers = { "X-TTL" => options[:ttl].to_s , "X-CDN-Enabled" => "True" }
345
356
  headers["X-User-Agent-ACL"] = options[:user_agent_acl] if options[:user_agent_acl]
346
357
  headers["X-Referrer-ACL"] = options[:referrer_acl] if options[:referrer_acl]
347
- response = post_with_headers(headers)
348
- raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202")
358
+
359
+ post_with_headers(headers)
360
+ # raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202")
349
361
  refresh
350
362
  true
351
363
  end
@@ -367,13 +379,11 @@ module CloudFiles
367
379
  end
368
380
 
369
381
  def post_with_headers(headers = {})
370
- if cdn_enabled?
371
- response = self.connection.cdn_request("POST", escaped_name, headers)
372
- else
373
- response = self.connection.storage_request("POST", escaped_name, headers)
382
+ begin
383
+ SwiftClient.post_container(cdn_enabled? ? self.connection.cdnurl : self.connection.storageurl, self.connection.authtoken, escaped_name, headers)
384
+ rescue ClientException => e
385
+ raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist (response code: #{e.status.to_s})" unless (e.status.to_s =~ /^20/)
374
386
  end
375
- raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist (response code: #{response.code})" unless (response.code =~ /^20/)
376
- response
377
387
  end
378
388
 
379
389
  # Makes a container private and returns true upon success. Throws NoSuchContainerException
@@ -386,10 +396,13 @@ module CloudFiles
386
396
  def make_private
387
397
  raise Exception::CDNNotAvailable unless cdn_available?
388
398
  headers = { "X-CDN-Enabled" => "False" }
389
- response = self.connection.cdn_request("POST", escaped_name, headers)
390
- raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202")
391
- refresh
392
- true
399
+ begin
400
+ SwiftClient.post_container(self.connection.cdnurl, self.connection.authtoken, escaped_name, headers)
401
+ refresh
402
+ true
403
+ rescue ClientException => e
404
+ raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (e.status.to_s == "201" || e.status.to_s == "202")
405
+ end
393
406
  end
394
407
 
395
408
  # Purges CDN Edge Cache for all objects inside of this container
@@ -413,9 +426,12 @@ module CloudFiles
413
426
  raise Exception::CDNNotAvailable unless cdn_available?
414
427
  headers = {}
415
428
  headers = {"X-Purge-Email" => email} if email
416
- response = self.connection.cdn_request("DELETE", escaped_name, headers)
417
- raise CloudFiles::Exception::Connection, "Error Unable to Purge Container: #{@name}" unless (response.code > "200" && response.code < "299")
418
- true
429
+ begin
430
+ SwiftClient.delete_container(self.connection.cdnurl, self.connection.authtoken, escaped_name, headers)
431
+ true
432
+ rescue ClientException => e
433
+ raise CloudFiles::Exception::Connection, "Error Unable to Purge Container: #{@name}" unless (e.status.to_s > "200" && e.status.to_s < "299")
434
+ end
419
435
  end
420
436
 
421
437
  def to_s # :nodoc: