Skip to content

Commit 504dfb0

Browse files
committed
Location regex should respect Exact paths
If a location is marked as Exact, and the ingress uses regex matching, the resulting location block should respect this.
1 parent d3ab5ef commit 504dfb0

File tree

4 files changed

+74
-7
lines changed

4 files changed

+74
-7
lines changed

internal/ingress/controller/template/template.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -526,14 +526,18 @@ func buildLocation(input interface{}, enforceRegex bool) string {
526526
}
527527

528528
path := location.Path
529-
if enforceRegex {
530-
return fmt.Sprintf(`~* "^%s"`, path)
531-
}
532529

533530
if location.PathType != nil && *location.PathType == networkingv1.PathTypeExact {
531+
if enforceRegex {
532+
return fmt.Sprintf(`~* "^%s$"`, path)
533+
}
534534
return fmt.Sprintf(`= %s`, path)
535535
}
536536

537+
if enforceRegex {
538+
return fmt.Sprintf(`~* "^%s"`, path)
539+
}
540+
537541
return path
538542
}
539543

internal/ingress/controller/template/template_test.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ var (
6767
XForwardedPrefix string
6868
SecureBackend bool
6969
enforceRegex bool
70+
pathType networking.PathType
7071
}{
7172
"when secure backend enabled": {
7273
"/",
@@ -78,6 +79,7 @@ var (
7879
"",
7980
true,
8081
false,
82+
networking.PathTypePrefix,
8183
},
8284
"when secure backend and dynamic config enabled": {
8385
"/",
@@ -89,6 +91,7 @@ var (
8991
"",
9092
true,
9193
false,
94+
networking.PathTypePrefix,
9295
},
9396
"when secure backend, stickiness and dynamic config enabled": {
9497
"/",
@@ -100,6 +103,7 @@ var (
100103
"",
101104
true,
102105
false,
106+
networking.PathTypePrefix,
103107
},
104108
"invalid redirect / to / with dynamic config enabled": {
105109
"/",
@@ -111,6 +115,7 @@ var (
111115
"",
112116
false,
113117
false,
118+
networking.PathTypePrefix,
114119
},
115120
"invalid redirect / to /": {
116121
"/",
@@ -122,6 +127,7 @@ var (
122127
"",
123128
false,
124129
false,
130+
networking.PathTypePrefix,
125131
},
126132
"redirect / to /jenkins": {
127133
"/",
@@ -137,6 +143,7 @@ proxy_pass $scheme://upstream_balancer;`,
137143
"",
138144
false,
139145
true,
146+
networking.PathTypePrefix,
140147
},
141148
"redirect / to /something with sticky enabled": {
142149
"/",
@@ -152,6 +159,7 @@ proxy_pass $scheme://upstream_balancer;`,
152159
"",
153160
false,
154161
true,
162+
networking.PathTypePrefix,
155163
},
156164
"redirect / to /something with sticky and dynamic config enabled": {
157165
"/",
@@ -167,6 +175,7 @@ proxy_pass $scheme://upstream_balancer;`,
167175
"",
168176
false,
169177
true,
178+
networking.PathTypePrefix,
170179
},
171180
"add the X-Forwarded-Prefix header": {
172181
"/there",
@@ -184,6 +193,7 @@ proxy_pass $scheme://upstream_balancer;`,
184193
"/there",
185194
false,
186195
true,
196+
networking.PathTypePrefix,
187197
},
188198
"use ~* location modifier when ingress does not use rewrite/regex target but at least one other ingress does": {
189199
"/something",
@@ -195,6 +205,19 @@ proxy_pass $scheme://upstream_balancer;`,
195205
"",
196206
false,
197207
true,
208+
networking.PathTypePrefix,
209+
},
210+
"exact paths should remain exact when enforce regex is enabled": {
211+
"/something",
212+
"/something",
213+
`~* "^/something$"`,
214+
"proxy_pass http://upstream_balancer;",
215+
"proxy_pass $scheme://upstream_balancer;",
216+
false,
217+
"",
218+
false,
219+
true,
220+
networking.PathTypeExact,
198221
},
199222
}
200223
)
@@ -319,7 +342,7 @@ func TestBuildLocation(t *testing.T) {
319342
for k, tc := range tmplFuncTestcases {
320343
loc := &ingress.Location{
321344
Path: tc.Path,
322-
PathType: &pathPrefix,
345+
PathType: &tc.pathType,
323346
Rewrite: rewrite.Config{Target: tc.Target},
324347
}
325348

test/e2e/annotations/rewrite.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ var _ = framework.DescribeAnnotation("rewrite-target use-regex enable-rewrite-lo
9898
f.WaitForNginxServer(host,
9999
func(server string) bool {
100100
return strings.Contains(server, `location ~* "^/" {`) &&
101-
strings.Contains(server, `location ~* "^/.well-known/acme/challenge" {`)
101+
strings.Contains(server, `location ~* "^/.well-known/acme/challenge$" {`)
102102
})
103103

104104
ginkgo.By("making a second request to the non-rewritten location")
@@ -132,7 +132,7 @@ var _ = framework.DescribeAnnotation("rewrite-target use-regex enable-rewrite-lo
132132

133133
f.WaitForNginxServer(host,
134134
func(server string) bool {
135-
return strings.Contains(server, `location ~* "^/foo" {`) &&
135+
return strings.Contains(server, `location ~* "^/foo$" {`) &&
136136
strings.Contains(server, `location ~* "^/foo.+" {`)
137137
})
138138

@@ -174,7 +174,7 @@ var _ = framework.DescribeAnnotation("rewrite-target use-regex enable-rewrite-lo
174174

175175
f.WaitForNginxServer(host,
176176
func(server string) bool {
177-
return strings.Contains(server, `location ~* "^/foo/bar/bar" {`) &&
177+
return strings.Contains(server, `location ~* "^/foo/bar/bar$" {`) &&
178178
strings.Contains(server, `location ~* "^/foo/bar/[a-z]{3}" {`)
179179
})
180180

test/e2e/ingress/pathtype_exact.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,44 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] exact", func() {
113113
assert.NotContains(ginkgo.GinkgoT(), body, "pathtype=exact")
114114
assert.NotContains(ginkgo.GinkgoT(), body, "duplicated=true")
115115
})
116+
117+
ginkgo.It("should respect exact type when using regex matching", func() {
118+
disableSnippet := f.AllowSnippetConfiguration()
119+
defer disableSnippet()
120+
121+
host := "exact.path"
122+
123+
annotations := map[string]string{
124+
"nginx.ingress.kubernetes.io/configuration-snippet": `more_set_input_headers "pathType: exact";`,
125+
"nginx.ingress.kubernetes.io/use-regex": "true",
126+
}
127+
128+
exactPathType := networking.PathTypeExact
129+
ing := framework.NewSingleIngress("exact", "/exact", host, f.Namespace, framework.EchoService, 80, annotations)
130+
ing.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].PathType = &exactPathType
131+
f.EnsureIngress(ing)
132+
133+
f.WaitForNginxServer(host,
134+
func(server string) bool {
135+
return strings.Contains(server, host) &&
136+
strings.Contains(server, `location ~* "^/exact$"`)
137+
})
138+
139+
body := f.HTTPTestClient().
140+
GET("/exact").
141+
WithHeader("Host", host).
142+
Expect().
143+
Status(http.StatusOK).
144+
Body().
145+
Raw()
146+
147+
assert.NotContains(ginkgo.GinkgoT(), body, "pathtype=prefix")
148+
assert.Contains(ginkgo.GinkgoT(), body, "pathtype=exact")
149+
150+
f.HTTPTestClient().
151+
GET("/exact/suffix").
152+
WithHeader("Host", host).
153+
Expect().
154+
Status(http.StatusNotFound)
155+
})
116156
})

0 commit comments

Comments
 (0)