Update http_route_controller.go
1. No longer create multiple matching rules for multiple http methods. Instead use regular expressions.
2. Create an additional route to handle the case where the path prefix is followed by a slash
@@ -493,12 +493,23 @@ func (r *HttpRouteReconcilerTask) BuildMatches(route *corev1alpha1.HttpRoute) []
)
for _, path := range spec.Paths {
- for _, method := range spec.Methods {
+ var methodRegexp strings.Builder
+ methodRegexp.WriteString("^(")
+
+ for i, method := range spec.Methods {
+ methodRegexp.WriteString(string(method))
+
+ if i < len(spec.Methods)-1 {
+ methodRegexp.WriteString("|")
+ }
+ }
+
+ methodRegexp.WriteString(")$")
match := &istioNetworkingV1Beta1.HTTPMatchRequest{
Method: &istioNetworkingV1Beta1.StringMatch{
- MatchType: &istioNetworkingV1Beta1.StringMatch_Exact{
- Exact: string(method),
+ MatchType: &istioNetworkingV1Beta1.StringMatch_Regex{
+ Regex: methodRegexp.String(),
},
},
}
@@ -507,18 +518,11 @@ func (r *HttpRouteReconcilerTask) BuildMatches(route *corev1alpha1.HttpRoute) []
for _, scheme := range spec.Schemes {
if scheme == "http" {
- //if spec.HttpRedirectToHttps {
- // match.Gateways = append(
- // match.Gateways,
- // HTTP_REDIRECT_GATEWAY_NAMESPACED_NAME.String(),
- // )
- //} else {
match.Gateways = append(
match.Gateways,
HTTP_GATEWAY_NAMESPACED_NAME.String(),
)
- //}
- } else {
+ } else if scheme == "https" {
match.Gateways = append(
match.Gateways,
HTTPS_GATEWAY_NAMESPACED_NAME.String(),
@@ -542,6 +546,24 @@ func (r *HttpRouteReconcilerTask) BuildMatches(route *corev1alpha1.HttpRoute) []
r.PatchConditionsToHttpMatch(match, spec)
res = append(res, match)
+
+ // Prevent double slash after strip path rewrite
+ // Assume we have a route that enabled strip path and has a path prefix with /bbbb
+ // Request #1 with path /bbbbaaaa will be rewritten to /aaaa, this is CORRECT
+ // Request #2 with path /bbbb/aaaa will be rewritten to //aaaa, which has double slashes and it is WRONG
+ // To solve this, add another route with path prefix /bbbb/
+ // Request #1 doesn't match this route. Skip
+ // Request #2 will be rewritten to /aaaa, which is correct.
+ if route.Spec.StripPath && path != "/" {
+ copyedMatch := match.DeepCopy()
+
+ copyedMatch.Uri = &istioNetworkingV1Beta1.StringMatch{
+ MatchType: &istioNetworkingV1Beta1.StringMatch_Prefix{
+ Prefix: path + "/",
+ },
+ }
+
+ res = append(res, copyedMatch)
}
}
