From 316d8256673561b6a8adddc6b1ae7d682f6d345b Mon Sep 17 00:00:00 2001 From: Nicolas Goy Date: Wed, 26 Nov 2014 18:35:40 +0100 Subject: [PATCH] More operations --- lib/swift_storage/account.rb | 27 ++++++++++++++++++ lib/swift_storage/container.rb | 22 +++++++++++++++ lib/swift_storage/headers.rb | 4 +++ lib/swift_storage/node.rb | 12 +++++--- lib/swift_storage/object.rb | 50 ++++++++++++++++++++++++---------- lib/swift_storage/utils.rb | 4 +++ 6 files changed, 101 insertions(+), 18 deletions(-) diff --git a/lib/swift_storage/account.rb b/lib/swift_storage/account.rb index d53f473..cbb3ec3 100644 --- a/lib/swift_storage/account.rb +++ b/lib/swift_storage/account.rb @@ -3,6 +3,33 @@ class SwiftStorage::Account < SwiftStorage::Node parent_node :service + # Write account meta data + # + # @param temp_url_key [String] + # The shared secret used to sign temporary URLs. + # Changing this key will invalidate all temporary URLs signed with the older + # key. + # + def write(temp_url_key: nil) + h = {} + h[H::ACCOUNT_TEMP_URL_KEY] = temp_url_key if temp_url_key + + request(relative_path, :method => :post, :headers => h) + end + + # Returns the temporary URL key + # + # @return [String] + # Key used to sign temporary URLs + # + def temp_url_key + metadata.temp_url_key rescue nil + end + + def relative_path + '' + end + end diff --git a/lib/swift_storage/container.rb b/lib/swift_storage/container.rb index b54dd3e..2fcc8a9 100644 --- a/lib/swift_storage/container.rb +++ b/lib/swift_storage/container.rb @@ -15,5 +15,27 @@ def objects @objects ||= SwiftStorage::ObjectCollection.new(self) end + def create + request(relative_path, :method => :put) + end + + def write(write_acl: nil, read_acl: nil) + h = {} + read_acl = read_acl.join(',') if read_acl.respond_to?(:to_ary) + write_acl = write_acl.join(',') if write_acl.respond_to?(:to_ary) + + h[H::CONTAINER_READ] = read_acl + h[H::CONTAINER_WRITE] = write_acl + + request(relative_path, :method => :post, :headers => h) + end + + def acl + r = headers.read.split(',') rescue nil + w = headers.write.split(',') rescue nil + struct(:read => r, :write => w) + end + + end diff --git a/lib/swift_storage/headers.rb b/lib/swift_storage/headers.rb index 38ace05..c65fe2b 100644 --- a/lib/swift_storage/headers.rb +++ b/lib/swift_storage/headers.rb @@ -14,6 +14,10 @@ module Headers DELETE_AFTER = 'X-Delete-After'.freeze CACHE_CONTROL = 'Cache-Control'.freeze EXPIRES = 'Expires'.freeze + OBJECT_MANIFEST = 'X-Object-Manifest'.freeze + CONTAINER_READ = 'X-Container-Read'.freeze + CONTAINER_WRITE = 'X-Container-Write'.freeze + ACCOUNT_TEMP_URL_KEY = 'X-Account-Meta-Temp-URL-Key'.freeze end end diff --git a/lib/swift_storage/node.rb b/lib/swift_storage/node.rb index 134701e..e3263c7 100644 --- a/lib/swift_storage/node.rb +++ b/lib/swift_storage/node.rb @@ -82,10 +82,14 @@ def clear_cache @metadata = nil end - private - def struct(h) - return nil if h.empty? - Struct.new(*h.keys.map(&:to_sym)).new(*h.values) + def exists? + request(relative_path, :method => :head) && true + rescue SwiftStorage::Errors::NotFoundError + false + end + + def delete + request(relative_path, :method => :delete) end diff --git a/lib/swift_storage/object.rb b/lib/swift_storage/object.rb index 13bdd6d..bd81cda 100644 --- a/lib/swift_storage/object.rb +++ b/lib/swift_storage/object.rb @@ -6,15 +6,22 @@ # @attr [String] content_type # Content type of the Object, eg: `image/png`. # +# @attr [String] expires +# When the object is set to expire. +# +# @attr [String] cache_control +# Object cache control header. +# class SwiftStorage::Object < SwiftStorage::Node - include SwiftStorage parent_node :container header_attributes :content_length, - :content_type + :content_type, + :expires, + :cache_control # Read the object data # @@ -43,7 +50,10 @@ def read(output_stream=nil) # This will always make a request to the API server and will not use cache # # @note If you want to only update the metadata, you may omit `input_stream` - # but you must specify all other options otherwise they will be overwritten. + # but you must specify all other options otherwise they will be overwritten. + # + # @note Some headers specified here may not work with a specific swift server + # as they must be enabled in the server configuration. # # @param input_stream [String, IO] # The data to upload, if ommited, the write will not override the body and instead it will update @@ -71,6 +81,11 @@ def read(output_stream=nil) # @param expires [Time] # Set the Expires header. # + # @param object_manifest [String] + # When set, this object acts as a large object manifest. The value should be + # `/` where `` is the container the object + # segments are in and `` is the common prefix for all the segments. + # # @return [input_stream] # Return the `input_stream` argument, or `nil` if `input_stream` is ommited. # @@ -81,29 +96,33 @@ def write(input_stream=nil, delete_after: nil, cache_control: nil, expires: nil, + object_manifest: nil, metadata: nil) - h = { - Headers::CONTENT_DISPOSITION => attachment ? 'attachment' : 'inline' - } + h = {} input_stream.nil? or content_type or raise ArgumentError, 'Content_type is required if input_stream is given' - h[Headers::CONTENT_TYPE] = content_type if content_type + object_manifest.nil? or input_stream.nil? or raise ArgumentError, 'Input must be nil on object manigest' + + h[H::CONTENT_DISPOSITION] = attachment ? 'attachment' : 'inline' + h[H::OBJECT_MANIFEST] = object_manifest if object_manifest + h[H::CONTENT_TYPE] = content_type if content_type + h[H::EXPIRES] = expires.httpdate if expires + h[H::CACHE_CONTROL] = cache_control if cache_control if delete_at - h[Headers::DELETE_AT] = delete_at.to_i.to_s + h[H::DELETE_AT] = delete_at.to_i.to_s elsif delete_after - h[Headers::DELETE_AFTER] = delete_after.to_i.to_s + h[H::DELETE_AFTER] = delete_after.to_i.to_s end - h[Headers::EXPIRES] = expires.httpdate if expires - h[Headers::CACHE_CONTROL] = cache_control if cache_control - merge_metadata(h, metadata) + method = input_stream || object_manifest ? :put : :post + request(relative_path, - :method => (input_stream ? :put : :post), + :method => method, :headers => h, :input_stream => input_stream) clear_cache @@ -130,7 +149,7 @@ def temp_url(expires=nil, method: :get) # Returns the object's URL # - # @note This URL is unsigned and the container authorization will apply. If + # @note This URL is unsigneds and the container authorization will apply. If # the container do not allow public access, this URL will require an # authentication token. # @@ -142,6 +161,9 @@ def url end private + + H = SwiftStorage::Headers + def relative_path File.join(container.name, name) end diff --git a/lib/swift_storage/utils.rb b/lib/swift_storage/utils.rb index fd6094f..781d45f 100644 --- a/lib/swift_storage/utils.rb +++ b/lib/swift_storage/utils.rb @@ -15,5 +15,9 @@ def sig_to_hex(str) }.join end + def struct(h) + return nil if h.empty? + Struct.new(*h.keys.map(&:to_sym)).new(*h.values) + end end