diff --git a/pkg/muxer/http/matcher_v2.go b/pkg/muxer/http/matcher_v2.go index 72d5d826a..d87b8e41d 100644 --- a/pkg/muxer/http/matcher_v2.go +++ b/pkg/muxer/http/matcher_v2.go @@ -25,15 +25,21 @@ var httpFuncsV2 = map[string]func(*matchersTree, ...string) error{ } func pathV2(tree *matchersTree, paths ...string) error { + var routes []*mux.Route + for _, path := range paths { - if !strings.HasPrefix(path, "/") { - return fmt.Errorf("path %q does not start with a '/'", path) + route := mux.NewRouter().NewRoute() + + if err := route.Path(path).GetError(); err != nil { + return err } + + routes = append(routes, route) } tree.matcher = func(req *http.Request) bool { - for _, path := range paths { - if req.URL.Path == path { + for _, route := range routes { + if route.Match(req, &mux.RouteMatch{}) { return true } } @@ -45,15 +51,21 @@ func pathV2(tree *matchersTree, paths ...string) error { } func pathPrefixV2(tree *matchersTree, paths ...string) error { + var routes []*mux.Route + for _, path := range paths { - if !strings.HasPrefix(path, "/") { - return fmt.Errorf("path %q does not start with a '/'", path) + route := mux.NewRouter().NewRoute() + + if err := route.PathPrefix(path).GetError(); err != nil { + return err } + + routes = append(routes, route) } tree.matcher = func(req *http.Request) bool { - for _, path := range paths { - if strings.HasPrefix(req.URL.Path, path) { + for _, route := range routes { + if route.Match(req, &mux.RouteMatch{}) { return true } } diff --git a/pkg/muxer/http/matcher_v2_test.go b/pkg/muxer/http/matcher_v2_test.go index eac62a005..f8c381712 100644 --- a/pkg/muxer/http/matcher_v2_test.go +++ b/pkg/muxer/http/matcher_v2_test.go @@ -454,6 +454,18 @@ func TestPathV2Matcher(t *testing.T) { "https://example.com/css/main.css": http.StatusNotFound, }, }, + { + desc: "valid Path matcher with regexp", + rule: "Path(`/css{path:(/.*)?}`)", + expected: map[string]int{ + "https://example.com": http.StatusNotFound, + "https://example.com/css/main.css": http.StatusOK, + "https://example.org/css/main.css": http.StatusOK, + "https://example.com/css/components/component.css": http.StatusOK, + "https://example.com/css.css": http.StatusNotFound, + "https://example.com/js/main.js": http.StatusNotFound, + }, + }, } for _, test := range testCases { @@ -535,6 +547,18 @@ func TestPathPrefixV2Matcher(t *testing.T) { "https://example.com/css/main.css": http.StatusOK, }, }, + { + desc: "valid PathPrefix matcher with regexp", + rule: "PathPrefix(`/css-{name:[0-9]?}`)", + expected: map[string]int{ + "https://example.com": http.StatusNotFound, + "https://example.com/css-1/main.css": http.StatusOK, + "https://example.org/css-222/main.css": http.StatusOK, + "https://example.com/css-333333/components/component.css": http.StatusOK, + "https://example.com/css.css": http.StatusNotFound, + "https://example.com/js/main.js": http.StatusNotFound, + }, + }, } for _, test := range testCases {