Skip to content

Commit 1fef84e

Browse files
committed
etags: add strong and weak matchers
1 parent 8b5b25f commit 1fef84e

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

lib/protocol/http/header/etags.rb

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,32 @@
88
module Protocol
99
module HTTP
1010
module Header
11-
# This implementation is not strictly correct according to the RFC-specified format.
1211
class ETags < Split
1312
def wildcard?
1413
self.include?('*')
1514
end
1615

16+
# This implementation is not strictly correct according to the RFC-specified format.
1717
def match?(etag)
1818
wildcard? || self.include?(etag)
1919
end
20+
21+
# Useful with If-Match
22+
def strong_match?(etag)
23+
wildcard? || self.reject{|t| weak_tag?(t)}.include?(etag)
24+
end
25+
26+
# Useful with If-None-Match
27+
def weak_match?(etag)
28+
opposite_tag = weak_tag?(etag) ? etag[2..-1] : "W/#{etag}"
29+
wildcard? || self.include?(etag) || self.include?(opposite_tag)
30+
end
31+
32+
private
33+
34+
def weak_tag?(tag)
35+
tag&.start_with? 'W/'
36+
end
2037
end
2138
end
2239
end

test/protocol/http/header/etags.rb

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,43 @@
1414
end
1515

1616
it "matches anything" do
17-
expect(header).to be(:match?, "anything")
17+
expect(header).to be(:match?, '"anything"')
1818
end
1919
end
2020

21-
with "abcd" do
21+
with '"abcd"' do
2222
it "is not a wildcard" do
2323
expect(header).not.to be(:wildcard?)
2424
end
2525

2626
it "matches itself" do
27-
expect(header).to be(:match?, "abcd")
27+
expect(header).to be(:match?, '"abcd"')
28+
end
29+
30+
it "strongly matches only another strong etag" do
31+
expect(header).to be(:strong_match?, '"abcd"')
32+
expect(header).not.to be(:strong_match?, 'W/"abcd"')
33+
end
34+
35+
it "weakly matches both weak and strong etags" do
36+
expect(header).to be(:weak_match?, '"abcd"')
37+
expect(header).to be(:weak_match?, 'W/"abcd"')
2838
end
2939

3040
it "does not match anything else" do
31-
expect(header).not.to be(:match?, "anything else")
41+
expect(header).not.to be(:match?, '"anything else"')
42+
end
43+
end
44+
45+
with 'W/"abcd"' do
46+
it "never strongly matches" do
47+
expect(header).not.to be(:strong_match?, '"abcd"')
48+
expect(header).not.to be(:strong_match?, 'W/"abcd"')
49+
end
50+
51+
it "weakly matches both weak and strong etags" do
52+
expect(header).to be(:weak_match?, '"abcd"')
53+
expect(header).to be(:weak_match?, 'W/"abcd"')
3254
end
3355
end
3456
end

0 commit comments

Comments
 (0)