@@ -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 := createReturnAndRewriteConfigForRedirectFilter (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 createReturnAndRewriteConfigForRedirectFilter (
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
591643func 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