Skip to content

Commit 22ed925

Browse files
authored
Add #strong_match? and #weak_match? to ETags header. (#40)
1 parent 8b5b25f commit 22ed925

File tree

4 files changed

+52
-6
lines changed

4 files changed

+52
-6
lines changed

.mailmap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
Dan Olson <[email protected]>
1+
Dan Olson <[email protected]>
2+
Thomas Morgan <[email protected]>

lib/protocol/http/header/etags.rb

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,42 @@
22

33
# Released under the MIT License.
44
# Copyright, 2020-2023, by Samuel Williams.
5+
# Copyright, 2023, by Thomas Morgan.
56

67
require_relative 'split'
78

89
module Protocol
910
module HTTP
1011
module Header
11-
# This implementation is not strictly correct according to the RFC-specified format.
1212
class ETags < Split
1313
def wildcard?
1414
self.include?('*')
1515
end
1616

17+
# This implementation is not strictly correct according to the RFC-specified format.
1718
def match?(etag)
1819
wildcard? || self.include?(etag)
1920
end
21+
22+
# Useful with If-Match
23+
def strong_match?(etag)
24+
wildcard? || (!weak_tag?(etag) && self.include?(etag))
25+
end
26+
27+
# Useful with If-None-Match
28+
def weak_match?(etag)
29+
wildcard? || self.include?(etag) || self.include?(opposite_tag(etag))
30+
end
31+
32+
private
33+
34+
def opposite_tag(etag)
35+
weak_tag?(etag) ? etag[2..-1] : "W/#{etag}"
36+
end
37+
38+
def weak_tag?(tag)
39+
tag&.start_with? 'W/'
40+
end
2041
end
2142
end
2243
end

license.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Copyright, 2020-2023, by Bruno Sutic.
88
Copyright, 2022, by Herrick Fang.
99
Copyright, 2022, by Dan Olson.
1010
Copyright, 2023, by Genki Takiuchi.
11+
Copyright, 2023, by Thomas Morgan.
1112

1213
Permission is hereby granted, free of charge, to any person obtaining a copy
1314
of this software and associated documentation files (the "Software"), to deal

test/protocol/http/header/etags.rb

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# Released under the MIT License.
44
# Copyright, 2020-2023, by Samuel Williams.
5+
# Copyright, 2023, by Thomas Morgan.
56

67
require 'protocol/http/header/etags'
78

@@ -14,21 +15,43 @@
1415
end
1516

1617
it "matches anything" do
17-
expect(header).to be(:match?, "anything")
18+
expect(header).to be(:match?, '"anything"')
1819
end
1920
end
2021

21-
with "abcd" do
22+
with '"abcd"' do
2223
it "is not a wildcard" do
2324
expect(header).not.to be(:wildcard?)
2425
end
2526

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

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

0 commit comments

Comments
 (0)