Detect binary data even when content-type doesn't contain 'charset=binary'

This commit is contained in:
galfert 2012-11-04 19:29:54 +01:00
parent 44d276a387
commit e2095a34a6
4 changed files with 98 additions and 36 deletions

View File

@ -91,7 +91,7 @@ module RemoteStorage
timestamp = (Time.now.to_f * 1000).to_i timestamp = (Time.now.to_f * 1000).to_i
object.meta["timestamp"] = timestamp object.meta["timestamp"] = timestamp
if binary_data?(content_type) if binary_data?(object.content_type, data)
save_binary_data(object, data) or halt 422 save_binary_data(object, data) or halt 422
else else
set_object_data(object, data) or halt 422 set_object_data(object, data) or halt 422
@ -309,8 +309,15 @@ module RemoteStorage
object.raw_data = "" object.raw_data = ""
end end
def binary_data?(content_type) def binary_data?(content_type, data)
content_type[/[^;\s]+$/] == "charset=binary" 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 end
def parent_directories_for(directory) def parent_directories_for(directory)

View File

@ -125,22 +125,44 @@ describe "Directories" do
end end
context "with binary data" do context "with binary data" do
before do context "charset given in content-type header" do
header "Content-Type", "image/jpeg; charset=binary" before do
filename = File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", "rockrule.jpeg") header "Content-Type", "image/jpeg; charset=binary"
@image = File.open(filename, "r").read filename = File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", "rockrule.jpeg")
put "/jimmy/tasks/jaypeg.jpg", @image @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
it "lists the binary files" do context "no charset in content-type header" do
get "/jimmy/tasks/" 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) last_response.status.must_equal 200
content.must_include "jaypeg.jpg"
content["jaypeg.jpg"].must_be_kind_of Integer content = JSON.parse(last_response.body)
content["jaypeg.jpg"].to_s.length.must_equal 13 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 end
end end

View File

@ -185,33 +185,66 @@ describe "App with Riak backend" do
end end
context "with binary data" do context "with binary data" do
before do context "binary charset in content-type header" do
header "Content-Type", "image/jpeg; charset=binary" before do
filename = File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", "rockrule.jpeg") header "Content-Type", "image/jpeg; charset=binary"
@image = File.open(filename, "r").read filename = File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", "rockrule.jpeg")
put "/jimmy/documents/jaypeg", @image @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 end
it "uses the requested content type" do context "no binary charset in content-type header" do
get "/jimmy/documents/jaypeg" 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 it "uses the requested content type" do
last_response.content_type.must_equal "image/jpeg; charset=binary" get "/jimmy/documents/jaypeg"
end
it "delivers the data correctly" do last_response.status.must_equal 200
get "/jimmy/documents/jaypeg" last_response.content_type.must_equal "image/jpeg"
end
last_response.status.must_equal 200 it "delivers the data correctly" do
last_response.body.must_equal @image get "/jimmy/documents/jaypeg"
end
it "indexes the binary set" do last_response.status.must_equal 200
indexes = binary_bucket.get("jimmy:documents:jaypeg").indexes last_response.body.must_equal @image
indexes["user_id_bin"].must_be_kind_of Set end
indexes["user_id_bin"].must_include "jimmy"
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
end end

View File

@ -43,7 +43,7 @@ def binary_bucket
end end
def purge_all_buckets 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} bucket.keys.each {|key| bucket.delete key}
end end
end end