diff --git a/internal/adc/translator/httproute.go b/internal/adc/translator/httproute.go index 4acabd31..fb6cf707 100644 --- a/internal/adc/translator/httproute.go +++ b/internal/adc/translator/httproute.go @@ -741,6 +741,10 @@ func (t *Translator) translateGatewayHTTPRouteMatch(match *gatewayv1.HTTPRouteMa }) route.Vars = append(route.Vars, this) + // APISIX Admin API requires uris to be a non-null array. Use "/*" + // as a catch-all so APISIX accepts the route; the vars entry above + // performs the actual regex filtering. + route.Uris = []string{"/*"} default: return nil, errors.New("unknown path match type " + string(*match.Path.Type)) } diff --git a/test/e2e/gatewayapi/httproute.go b/test/e2e/gatewayapi/httproute.go index 75197a29..e9432002 100644 --- a/test/e2e/gatewayapi/httproute.go +++ b/test/e2e/gatewayapi/httproute.go @@ -942,6 +942,60 @@ spec: }) }) + It("HTTPRoute RegularExpression Match", func() { + var regexRoute = fmt.Sprintf(` +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: httpbin +spec: + parentRefs: + - name: %s + hostnames: + - httpbin.example + rules: + - matches: + - path: + type: RegularExpression + value: /status/[0-9]+ + backendRefs: + - name: httpbin-service-e2e-test + port: 80 +`, s.Namespace()) + + By("create HTTPRoute with RegularExpression path type") + s.ResourceApplied("HTTPRoute", "httpbin", regexRoute, 1) + + By("access dataplane: path matching regex should succeed") + s.RequestAssert(&scaffold.RequestAssert{ + Method: "GET", + Path: "/status/200", + Host: "httpbin.example", + Check: scaffold.WithExpectedStatus(http.StatusOK), + Timeout: time.Second * 30, + Interval: time.Second * 2, + }) + + s.RequestAssert(&scaffold.RequestAssert{ + Method: "GET", + Path: "/status/201", + Host: "httpbin.example", + Check: scaffold.WithExpectedStatus(http.StatusCreated), + Timeout: time.Second * 30, + Interval: time.Second * 2, + }) + + By("access dataplane: path not matching regex should return 404") + s.RequestAssert(&scaffold.RequestAssert{ + Method: "GET", + Path: "/status/ok", + Host: "httpbin.example", + Check: scaffold.WithExpectedStatus(http.StatusNotFound), + Timeout: time.Second * 30, + Interval: time.Second * 2, + }) + }) + It("HTTPRoute Method Match", func() { By("create HTTPRoute") s.ResourceApplied("HTTPRoute", "httpbin", fmt.Sprintf(methodRouteGETAndDELETEByAnything, s.Namespace()), 1)