From 5dd1d26b202b7cfaf8d4661a8ff059353e60cb0e Mon Sep 17 00:00:00 2001 From: Garret Alfert Date: Fri, 9 Aug 2013 10:56:04 +0200 Subject: [PATCH] Set and check ETag headers --- lib/remote_storage/riak.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/remote_storage/riak.rb b/lib/remote_storage/riak.rb index 76afbf1..19c2035 100644 --- a/lib/remote_storage/riak.rb +++ b/lib/remote_storage/riak.rb @@ -40,8 +40,11 @@ module RemoteStorage def get_data(user, directory, key) object = data_bucket.get("#{user}:#{directory}:#{key}") + server.halt 304 if server.env["HTTP_IF_NONE_MATCH"] == object.etag + server.headers["Content-Type"] = object.content_type server.headers["Last-Modified"] = last_modified_date_for(object) + server.headers["ETag"] = object.etag if binary_key = object.meta["binary_key"] object = cs_binary_bucket.files.get(binary_key[0]) @@ -66,10 +69,14 @@ module RemoteStorage def get_directory_listing(user, directory) directory_object = directory_bucket.get("#{user}:#{directory}") + + server.halt 304 if server.env["HTTP_IF_NONE_MATCH"] == directory_object.etag + timestamp = directory_object.data.to_i timestamp /= 1000 if timestamp.to_s.length == 13 server.headers["Content-Type"] = "application/json" server.headers["Last-Modified"] = Time.at(timestamp).to_s(:rfc822) + server.headers["ETag"] = directory_object.etag listing = directory_listing(user, directory) @@ -81,6 +88,10 @@ module RemoteStorage def put_data(user, directory, key, data, content_type=nil) object = build_data_object(user, directory, key, data, content_type) + if required_match = server.env["HTTP_IF_MATCH"] + server.halt 412 unless required_match == object.etag + end + object_exists = !object.raw_data.nil? existing_object_size = object_size(object) @@ -102,6 +113,7 @@ module RemoteStorage update_all_directory_objects(user, directory, timestamp) + server.headers["ETag"] = object.etag server.halt 200 rescue ::Riak::HTTPFailedRequest server.halt 422 @@ -110,6 +122,11 @@ module RemoteStorage def delete_data(user, directory, key) object = data_bucket.get("#{user}:#{directory}:#{key}") existing_object_size = object_size(object) + etag = object.etag + + if match_requirement = server.env["HTTP_IF_MATCH"] + server.halt 412 unless match_requirement == etag + end if binary_key = object.meta["binary_key"] object = cs_binary_bucket.files.get(binary_key[0]) @@ -125,6 +142,7 @@ module RemoteStorage timestamp = (Time.now.to_f * 1000).to_i delete_or_update_directory_objects(user, directory, timestamp) + server.headers["ETag"] = etag server.halt riak_response[:code] rescue ::Riak::HTTPFailedRequest server.halt 404