Generate an ETag for a container's root
This commit is contained in:
parent
0e450c5e5c
commit
87741d002a
@ -4,6 +4,7 @@ require "cgi"
|
|||||||
require "active_support/core_ext/time/conversions"
|
require "active_support/core_ext/time/conversions"
|
||||||
require "active_support/core_ext/numeric/time"
|
require "active_support/core_ext/numeric/time"
|
||||||
require "redis"
|
require "redis"
|
||||||
|
require 'digest/md5'
|
||||||
|
|
||||||
module RemoteStorage
|
module RemoteStorage
|
||||||
class Swift
|
class Swift
|
||||||
@ -57,36 +58,47 @@ module RemoteStorage
|
|||||||
end
|
end
|
||||||
|
|
||||||
def get_head_directory_listing(user, directory)
|
def get_head_directory_listing(user, directory)
|
||||||
res = do_head_request("#{url_for_directory(user, directory)}/")
|
is_root_listing = directory.empty?
|
||||||
|
if is_root_listing
|
||||||
|
# We need to calculate the etag ourselves
|
||||||
|
res = do_get_request("#{url_for_directory(user, directory)}/?format=json")
|
||||||
|
etag = etag_for(res.body)
|
||||||
|
else
|
||||||
|
res = do_head_request("#{url_for_directory(user, directory)}/")
|
||||||
|
etag = res.headers[:etag]
|
||||||
|
end
|
||||||
|
|
||||||
server.headers["Content-Type"] = "application/json"
|
server.headers["Content-Type"] = "application/json"
|
||||||
server.headers["ETag"] = %Q("#{res.headers[:etag]}")
|
server.headers["ETag"] = %Q("#{etag}")
|
||||||
rescue RestClient::ResourceNotFound
|
rescue RestClient::ResourceNotFound
|
||||||
server.halt 404
|
server.halt 404
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_directory_listing(user, directory)
|
def get_directory_listing(user, directory)
|
||||||
server.headers["Content-Type"] = "application/json"
|
|
||||||
|
|
||||||
do_head_request("#{url_for_directory(user, directory)}/") do |response|
|
|
||||||
if response.code == 404
|
|
||||||
return directory_listing([]).to_json
|
|
||||||
else
|
|
||||||
server.headers["ETag"] = %Q("#{response.headers[:etag]}")
|
|
||||||
none_match = (server.env["HTTP_IF_NONE_MATCH"] || "").split(",").map(&:strip)
|
|
||||||
server.halt 304 if none_match.include? %Q("#{response.headers[:etag]}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
is_root_listing = directory.empty?
|
is_root_listing = directory.empty?
|
||||||
|
|
||||||
res = if is_root_listing
|
server.headers["Content-Type"] = "application/json"
|
||||||
do_get_request("#{container_url_for(user)}/?format=json")
|
|
||||||
else
|
|
||||||
do_get_request("#{container_url_for(user)}/?format=json&path=#{escape(directory)}/")
|
|
||||||
end
|
|
||||||
|
|
||||||
if body = JSON.parse(res.body)
|
etag, get_response = nil
|
||||||
|
|
||||||
|
do_head_request("#{url_for_directory(user, directory)}/") do |response|
|
||||||
|
return directory_listing([]).to_json if response.code == 404
|
||||||
|
|
||||||
|
if is_root_listing
|
||||||
|
get_response = do_get_request("#{container_url_for(user)}/?format=json")
|
||||||
|
etag = etag_for(get_response.body)
|
||||||
|
else
|
||||||
|
get_response = do_get_request("#{container_url_for(user)}/?format=json&path=#{escape(directory)}/")
|
||||||
|
etag = response.headers[:etag]
|
||||||
|
end
|
||||||
|
|
||||||
|
none_match = (server.env["HTTP_IF_NONE_MATCH"] || "").split(",").map(&:strip)
|
||||||
|
server.halt 304 if none_match.include? etag
|
||||||
|
end
|
||||||
|
|
||||||
|
server.headers["ETag"] = %Q("#{etag}")
|
||||||
|
|
||||||
|
if body = JSON.parse(get_response.body)
|
||||||
listing = directory_listing(body, is_root_listing)
|
listing = directory_listing(body, is_root_listing)
|
||||||
else
|
else
|
||||||
puts "listing not JSON"
|
puts "listing not JSON"
|
||||||
@ -328,5 +340,15 @@ module RemoteStorage
|
|||||||
def redis
|
def redis
|
||||||
@redis ||= Redis.new(host: settings.redis["host"], port: settings.redis["port"])
|
@redis ||= Redis.new(host: settings.redis["host"], port: settings.redis["port"])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def etag_for(body)
|
||||||
|
objects = JSON.parse(body)
|
||||||
|
|
||||||
|
if objects.empty?
|
||||||
|
Digest::MD5.hexdigest ''
|
||||||
|
else
|
||||||
|
Digest::MD5.hexdigest objects.map { |o| o["hash"] }.join
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user