Skip to content

Commit 071a022

Browse files
committed
add path field for RequestRedirect Filter
1 parent 3683b58 commit 071a022

File tree

16 files changed

+764
-161
lines changed

16 files changed

+764
-161
lines changed

internal/mode/static/nginx/config/servers.go

+58-35
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,10 @@ func updateLocation(
435435
location.Includes = append(location.Includes, createIncludesFromLocationSnippetsFilters(filters.SnippetsFilters)...)
436436

437437
if filters.RequestRedirect != nil {
438-
ret := createReturnValForRedirectFilter(filters.RequestRedirect, listenerPort)
438+
ret, rewrite := createReturnValForRedirectFilter(filters.RequestRedirect, listenerPort, path)
439+
if rewrite.MainRewrite != "" {
440+
location.Rewrites = append(location.Rewrites, rewrite.MainRewrite)
441+
}
439442
location.Return = ret
440443
return location
441444
}
@@ -543,9 +546,13 @@ func createProxySSLVerify(v *dataplane.VerifyTLS) *http.ProxySSLVerify {
543546
}
544547
}
545548

546-
func createReturnValForRedirectFilter(filter *dataplane.HTTPRequestRedirectFilter, listenerPort int32) *http.Return {
549+
func createReturnValForRedirectFilter(
550+
filter *dataplane.HTTPRequestRedirectFilter,
551+
listenerPort int32,
552+
path string,
553+
) (*http.Return, *rewriteConfig) {
547554
if filter == nil {
548-
return nil
555+
return nil, nil
549556
}
550557

551558
hostname := "$host"
@@ -582,10 +589,55 @@ func createReturnValForRedirectFilter(filter *dataplane.HTTPRequestRedirectFilte
582589
}
583590
}
584591

592+
body := fmt.Sprintf("%s://%s$request_uri", scheme, hostnamePort)
593+
594+
rewrites := &rewriteConfig{}
595+
if filter.Path != nil {
596+
rewrites.MainRewrite = createMainRewriteForFilters(filter.Path, path)
597+
body = fmt.Sprintf("%s://%s$uri$is_args$args", scheme, hostnamePort)
598+
}
599+
585600
return &http.Return{
586601
Code: code,
587-
Body: fmt.Sprintf("%s://%s$request_uri", scheme, hostnamePort),
602+
Body: body,
603+
}, rewrites
604+
}
605+
606+
func createMainRewriteForFilters(pathModifier *dataplane.HTTPPathModifier, path string) string {
607+
var mainRewrite string
608+
switch pathModifier.Type {
609+
case dataplane.ReplaceFullPath:
610+
mainRewrite = fmt.Sprintf("^ %s", pathModifier.Replacement)
611+
case dataplane.ReplacePrefixMatch:
612+
filterPrefix := pathModifier.Replacement
613+
if filterPrefix == "" {
614+
filterPrefix = "/"
615+
}
616+
617+
// capture everything following the configured prefix up to the first ?, if present.
618+
regex := fmt.Sprintf("^%s([^?]*)?", path)
619+
// replace the configured prefix with the filter prefix, append the captured segment,
620+
// and include the request arguments stored in nginx variable $args.
621+
// https://nginx.org/en/docs/http/ngx_http_core_module.html#var_args
622+
replacement := fmt.Sprintf("%s$1?$args?", filterPrefix)
623+
624+
// if configured prefix does not end in /, but replacement prefix does end in /,
625+
// then make sure that we *require* but *don't capture* a trailing slash in the request,
626+
// otherwise we'll get duplicate slashes in the full replacement
627+
if strings.HasSuffix(filterPrefix, "/") && !strings.HasSuffix(path, "/") {
628+
regex = fmt.Sprintf("^%s(?:/([^?]*))?", path)
629+
}
630+
631+
// if configured prefix ends in / we won't capture it for a request (since it's not in the regex),
632+
// so append it to the replacement prefix if the replacement prefix doesn't already end in /
633+
if strings.HasSuffix(path, "/") && !strings.HasSuffix(filterPrefix, "/") {
634+
replacement = fmt.Sprintf("%s/$1?$args?", filterPrefix)
635+
}
636+
637+
mainRewrite = fmt.Sprintf("%s %s", regex, replacement)
588638
}
639+
640+
return mainRewrite
589641
}
590642

591643
func createRewritesValForRewriteFilter(filter *dataplane.HTTPURLRewriteFilter, path string) *rewriteConfig {
@@ -594,40 +646,11 @@ func createRewritesValForRewriteFilter(filter *dataplane.HTTPURLRewriteFilter, p
594646
}
595647

596648
rewrites := &rewriteConfig{}
597-
598649
if filter.Path != nil {
599650
rewrites.InternalRewrite = "^ $request_uri"
600-
switch filter.Path.Type {
601-
case dataplane.ReplaceFullPath:
602-
rewrites.MainRewrite = fmt.Sprintf("^ %s break", filter.Path.Replacement)
603-
case dataplane.ReplacePrefixMatch:
604-
filterPrefix := filter.Path.Replacement
605-
if filterPrefix == "" {
606-
filterPrefix = "/"
607-
}
608651

609-
// capture everything following the configured prefix up to the first ?, if present.
610-
regex := fmt.Sprintf("^%s([^?]*)?", path)
611-
// replace the configured prefix with the filter prefix, append the captured segment,
612-
// and include the request arguments stored in nginx variable $args.
613-
// https://nginx.org/en/docs/http/ngx_http_core_module.html#var_args
614-
replacement := fmt.Sprintf("%s$1?$args?", filterPrefix)
615-
616-
// if configured prefix does not end in /, but replacement prefix does end in /,
617-
// then make sure that we *require* but *don't capture* a trailing slash in the request,
618-
// otherwise we'll get duplicate slashes in the full replacement
619-
if strings.HasSuffix(filterPrefix, "/") && !strings.HasSuffix(path, "/") {
620-
regex = fmt.Sprintf("^%s(?:/([^?]*))?", path)
621-
}
622-
623-
// if configured prefix ends in / we won't capture it for a request (since it's not in the regex),
624-
// so append it to the replacement prefix if the replacement prefix doesn't already end in /
625-
if strings.HasSuffix(path, "/") && !strings.HasSuffix(filterPrefix, "/") {
626-
replacement = fmt.Sprintf("%s/$1?$args?", filterPrefix)
627-
}
628-
629-
rewrites.MainRewrite = fmt.Sprintf("%s %s break", regex, replacement)
630-
}
652+
// for URLRewriteFilter, we add a break to the rewrite to prevent further processing of the request.
653+
rewrites.MainRewrite = fmt.Sprintf("%s break", createMainRewriteForFilters(filter.Path, path))
631654
}
632655

633656
return rewrites

0 commit comments

Comments
 (0)