@@ -414,7 +414,7 @@ func initializeExternalLocations(
414414 }
415415 if ! exactPathExists {
416416 externalLocExact := http.Location {
417- Path : exactPath (externalLocPath ),
417+ Path : exactPath (rule . Path ),
418418 Type : locType ,
419419 }
420420 extLocations = append (extLocations , externalLocExact )
@@ -458,23 +458,22 @@ func updateLocation(
458458 mirrorPercentage * float64 ,
459459) http.Location {
460460 filters := matchRule .Filters
461- path := pathRule .Path
462461 grpc := pathRule .GRPC
463462
464463 if filters .InvalidFilter != nil {
465464 location .Return = & http.Return {Code : http .StatusInternalServerError }
466465 return location
467466 }
468467
469- location = updateLocationMirrorRoute (location , path , grpc )
468+ location = updateLocationMirrorRoute (location , pathRule . Path , grpc )
470469 location .Includes = append (location .Includes , createIncludesFromLocationSnippetsFilters (filters .SnippetsFilters )... )
471470
472471 if filters .RequestRedirect != nil {
473- return updateLocationRedirectFilter (location , filters .RequestRedirect , listenerPort , path )
472+ return updateLocationRedirectFilter (location , filters .RequestRedirect , listenerPort , pathRule )
474473 }
475474
476- location = updateLocationRewriteFilter (location , filters .RequestURLRewrite , path )
477- location = updateLocationMirrorFilters (location , filters .RequestMirrors , path , mirrorPercentage )
475+ location = updateLocationRewriteFilter (location , filters .RequestURLRewrite , pathRule )
476+ location = updateLocationMirrorFilters (location , filters .RequestMirrors , pathRule . Path , mirrorPercentage )
478477 location = updateLocationProxySettings (location , matchRule , grpc , keepAliveCheck )
479478
480479 return location
@@ -495,9 +494,9 @@ func updateLocationRedirectFilter(
495494 location http.Location ,
496495 redirectFilter * dataplane.HTTPRequestRedirectFilter ,
497496 listenerPort int32 ,
498- path string ,
497+ pathRule dataplane. PathRule ,
499498) http.Location {
500- ret , rewrite := createReturnAndRewriteConfigForRedirectFilter (redirectFilter , listenerPort , path )
499+ ret , rewrite := createReturnAndRewriteConfigForRedirectFilter (redirectFilter , listenerPort , pathRule )
501500 if rewrite .MainRewrite != "" {
502501 location .Rewrites = append (location .Rewrites , rewrite .MainRewrite )
503502 }
@@ -509,9 +508,9 @@ func updateLocationRedirectFilter(
509508func updateLocationRewriteFilter (
510509 location http.Location ,
511510 rewriteFilter * dataplane.HTTPURLRewriteFilter ,
512- path string ,
511+ pathRule dataplane. PathRule ,
513512) http.Location {
514- rewrites := createRewritesValForRewriteFilter (rewriteFilter , path )
513+ rewrites := createRewritesValForRewriteFilter (rewriteFilter , pathRule )
515514 if rewrites != nil {
516515 if location .Type == http .InternalLocationType && rewrites .InternalRewrite != "" {
517516 location .Rewrites = append (location .Rewrites , rewrites .InternalRewrite )
@@ -658,7 +657,7 @@ func createProxySSLVerify(v *dataplane.VerifyTLS) *http.ProxySSLVerify {
658657func createReturnAndRewriteConfigForRedirectFilter (
659658 filter * dataplane.HTTPRequestRedirectFilter ,
660659 listenerPort int32 ,
661- path string ,
660+ pathRule dataplane. PathRule ,
662661) (* http.Return , * rewriteConfig ) {
663662 if filter == nil {
664663 return nil , nil
@@ -702,7 +701,12 @@ func createReturnAndRewriteConfigForRedirectFilter(
702701
703702 rewrites := & rewriteConfig {}
704703 if filter .Path != nil {
705- rewrites .MainRewrite = createMainRewriteForFilters (filter .Path , path )
704+ mainRewrite := createMainRewriteForFilters (filter .Path , pathRule )
705+ if mainRewrite == "" {
706+ // Invalid configuration for the rewrite filter
707+ return nil , nil
708+ }
709+ rewrites .MainRewrite = mainRewrite
706710 body = fmt .Sprintf ("%s://%s$uri$is_args$args" , scheme , hostnamePort )
707711 }
708712
@@ -712,19 +716,26 @@ func createReturnAndRewriteConfigForRedirectFilter(
712716 }, rewrites
713717}
714718
715- func createMainRewriteForFilters (pathModifier * dataplane.HTTPPathModifier , path string ) string {
719+ func createMainRewriteForFilters (pathModifier * dataplane.HTTPPathModifier , pathRule dataplane. PathRule ) string {
716720 var mainRewrite string
717721 switch pathModifier .Type {
718722 case dataplane .ReplaceFullPath :
719723 mainRewrite = fmt .Sprintf ("^ %s" , pathModifier .Replacement )
720724 case dataplane .ReplacePrefixMatch :
725+ // ReplacePrefixMatch is only compatible with a PathPrefix HTTPRouteMatch.
726+ // ReplaceFullPath is compatible with PathTypeExact/PathTypePrefix/PathTypeRegularExpression HTTPRouteMatch.
727+ // see https://gateway-api.sigs.k8s.io/reference/spec/?h=replaceprefixmatch#httppathmodifier
728+ if pathRule .PathType != dataplane .PathTypePrefix {
729+ return ""
730+ }
731+
721732 filterPrefix := pathModifier .Replacement
722733 if filterPrefix == "" {
723734 filterPrefix = "/"
724735 }
725736
726737 // capture everything following the configured prefix up to the first ?, if present.
727- regex := fmt .Sprintf ("^%s([^?]*)?" , path )
738+ regex := fmt .Sprintf ("^%s([^?]*)?" , pathRule . Path )
728739 // replace the configured prefix with the filter prefix, append the captured segment,
729740 // and include the request arguments stored in nginx variable $args.
730741 // https://nginx.org/en/docs/http/ngx_http_core_module.html#var_args
@@ -733,13 +744,13 @@ func createMainRewriteForFilters(pathModifier *dataplane.HTTPPathModifier, path
733744 // if configured prefix does not end in /, but replacement prefix does end in /,
734745 // then make sure that we *require* but *don't capture* a trailing slash in the request,
735746 // otherwise we'll get duplicate slashes in the full replacement
736- if strings .HasSuffix (filterPrefix , "/" ) && ! strings .HasSuffix (path , "/" ) {
737- regex = fmt .Sprintf ("^%s(?:/([^?]*))?" , path )
747+ if strings .HasSuffix (filterPrefix , "/" ) && ! strings .HasSuffix (pathRule . Path , "/" ) {
748+ regex = fmt .Sprintf ("^%s(?:/([^?]*))?" , pathRule . Path )
738749 }
739750
740751 // if configured prefix ends in / we won't capture it for a request (since it's not in the regex),
741752 // so append it to the replacement prefix if the replacement prefix doesn't already end in /
742- if strings .HasSuffix (path , "/" ) && ! strings .HasSuffix (filterPrefix , "/" ) {
753+ if strings .HasSuffix (pathRule . Path , "/" ) && ! strings .HasSuffix (filterPrefix , "/" ) {
743754 replacement = fmt .Sprintf ("%s/$1?$args?" , filterPrefix )
744755 }
745756
@@ -749,7 +760,10 @@ func createMainRewriteForFilters(pathModifier *dataplane.HTTPPathModifier, path
749760 return mainRewrite
750761}
751762
752- func createRewritesValForRewriteFilter (filter * dataplane.HTTPURLRewriteFilter , path string ) * rewriteConfig {
763+ func createRewritesValForRewriteFilter (
764+ filter * dataplane.HTTPURLRewriteFilter ,
765+ pathRule dataplane.PathRule ,
766+ ) * rewriteConfig {
753767 if filter == nil {
754768 return nil
755769 }
@@ -758,8 +772,13 @@ func createRewritesValForRewriteFilter(filter *dataplane.HTTPURLRewriteFilter, p
758772 if filter .Path != nil {
759773 rewrites .InternalRewrite = "^ $request_uri"
760774
761- // for URLRewriteFilter, we add a break to the rewrite to prevent further processing of the request.
762- rewrites .MainRewrite = fmt .Sprintf ("%s break" , createMainRewriteForFilters (filter .Path , path ))
775+ mainRewrite := createMainRewriteForFilters (filter .Path , pathRule )
776+ if mainRewrite == "" {
777+ // Invalid configuration for the rewrite filter
778+ return nil
779+ }
780+ // For URLRewriteFilter, add "break" to prevent further processing of the request.
781+ rewrites .MainRewrite = fmt .Sprintf ("%s break" , mainRewrite )
763782 }
764783
765784 return rewrites
@@ -982,14 +1001,18 @@ func createPath(rule dataplane.PathRule) string {
9821001 switch rule .PathType {
9831002 case dataplane .PathTypeExact :
9841003 return exactPath (rule .Path )
1004+ case dataplane .PathTypePrefix :
1005+ return fmt .Sprintf ("^~ %s" , rule .Path )
1006+ case dataplane .PathTypeRegularExpression :
1007+ return fmt .Sprintf ("~ %s" , rule .Path )
9851008 default :
986- return rule .Path
1009+ panic ( fmt . Errorf ( "unknown path type %q for path %q" , rule .PathType , rule . Path ))
9871010 }
9881011}
9891012
9901013func createDefaultRootLocation () http.Location {
9911014 return http.Location {
992- Path : "/" ,
1015+ Path : "= /" ,
9931016 Return : & http.Return {Code : http .StatusNotFound },
9941017 }
9951018}
0 commit comments