Skip to content

Commit e04cc27

Browse files
authored
Prioritize method matching (#789)
Problem: A recent clarification in the gateway API stated that methods are prioritized higher than headers when matching. We were not abiding by this order. Solution: Check for methods to prioritize rules before we check headers.
1 parent 2db8d68 commit e04cc27

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

internal/state/dataplane/sort.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Precedence must be given to the Rule with the largest number of (Continuing on t
2424
- Characters in a matching non-wildcard hostname.
2525
- Characters in a matching hostname.
2626
- Characters in a matching path.
27+
- Method match.
2728
- Header matches.
2829
- Query param matches.
2930
@@ -43,16 +44,25 @@ func higherPriority(rule1, rule2 MatchRule) bool {
4344
match1 := rule1.GetMatch()
4445
match2 := rule2.GetMatch()
4546

46-
// If both matches exists then compare the number of header matches
47-
// The match with the largest number of header matches wins
47+
// Compare if a method exists on one of the matches but not the other.
48+
// The match with the method specified wins.
49+
if match1.Method != nil && match2.Method == nil {
50+
return true
51+
}
52+
if match2.Method != nil && match1.Method == nil {
53+
return false
54+
}
55+
56+
// Compare the number of header matches.
57+
// The match with the largest number of header matches wins.
4858
l1 := len(match1.Headers)
4959
l2 := len(match2.Headers)
5060

5161
if l1 != l2 {
5262
return l1 > l2
5363
}
54-
// If the number of headers is equal then compare the number of query param matches
55-
// The match with the most query param matches wins
64+
// If the number of headers is equal then compare the number of query param matches.
65+
// The match with the most query param matches wins.
5666
l1 = len(match1.QueryParams)
5767
l2 = len(match2.QueryParams)
5868

internal/state/dataplane/sort_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ func TestSort(t *testing.T) {
7777
},
7878
},
7979
}
80+
methodMatch := v1beta1.HTTPRouteMatch{
81+
Path: &v1beta1.HTTPPathMatch{
82+
Value: helpers.GetStringPointer("/path"),
83+
},
84+
Method: helpers.GetPointer(v1beta1.HTTPMethodPost),
85+
}
8086

8187
hr1 := v1beta1.HTTPRoute{
8288
ObjectMeta: metav1.ObjectMeta{
@@ -96,6 +102,7 @@ func TestSort(t *testing.T) {
96102
Matches: []v1beta1.HTTPRouteMatch{
97103
twoHeaderOneParamMatch, // tie decided on params
98104
threeHeaderMatch, // tie decided on headers
105+
methodMatch, // tie decided on method
99106
},
100107
},
101108
},
@@ -153,6 +160,11 @@ func TestSort(t *testing.T) {
153160
RuleIdx: 2,
154161
Source: &hr1,
155162
},
163+
{
164+
MatchIdx: 2, // methodMatch
165+
RuleIdx: 2,
166+
Source: &hr1,
167+
},
156168
{
157169
MatchIdx: 0, // twoHeaderMatch / later timestamp / test/hr2
158170
RuleIdx: 0,
@@ -166,6 +178,11 @@ func TestSort(t *testing.T) {
166178
}
167179

168180
sortedRoutes := []MatchRule{
181+
{
182+
MatchIdx: 2, // methodMatch
183+
RuleIdx: 2,
184+
Source: &hr1,
185+
},
169186
{
170187
MatchIdx: 1, // threeHeaderMatch
171188
RuleIdx: 2,

0 commit comments

Comments
 (0)