diff --git a/path.go b/path.go index 3609caa8..c44f058a 100644 --- a/path.go +++ b/path.go @@ -287,6 +287,11 @@ func findParamLen(s string, segment *routeSegment) int { return constPosition } } else if constPosition := strings.Index(s, segment.ComparePart); constPosition != -1 { + // if the compare part was found, but contains a slash although this part is not greedy, then it must not match + // example: /api/:param/fixedEnd -> path: /api/123/456/fixedEnd = no match , /api/123/fixedEnd = match + if !segment.IsGreedy && strings.IndexByte(s[:constPosition], slashDelimiter) != -1 { + return 0 + } return constPosition } diff --git a/path_test.go b/path_test.go index 3d401ed3..8cc6cc05 100644 --- a/path_test.go +++ b/path_test.go @@ -183,6 +183,10 @@ func Test_Path_matchParams(t *testing.T) { {url: "/api/v1/", params: nil, match: false}, {url: "/api/v1/something", params: nil, match: false}, }) + testCase("/api/:param/fixedEnd", []testparams{ + {url: "/api/abc/fixedEnd", params: []string{"abc"}, match: true}, + {url: "/api/abc/def/fixedEnd", params: nil, match: false}, + }) testCase("/shop/product/::filter/color::color/size::size", []testparams{ {url: "/shop/product/:test/color:blue/size:xs", params: []string{"test", "blue", "xs"}, match: true}, {url: "/shop/product/test/color:blue/size:xs", params: nil, match: false}, @@ -430,6 +434,10 @@ func Benchmark_Path_matchParams(t *testing.B) { } } + benchCase("/api/:param/fixedEnd", []testparams{ + {url: "/api/abc/fixedEnd", params: []string{"abc"}, match: true}, + {url: "/api/abc/def/fixedEnd", params: nil, match: false}, + }) benchCase("/api/v1/:param/*", []testparams{ {url: "/api/v1/entity", params: []string{"entity", ""}, match: true}, {url: "/api/v1/entity/", params: []string{"entity", ""}, match: true},