lib/cloudfiles/container.rb in cloudfiles-1.4.17 vs lib/cloudfiles/container.rb in cloudfiles-1.4.18

- old
+ new

@@ -14,20 +14,10 @@ # # Will likely not be called directly, instead use connection.container('container_name') to retrieve the object. def initialize(connection, name) @connection = connection @name = name - @storagehost = self.connection.storagehost - @storagepath = self.connection.storagepath + "/" + CloudFiles.escape(@name) - @storageport = self.connection.storageport - @storagescheme = self.connection.storagescheme - if self.connection.cdn_available? - @cdnmgmthost = self.connection.cdnmgmthost - @cdnmgmtpath = self.connection.cdnmgmtpath + "/" + CloudFiles.escape(@name) if self.connection.cdnmgmtpath - @cdnmgmtport = self.connection.cdnmgmtport - @cdnmgmtscheme = self.connection.cdnmgmtscheme - end # Load the metadata now, so we'll get a CloudFiles::Exception::NoSuchContainer exception should the container # not exist. self.container_metadata end @@ -49,30 +39,31 @@ alias :populate :refresh # Retrieves Metadata for the container def container_metadata @metadata ||= ( - response = self.connection.cfreq("HEAD", @storagehost, @storagepath + "/", @storageport, @storagescheme) + response = self.connection.storage_request("HEAD", "#{escaped_name}/") raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code =~ /^20/) resphash = {} response.to_hash.select { |k,v| k.match(/^x-container-meta/) }.each { |x| resphash[x[0]] = x[1].to_s } - {:bytes => response["x-container-bytes-used"].to_i, :count => response["x-container-object-count"].to_i, :metadata => resphash} + {: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"]} ) end # Retrieves CDN-Enabled Meta Data def cdn_metadata return @cdn_metadata if @cdn_metadata if cdn_available? @cdn_metadata = ( - response = self.connection.cfreq("HEAD", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme) + response = self.connection.cdn_request("HEAD", escaped_name) cdn_enabled = ((response["x-cdn-enabled"] || "").downcase == "true") ? true : false { :cdn_enabled => cdn_enabled, :cdn_ttl => cdn_enabled ? response["x-ttl"].to_i : nil, :cdn_url => cdn_enabled ? response["x-cdn-uri"] : nil, :cdn_ssl_url => cdn_enabled ? response["x-cdn-ssl-uri"] : nil, + :cdn_streaming_url => cdn_enabled ? response["x-cdn-streaming-uri"] : nil, :user_agent_acl => response["x-user-agent-acl"], :referrer_acl => response["x-referrer-acl"], :cdn_log => (cdn_enabled and response["x-log-retention"] == "True") ? true : false } ) @@ -98,24 +89,24 @@ # Throws NoSuchObjectException if the container doesn't exist. Throws InvalidResponseException if the request # fails. def set_metadata(metadatahash) headers = {} metadatahash.each{ |key, value| headers['X-Container-Meta-' + CloudFiles.escape(key.to_s.capitalize)] = value.to_s } - response = self.connection.cfreq("POST", @storagehost, @storagepath, @storageport, @storagescheme, headers) + response = self.connection.storage_request("POST", escaped_name, headers) raise CloudFiles::Exception::NoSuchObject, "Container #{@name} does not exist" if (response.code == "404") raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code =~ /^20/) true end # Size of the container (in bytes) def bytes - self.metadata[:bytes] + self.container_metadata[:bytes] end # Number of objects in the container def count - self.metadata[:count] + self.container_metadata[:count] end # Returns true if the container is public and CDN-enabled. Returns false otherwise. # # Aliased as container.public? @@ -143,10 +134,14 @@ # CDN SSL container URL (if container is public) def cdn_ssl_url self.cdn_metadata[:cdn_ssl_url] end + # CDN Streaming container URL (if container is public) + def cdn_ssl_url + self.cdn_metadata[:cdn_streaming_url] + end # The container ACL on the User Agent def user_agent_acl self.cdn_metadata[:user_agent_acl] end @@ -154,24 +149,34 @@ # The container ACL on the site Referrer def referrer_acl self.cdn_metadata[:referrer_acl] end + #used by openstack swift + def read_acl + self.container_metadata[:container_read] + end + + #used by openstack swift + def write_acl + self.container_metadata[:container_write] + end + # Returns true if log retention is enabled on this container, false otherwise def cdn_log self.cdn_metadata[:cdn_log] end alias :log_retention? :cdn_log alias :cdn_log? :cdn_log # Change the log retention status for this container. Values are true or false. # # These logs will be periodically (at unpredictable intervals) compressed and uploaded - # to a “.CDN_ACCESS_LOGS” container in the form of “container_name.YYYYMMDDHH-XXXX.gz”. + # to a ".CDN_ACCESS_LOGS" container in the form of "container_name.YYYYMMDDHH-XXXX.gz". def log_retention=(value) raise Exception::CDNNotAvailable unless cdn_available? - response = self.connection.cfreq("POST", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme, {"x-log-retention" => value.to_s.capitalize}) + response = self.connection.cdn_request("POST", escaped_name, {"x-log-retention" => value.to_s.capitalize}) raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "201" or response.code == "202") return true end @@ -214,11 +219,11 @@ params.each do |param, value| if [:limit, :marker, :prefix, :path, :delimiter].include? param query << "#{param}=#{CloudFiles.escape(value.to_s)}" end end - response = self.connection.cfreq("GET", @storagehost, "#{@storagepath}?#{query.join '&'}", @storageport, @storagescheme) + response = self.connection.storage_request("GET", "#{escaped_name}?#{query.join '&'}") return [] if (response.code == "204") raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "200") return CloudFiles.lines(response.body) end alias :list_objects :objects @@ -247,11 +252,11 @@ params.each do |param, value| if [:limit, :marker, :prefix, :path, :delimiter].include? param query << "#{param}=#{CloudFiles.escape(value.to_s)}" end end - response = self.connection.cfreq("GET", @storagehost, "#{@storagepath}?#{query.join '&'}", @storageport, @storagescheme) + response = self.connection.storage_request("GET", "#{escaped_name}?#{query.join '&'}") return {} if (response.code == "204") raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "200") doc = REXML::Document.new(response.body) detailhash = {} doc.elements.each("container/object") { |o| @@ -279,11 +284,11 @@ # => true # # container.object_exists?('badfile.txt') # => false def object_exists?(objectname) - response = self.connection.cfreq("HEAD", @storagehost, "#{@storagepath}/#{CloudFiles.escape objectname}", @storageport, @storagescheme) + response = self.connection.storage_request("HEAD", "#{escaped_name}/#{CloudFiles.escape objectname}") return (response.code =~ /^20/)? true : false end # Creates a new CloudFiles::StorageObject in the current container. # @@ -304,11 +309,11 @@ # => true # # container.delete_object('nonexistent_file.txt') # => NoSuchObjectException: Object nonexistent_file.txt does not exist def delete_object(objectname) - response = self.connection.cfreq("DELETE", @storagehost, "#{@storagepath}/#{CloudFiles.escape objectname}", @storageport, @storagescheme) + response = self.connection.storage_request("DELETE", "#{escaped_name}/#{CloudFiles.escape objectname}") raise CloudFiles::Exception::NoSuchObject, "Object #{objectname} does not exist" if (response.code == "404") raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code =~ /^20/) true end @@ -331,21 +336,47 @@ print "DEPRECATED: make_public takes a hash of options now, instead of a TTL number" ttl = options options = {:ttl => ttl} end - response = self.connection.cfreq("PUT", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme) + response = self.connection.cdn_request("PUT", escaped_name) raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202") headers = { "X-TTL" => options[:ttl].to_s , "X-CDN-Enabled" => "True" } headers["X-User-Agent-ACL"] = options[:user_agent_acl] if options[:user_agent_acl] headers["X-Referrer-ACL"] = options[:referrer_acl] if options[:referrer_acl] - response = self.connection.cfreq("POST", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme, headers) + response = post_with_headers(headers) raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202") refresh true end + + # Only to be used with openstack swift + def set_write_acl(write_string) + refresh + headers = {"X-Container-Write" => write_string} + post_with_headers(headers) + true + end + + # Only to be used with openstack swift + def set_read_acl(read_string) + refresh + headers = {"X-Container-Read" => read_string} + post_with_headers(headers) + true + end + + def post_with_headers(headers = {}) + if cdn_enabled? + response = self.connection.cdn_request("POST", escaped_name, headers) + else + response = self.connection.storage_request("POST", escaped_name, headers) + end + raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist (response code: #{response.code})" unless (response.code =~ /^20/) + response + end # Makes a container private and returns true upon success. Throws NoSuchContainerException # if the container doesn't exist or if the request fails. # # Note that if the container was previously public, it will continue to exist out on the CDN until it expires. @@ -353,11 +384,11 @@ # container.make_private # => true def make_private raise Exception::CDNNotAvailable unless cdn_available? headers = { "X-CDN-Enabled" => "False" } - response = self.connection.cfreq("POST", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme, headers) + response = self.connection.cdn_request("POST", escaped_name, headers) raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202") refresh true end @@ -378,26 +409,26 @@ # # container.purge_from_cdn("User@domain.com, User2@domain.com") # => true def purge_from_cdn(email=nil) raise Exception::CDNNotAvailable unless cdn_available? - if email - headers = {"X-Purge-Email" => email} - response = self.connection.cfreq("DELETE", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme, headers) - raise CloudFiles::Exception::Connection, "Error Unable to Purge Container: #{@name}" unless (response.code > "200" && response.code < "299") - else - response = self.connection.cfreq("DELETE", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme) - raise CloudFiles::Exception::Connection, "Error Unable to Purge Container: #{@name}" unless (response.code > "200" && response.code < "299") + headers = {} + headers = {"X-Purge-Email" => email} if email + response = self.connection.cdn_request("DELETE", escaped_name, headers) + raise CloudFiles::Exception::Connection, "Error Unable to Purge Container: #{@name}" unless (response.code > "200" && response.code < "299") true - end end def to_s # :nodoc: @name end def cdn_available? self.connection.cdn_available? + end + + def escaped_name + CloudFiles.escape(@name) end end end