Add non regex pathPrefix
This commit is contained in:
parent
877770f7cf
commit
b23b2611b3
2 changed files with 87 additions and 2 deletions
|
@ -54,11 +54,32 @@ func (r *Rules) path(paths ...string) *mux.Route {
|
||||||
func (r *Rules) pathPrefix(paths ...string) *mux.Route {
|
func (r *Rules) pathPrefix(paths ...string) *mux.Route {
|
||||||
router := r.route.route.Subrouter()
|
router := r.route.route.Subrouter()
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
router.PathPrefix(strings.TrimSpace(path))
|
buildPath(path, router)
|
||||||
}
|
}
|
||||||
return r.route.route
|
return r.route.route
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildPath(path string, router *mux.Router) {
|
||||||
|
cleanPath := strings.TrimSpace(path)
|
||||||
|
// {} are used to define a regex pattern in http://www.gorillatoolkit.org/pkg/mux.
|
||||||
|
// if we find a { in the path, that means we use regex, then the gorilla/mux implementation is chosen
|
||||||
|
// otherwise, we use a lightweight implementation
|
||||||
|
if strings.Contains(cleanPath, "{") {
|
||||||
|
router.PathPrefix(cleanPath)
|
||||||
|
} else {
|
||||||
|
m := &prefixMatcher{prefix: cleanPath}
|
||||||
|
router.NewRoute().MatcherFunc(m.Match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type prefixMatcher struct {
|
||||||
|
prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *prefixMatcher) Match(r *http.Request, _ *mux.RouteMatch) bool {
|
||||||
|
return strings.HasPrefix(r.URL.Path, m.prefix) || strings.HasPrefix(r.URL.Path, m.prefix+"/")
|
||||||
|
}
|
||||||
|
|
||||||
type bySize []string
|
type bySize []string
|
||||||
|
|
||||||
func (a bySize) Len() int { return len(a) }
|
func (a bySize) Len() int { return len(a) }
|
||||||
|
@ -111,7 +132,7 @@ func (r *Rules) pathPrefixStrip(paths ...string) *mux.Route {
|
||||||
r.route.stripPrefixes = paths
|
r.route.stripPrefixes = paths
|
||||||
router := r.route.route.Subrouter()
|
router := r.route.route.Subrouter()
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
router.PathPrefix(strings.TrimSpace(path))
|
buildPath(path, router)
|
||||||
}
|
}
|
||||||
return r.route.route
|
return r.route.route
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,3 +192,67 @@ type fakeHandler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *fakeHandler) ServeHTTP(http.ResponseWriter, *http.Request) {}
|
func (h *fakeHandler) ServeHTTP(http.ResponseWriter, *http.Request) {}
|
||||||
|
|
||||||
|
func TestPathPrefix(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
path string
|
||||||
|
urls map[string]bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "leading slash",
|
||||||
|
path: "/bar",
|
||||||
|
urls: map[string]bool{
|
||||||
|
"http://foo.com/bar": true,
|
||||||
|
"http://foo.com/bar/": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "leading trailing slash",
|
||||||
|
path: "/bar/",
|
||||||
|
urls: map[string]bool{
|
||||||
|
"http://foo.com/bar": false,
|
||||||
|
"http://foo.com/bar/": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "no slash",
|
||||||
|
path: "bar",
|
||||||
|
urls: map[string]bool{
|
||||||
|
"http://foo.com/bar": false,
|
||||||
|
"http://foo.com/bar/": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "trailing slash",
|
||||||
|
path: "bar/",
|
||||||
|
urls: map[string]bool{
|
||||||
|
"http://foo.com/bar": false,
|
||||||
|
"http://foo.com/bar/": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
rls := &Rules{
|
||||||
|
route: &serverRoute{
|
||||||
|
route: &mux.Route{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
rt := rls.pathPrefix(test.path)
|
||||||
|
|
||||||
|
for testURL, expectedMatch := range test.urls {
|
||||||
|
req := testhelpers.MustNewRequest(http.MethodGet, testURL, nil)
|
||||||
|
match := rt.Match(req, &mux.RouteMatch{})
|
||||||
|
if match != expectedMatch {
|
||||||
|
t.Errorf("Error matching %s with %s, got %v expected %v", test.path, testURL, match, expectedMatch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue