From 2885c9fa74ef6c7b1cdf4b60024cedb30b25b726 Mon Sep 17 00:00:00 2001 From: PKhivasra Date: Tue, 10 Oct 2023 15:49:08 -0700 Subject: [PATCH] Sort the paths in routes to ensure matcher picks nearest regex to request uri When the default backend routes are registered, currently it is as per unordered map. This means that the routes can have "" or "\api\v1" before "api\v1\query_range". When the router matches the regex expression (Refs: https://gecgithub01.walmart.com/Telemetry/trickster-v2/blob/main/pkg/router/route.go#L40 https://gecgithub01.walmart.com/Telemetry/trickster-v2/blob/main/pkg/router/regexp.go#L323) with the routes map, if partial routes appears first that will be considered as a match, which causes request to be "Proxy-Only". Thus, with sorting we will ensure that routes will be a sorted array in the descending order of path lengths, meaning: "\api\v1\query_range" would appear before "api\v1" and "" so that we have appropriate match. Issue:https://github.com/trickstercache/trickster/issues/594 --- README.md | 2 +- pkg/routing/routing.go | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 740a53059..09574cd5e 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Trickster is hosted by the [Cloud Native Computing Foundation](https://cncf.io) Note: Trickster v1.1 is the production release, sourced from the [v1.1.x](https://github.com/trickstercache/trickster/tree/v1.1.x) branch. The `main` branch sources Trickster 2.0, which is currently in beta. -## HTTP Reverse Proxy Cache ## +## HTTP Reverse Proxy Cache Trickster is a fully-featured HTTP Reverse Proxy Cache for HTTP applications like static file servers and web API's. diff --git a/pkg/routing/routing.go b/pkg/routing/routing.go index 9115cbad4..1f8f3c5d8 100644 --- a/pkg/routing/routing.go +++ b/pkg/routing/routing.go @@ -383,7 +383,20 @@ func RegisterDefaultBackendRoutes(router router.Router, bknds backends.Backends, } tl.Info(logger, "registering default backend handler paths", tl.Pairs{"backendName": o.Name}) - for _, p := range o.Paths { + + // Sort by key length(Path length) to ensure /api/v1/query_range appear before /api/v1 or / path in regex path matching + keylist := make([]string, 0, len(o.Paths)) + for key := range o.Paths { + keylist = append(keylist, key) + } + sort.Sort(ByLen(keylist)) + for i := len(keylist)/2 - 1; i >= 0; i-- { + opp := len(keylist) - 1 - i + keylist[i], keylist[opp] = keylist[opp], keylist[i] + } + + for _, k := range keylist { + var p = o.Paths[k] if p.Handler != nil && len(p.Methods) > 0 { tl.Debug(logger, "registering default backend handler paths", tl.Pairs{"backendName": o.Name, "path": p.Path, "handlerName": p.HandlerName,