diff --git a/lib/remote_storage/riak.rb b/lib/remote_storage/riak.rb index 3ab09ea..7ead0cd 100644 --- a/lib/remote_storage/riak.rb +++ b/lib/remote_storage/riak.rb @@ -91,7 +91,7 @@ module RemoteStorage timestamp = (Time.now.to_f * 1000).to_i object.meta["timestamp"] = timestamp - if binary_data?(content_type) + if binary_data?(object.content_type, data) save_binary_data(object, data) or halt 422 else set_object_data(object, data) or halt 422 @@ -309,8 +309,15 @@ module RemoteStorage object.raw_data = "" end - def binary_data?(content_type) - content_type[/[^;\s]+$/] == "charset=binary" + def binary_data?(content_type, data) + return true if content_type[/[^;\s]+$/] == "charset=binary" + + original_encoding = data.encoding + data.force_encoding("UTF-8") + is_binary = !data.valid_encoding? + data.force_encoding(original_encoding) + + is_binary end def parent_directories_for(directory) diff --git a/spec/directories_spec.rb b/spec/directories_spec.rb index c66a22d..60fdd34 100644 --- a/spec/directories_spec.rb +++ b/spec/directories_spec.rb @@ -125,22 +125,44 @@ describe "Directories" do 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 + context "charset given in content-type header" 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 - it "lists the binary files" do - get "/jimmy/tasks/" + context "no charset in content-type header" do + before do + header "Content-Type", "image/jpeg" + 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 - last_response.status.must_equal 200 + it "lists the binary files" do + get "/jimmy/tasks/" - 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 + 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 end diff --git a/spec/riak_spec.rb b/spec/riak_spec.rb index 82ec497..2bc5f80 100644 --- a/spec/riak_spec.rb +++ b/spec/riak_spec.rb @@ -185,33 +185,66 @@ describe "App with Riak backend" do 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/documents/jaypeg", @image + context "binary charset in content-type header" 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/documents/jaypeg", @image + end + + it "uses the requested content type" do + get "/jimmy/documents/jaypeg" + + last_response.status.must_equal 200 + last_response.content_type.must_equal "image/jpeg; charset=binary" + end + + it "delivers the data correctly" do + get "/jimmy/documents/jaypeg" + + last_response.status.must_equal 200 + last_response.body.must_equal @image + end + + it "indexes the binary set" do + indexes = binary_bucket.get("jimmy:documents:jaypeg").indexes + indexes["user_id_bin"].must_be_kind_of Set + indexes["user_id_bin"].must_include "jimmy" + + indexes["directory_bin"].must_include "documents" + end end - it "uses the requested content type" do - get "/jimmy/documents/jaypeg" + context "no binary charset in content-type header" do + before do + header "Content-Type", "image/jpeg" + filename = File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", "rockrule.jpeg") + @image = File.open(filename, "r").read + put "/jimmy/documents/jaypeg", @image + end - last_response.status.must_equal 200 - last_response.content_type.must_equal "image/jpeg; charset=binary" - end + it "uses the requested content type" do + get "/jimmy/documents/jaypeg" - it "delivers the data correctly" do - get "/jimmy/documents/jaypeg" + last_response.status.must_equal 200 + last_response.content_type.must_equal "image/jpeg" + end - last_response.status.must_equal 200 - last_response.body.must_equal @image - end + it "delivers the data correctly" do + get "/jimmy/documents/jaypeg" - it "indexes the binary set" do - indexes = binary_bucket.get("jimmy:documents:jaypeg").indexes - indexes["user_id_bin"].must_be_kind_of Set - indexes["user_id_bin"].must_include "jimmy" + last_response.status.must_equal 200 + last_response.body.must_equal @image + end - indexes["directory_bin"].must_include "documents" + it "indexes the binary set" do + indexes = binary_bucket.get("jimmy:documents:jaypeg").indexes + indexes["user_id_bin"].must_be_kind_of Set + indexes["user_id_bin"].must_include "jimmy" + + indexes["directory_bin"].must_include "documents" + end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 05aceed..7172168 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -43,7 +43,7 @@ def binary_bucket end def purge_all_buckets - [data_bucket, directory_bucket, auth_bucket].each do |bucket| + [data_bucket, directory_bucket, auth_bucket, binary_bucket].each do |bucket| bucket.keys.each {|key| bucket.delete key} end end