Skip to content

Commit d47437c

Browse files
authored
xds: Fix invert functionality for header matcher (#4902)
* Fix invert functionality for header matcher
1 parent 9fa2698 commit d47437c

File tree

5 files changed

+208
-102
lines changed

5 files changed

+208
-102
lines changed

internal/xds/matcher/matcher_header.go

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,14 @@ func mdValuesFromOutgoingCtx(md metadata.MD, key string) (string, bool) {
5050

5151
// HeaderExactMatcher matches on an exact match of the value of the header.
5252
type HeaderExactMatcher struct {
53-
key string
54-
exact string
53+
key string
54+
exact string
55+
invert bool
5556
}
5657

5758
// NewHeaderExactMatcher returns a new HeaderExactMatcher.
58-
func NewHeaderExactMatcher(key, exact string) *HeaderExactMatcher {
59-
return &HeaderExactMatcher{key: key, exact: exact}
59+
func NewHeaderExactMatcher(key, exact string, invert bool) *HeaderExactMatcher {
60+
return &HeaderExactMatcher{key: key, exact: exact, invert: invert}
6061
}
6162

6263
// Match returns whether the passed in HTTP Headers match according to the
@@ -66,7 +67,7 @@ func (hem *HeaderExactMatcher) Match(md metadata.MD) bool {
6667
if !ok {
6768
return false
6869
}
69-
return v == hem.exact
70+
return (v == hem.exact) != hem.invert
7071
}
7172

7273
func (hem *HeaderExactMatcher) String() string {
@@ -76,13 +77,14 @@ func (hem *HeaderExactMatcher) String() string {
7677
// HeaderRegexMatcher matches on whether the entire request header value matches
7778
// the regex.
7879
type HeaderRegexMatcher struct {
79-
key string
80-
re *regexp.Regexp
80+
key string
81+
re *regexp.Regexp
82+
invert bool
8183
}
8284

8385
// NewHeaderRegexMatcher returns a new HeaderRegexMatcher.
84-
func NewHeaderRegexMatcher(key string, re *regexp.Regexp) *HeaderRegexMatcher {
85-
return &HeaderRegexMatcher{key: key, re: re}
86+
func NewHeaderRegexMatcher(key string, re *regexp.Regexp, invert bool) *HeaderRegexMatcher {
87+
return &HeaderRegexMatcher{key: key, re: re, invert: invert}
8688
}
8789

8890
// Match returns whether the passed in HTTP Headers match according to the
@@ -92,7 +94,7 @@ func (hrm *HeaderRegexMatcher) Match(md metadata.MD) bool {
9294
if !ok {
9395
return false
9496
}
95-
return grpcutil.FullMatchWithRegex(hrm.re, v)
97+
return grpcutil.FullMatchWithRegex(hrm.re, v) != hrm.invert
9698
}
9799

98100
func (hrm *HeaderRegexMatcher) String() string {
@@ -104,11 +106,12 @@ func (hrm *HeaderRegexMatcher) String() string {
104106
type HeaderRangeMatcher struct {
105107
key string
106108
start, end int64 // represents [start, end).
109+
invert bool
107110
}
108111

109112
// NewHeaderRangeMatcher returns a new HeaderRangeMatcher.
110-
func NewHeaderRangeMatcher(key string, start, end int64) *HeaderRangeMatcher {
111-
return &HeaderRangeMatcher{key: key, start: start, end: end}
113+
func NewHeaderRangeMatcher(key string, start, end int64, invert bool) *HeaderRangeMatcher {
114+
return &HeaderRangeMatcher{key: key, start: start, end: end, invert: invert}
112115
}
113116

114117
// Match returns whether the passed in HTTP Headers match according to the
@@ -119,9 +122,9 @@ func (hrm *HeaderRangeMatcher) Match(md metadata.MD) bool {
119122
return false
120123
}
121124
if i, err := strconv.ParseInt(v, 10, 64); err == nil && i >= hrm.start && i < hrm.end {
122-
return true
125+
return !hrm.invert
123126
}
124-
return false
127+
return hrm.invert
125128
}
126129

127130
func (hrm *HeaderRangeMatcher) String() string {
@@ -136,15 +139,18 @@ type HeaderPresentMatcher struct {
136139
}
137140

138141
// NewHeaderPresentMatcher returns a new HeaderPresentMatcher.
139-
func NewHeaderPresentMatcher(key string, present bool) *HeaderPresentMatcher {
142+
func NewHeaderPresentMatcher(key string, present bool, invert bool) *HeaderPresentMatcher {
143+
if invert {
144+
present = !present
145+
}
140146
return &HeaderPresentMatcher{key: key, present: present}
141147
}
142148

143149
// Match returns whether the passed in HTTP Headers match according to the
144150
// HeaderPresentMatcher.
145151
func (hpm *HeaderPresentMatcher) Match(md metadata.MD) bool {
146152
vs, ok := mdValuesFromOutgoingCtx(md, hpm.key)
147-
present := ok && len(vs) > 0
153+
present := ok && len(vs) > 0 // TODO: Are we sure we need this len(vs) > 0?
148154
return present == hpm.present
149155
}
150156

@@ -157,11 +163,12 @@ func (hpm *HeaderPresentMatcher) String() string {
157163
type HeaderPrefixMatcher struct {
158164
key string
159165
prefix string
166+
invert bool
160167
}
161168

162169
// NewHeaderPrefixMatcher returns a new HeaderPrefixMatcher.
163-
func NewHeaderPrefixMatcher(key string, prefix string) *HeaderPrefixMatcher {
164-
return &HeaderPrefixMatcher{key: key, prefix: prefix}
170+
func NewHeaderPrefixMatcher(key string, prefix string, invert bool) *HeaderPrefixMatcher {
171+
return &HeaderPrefixMatcher{key: key, prefix: prefix, invert: invert}
165172
}
166173

167174
// Match returns whether the passed in HTTP Headers match according to the
@@ -171,7 +178,7 @@ func (hpm *HeaderPrefixMatcher) Match(md metadata.MD) bool {
171178
if !ok {
172179
return false
173180
}
174-
return strings.HasPrefix(v, hpm.prefix)
181+
return strings.HasPrefix(v, hpm.prefix) != hpm.invert
175182
}
176183

177184
func (hpm *HeaderPrefixMatcher) String() string {
@@ -183,11 +190,12 @@ func (hpm *HeaderPrefixMatcher) String() string {
183190
type HeaderSuffixMatcher struct {
184191
key string
185192
suffix string
193+
invert bool
186194
}
187195

188196
// NewHeaderSuffixMatcher returns a new HeaderSuffixMatcher.
189-
func NewHeaderSuffixMatcher(key string, suffix string) *HeaderSuffixMatcher {
190-
return &HeaderSuffixMatcher{key: key, suffix: suffix}
197+
func NewHeaderSuffixMatcher(key string, suffix string, invert bool) *HeaderSuffixMatcher {
198+
return &HeaderSuffixMatcher{key: key, suffix: suffix, invert: invert}
191199
}
192200

193201
// Match returns whether the passed in HTTP Headers match according to the
@@ -197,7 +205,7 @@ func (hsm *HeaderSuffixMatcher) Match(md metadata.MD) bool {
197205
if !ok {
198206
return false
199207
}
200-
return strings.HasSuffix(v, hsm.suffix)
208+
return strings.HasSuffix(v, hsm.suffix) != hsm.invert
201209
}
202210

203211
func (hsm *HeaderSuffixMatcher) String() string {
@@ -209,14 +217,15 @@ func (hsm *HeaderSuffixMatcher) String() string {
209217
type HeaderContainsMatcher struct {
210218
key string
211219
contains string
220+
invert bool
212221
}
213222

214223
// NewHeaderContainsMatcher returns a new HeaderContainsMatcher. key is the HTTP
215224
// Header key to match on, and contains is the value that the header should
216225
// should contain for a successful match. An empty contains string does not
217226
// work, use HeaderPresentMatcher in that case.
218-
func NewHeaderContainsMatcher(key string, contains string) *HeaderContainsMatcher {
219-
return &HeaderContainsMatcher{key: key, contains: contains}
227+
func NewHeaderContainsMatcher(key string, contains string, invert bool) *HeaderContainsMatcher {
228+
return &HeaderContainsMatcher{key: key, contains: contains, invert: invert}
220229
}
221230

222231
// Match returns whether the passed in HTTP Headers match according to the
@@ -226,29 +235,9 @@ func (hcm *HeaderContainsMatcher) Match(md metadata.MD) bool {
226235
if !ok {
227236
return false
228237
}
229-
return strings.Contains(v, hcm.contains)
238+
return strings.Contains(v, hcm.contains) != hcm.invert
230239
}
231240

232241
func (hcm *HeaderContainsMatcher) String() string {
233242
return fmt.Sprintf("headerContains:%v%v", hcm.key, hcm.contains)
234243
}
235-
236-
// InvertMatcher inverts the match result of the underlying header matcher.
237-
type InvertMatcher struct {
238-
m HeaderMatcher
239-
}
240-
241-
// NewInvertMatcher returns a new InvertMatcher.
242-
func NewInvertMatcher(m HeaderMatcher) *InvertMatcher {
243-
return &InvertMatcher{m: m}
244-
}
245-
246-
// Match returns whether the passed in HTTP Headers match according to the
247-
// InvertMatcher.
248-
func (i *InvertMatcher) Match(md metadata.MD) bool {
249-
return !i.m.Match(md)
250-
}
251-
252-
func (i *InvertMatcher) String() string {
253-
return fmt.Sprintf("invert{%s}", i.m)
254-
}

0 commit comments

Comments
 (0)