Ignore weak ETAG prefix when comparing MATCH headers

Our metadata only contains the actual ETAG value, so we need
to use only that when comparing it.
This commit is contained in:
Garret Alfert 2018-01-03 21:29:52 +01:00
parent abddec62de
commit 8ffd15bb61
2 changed files with 75 additions and 4 deletions

View File

@ -52,7 +52,7 @@ module RemoteStorage
set_response_headers(res)
none_match = (server.env["HTTP_IF_NONE_MATCH"] || "").split(",").map(&:strip)
none_match = (server.env["HTTP_IF_NONE_MATCH"] || "").gsub(/^W\//, "").split(",").map(&:strip)
server.halt 304 if none_match.include? %Q("#{res.headers[:etag]}")
return res.body
@ -71,7 +71,7 @@ module RemoteStorage
server.headers["Content-Type"] = "application/ld+json"
none_match = (server.env["HTTP_IF_NONE_MATCH"] || "").split(",").map(&:strip)
none_match = (server.env["HTTP_IF_NONE_MATCH"] || "").gsub(/^W\//, "").split(",").map(&:strip)
if etag
server.halt 304 if none_match.include? %Q("#{etag}")
@ -139,7 +139,9 @@ module RemoteStorage
url = url_for_key(user, directory, key)
if required_match = server.env["HTTP_IF_MATCH"]
server.halt 412, "Precondition Failed" unless required_match == %Q("#{existing_metadata["e"]}")
unless required_match.gsub(/^W\//, "") == %Q("#{existing_metadata["e"]}")
server.halt 412, "Precondition Failed"
end
end
if server.env["HTTP_IF_NONE_MATCH"] == "*"
server.halt 412, "Precondition Failed" unless existing_metadata.empty?
@ -185,7 +187,9 @@ module RemoteStorage
existing_metadata = redis.hgetall "rs:m:#{user}:#{directory}/#{key}"
if required_match = server.env["HTTP_IF_MATCH"]
server.halt 412, "Precondition Failed" unless required_match == %Q("#{existing_metadata["e"]}")
unless required_match.gsub(/^W\//, "") == %Q("#{existing_metadata["e"]}")
server.halt 412, "Precondition Failed"
end
end
begin

View File

@ -249,6 +249,22 @@ describe "App" do
last_response.headers["Etag"].must_equal "\"newetag\""
end
it "allows the request if the header contains a weak ETAG matching the current ETag" do
header "If-Match", "W/\"oldetag\""
put_stub = OpenStruct.new(headers: {
etag: "newetag",
last_modified: "Fri, 04 Mar 2016 12:20:18 GMT"
})
RestClient.stub :put, put_stub do
put "/phil/food/aguacate", "aye"
end
last_response.status.must_equal 200
last_response.headers["Etag"].must_equal "\"newetag\""
end
it "fails the request if the header does not match the current ETag" do
header "If-Match", "someotheretag"
@ -473,6 +489,16 @@ describe "App" do
last_response.status.must_equal 200
end
it "succeeds when the header contains a weak ETAG matching the current ETag" do
header "If-Match", "W/\"bla\""
RestClient.stub :delete, "" do
delete "/phil/food/aguacate"
end
last_response.status.must_equal 200
end
it "fails the request if it does not match the current ETag" do
header "If-Match", "someotheretag"
@ -562,6 +588,40 @@ describe "App" do
last_response.body.must_equal "Not Found"
end
it "responds with 304 when IF_NONE_MATCH header contains the ETag" do
header "If-None-Match", "\"0815etag\""
get_stub = OpenStruct.new(body: "si", headers: {
etag: "0815etag",
last_modified: "Fri, 04 Mar 2016 12:20:18 GMT",
content_type: "text/plain; charset=utf-8",
content_length: 2
})
RestClient.stub :get, get_stub do
get "/phil/food/aguacate"
end
last_response.status.must_equal 304
end
it "responds with 304 when IF_NONE_MATCH header contains weak ETAG matching the current ETag" do
header "If-None-Match", "W/\"0815etag\""
get_stub = OpenStruct.new(body: "si", headers: {
etag: "0815etag",
last_modified: "Fri, 04 Mar 2016 12:20:18 GMT",
content_type: "text/plain; charset=utf-8",
content_length: 2
})
RestClient.stub :get, get_stub do
get "/phil/food/aguacate"
end
last_response.status.must_equal 304
end
end
describe "directory listings" do
@ -587,6 +647,13 @@ describe "App" do
last_response.status.must_equal 304
end
it "responds with 304 when IF_NONE_MATCH header contains weak ETAG matching the ETag" do
header "If-None-Match", "W/\"f9f85fbf5aa1fa378fd79ac8aa0a457d\""
get "/phil/food/"
last_response.status.must_equal 304
end
it "contains all items in the directory" do
get "/phil/food/"