From 483523b091be6717e918889aef4ce988d7dcbffa Mon Sep 17 00:00:00 2001 From: Garret Alfert Date: Fri, 2 Nov 2012 13:17:49 +0100 Subject: [PATCH] Allow binary content (fixes #18) --- config.yml.example | 2 ++ lib/remote_storage/riak.rb | 29 +++++++++++++++++++++++++++-- spec/directories_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/config.yml.example b/config.yml.example index a4069e4..b721a15 100644 --- a/config.yml.example +++ b/config.yml.example @@ -5,6 +5,7 @@ defaults: &defaults buckets: data: "user_data" directories: "rs_directories" + binaries: "rs_binaries" authorizations: "authorizations" development: @@ -15,6 +16,7 @@ test: buckets: data: "user_data_test" directories: "rs_directories_test" + binaries: "rs_binaries_test" authorizations: "authorizations_test" production: diff --git a/lib/remote_storage/riak.rb b/lib/remote_storage/riak.rb index 2df0b01..6a14dba 100644 --- a/lib/remote_storage/riak.rb +++ b/lib/remote_storage/riak.rb @@ -23,6 +23,10 @@ module RemoteStorage @auth_bucket ||= client.bucket(LiquorCabinet.config['buckets']['authorizations']) end + def binary_bucket + @binary_bucket ||= client.bucket(LiquorCabinet.config['buckets']['binaries']) + end + def authorize_request(user, directory, token, listing=false) request_method = env["REQUEST_METHOD"] @@ -47,6 +51,10 @@ module RemoteStorage headers["Content-Type"] = object.content_type headers["Last-Modified"] = last_modified_date_for(object) + if binary_link = object.links.select {|l| l.tag == "binary"}.first + object = client[binary_link.bucket].get(binary_link.key) + end + case object.content_type[/^[^;\s]+/] when "application/json" return object.data.to_json @@ -76,8 +84,10 @@ module RemoteStorage object = data_bucket.new("#{user}:#{directory}:#{key}") object.content_type = content_type || "text/plain; charset=utf-8" - unless set_object_data(object, data) - halt 422 + if binary_data?(content_type) + save_binary_data(object, data) or halt 422 + else + set_object_data(object, data) or halt 422 end directory_index = directory == "" ? "/" : directory @@ -279,6 +289,21 @@ module RemoteStorage return false end + def save_binary_data(object, data) + binary_object = binary_bucket.new(object.key) + binary_object.content_type = object.content_type + binary_object.raw_data = data + binary_object.store + + link = ::Riak::Link.new(binary_bucket.name, binary_object.key, "binary") + object.links << link + object.raw_data = "" + end + + def binary_data?(content_type) + content_type[/[^;\s]+$/] == "charset=binary" + end + def parent_directories_for(directory) directories = directory.split("/") parent_directories = [] diff --git a/spec/directories_spec.rb b/spec/directories_spec.rb index 2bdf549..a01c602 100644 --- a/spec/directories_spec.rb +++ b/spec/directories_spec.rb @@ -123,6 +123,26 @@ describe "Directories" do directory.data.to_i.must_equal object.meta['timestamp'][0].to_i end end + + context "with binary data" do + before do + header "Content-Type", "image/jpeg; charset=binary" + filename = File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", "rockrule.jpeg") + @image = File.open(filename, "r").read + put "/jimmy/tasks/jaypeg.jpg", @image + end + + it "lists the binary files" do + get "/jimmy/tasks/" + + last_response.status.must_equal 200 + + content = JSON.parse(last_response.body) + content.must_include "jaypeg.jpg" + content["jaypeg.jpg"].must_be_kind_of Integer + content["jaypeg.jpg"].to_s.length.must_equal 13 + end + end end context "for a sub-directory" do