Skip to content

Commit

Permalink
new algo for sorting routes by slug length
Browse files Browse the repository at this point in the history
  • Loading branch information
simonmittag committed Apr 16, 2023
1 parent a3aead6 commit 0041832
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 1 deletion.
25 changes: 25 additions & 0 deletions j8acfg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,31 @@ routes:
resource: badlocal
- path: /badssl
resource: badssl
- path: /path/med/2
pathType: exact
resource: blah2
- path: /path/med/1st
pathType: exact
resource: blah1
- path: /longfirstslug_longfirstslug_longfirstslug_longfirstslug/short
resource: blah1
- path: /short/longersecondslug_longersecondslug_longersecondslug_longersecondslug
resource: blah1
- path: /a/a/
rescource: blah3213
- path: /a/ab/
rescource: blah3123
- path: /path/long/hierarchy/2nd
pathType: prefix
resource: blah4
- path: /path/long/hierarchy/first
pathType: prefix
resource: blah3
- path: /c/a
rescource: blah3213
- path: /ab/a/a/
rescource: blah3213


resources:
jsonplaceholder:
Expand Down
2 changes: 2 additions & 0 deletions proxyhandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ func proxyHandler(response http.ResponseWriter, request *http.Request, exec prox
}
}

// TODO this needs a new order. Exact matches first, then prefix matches. inside all these, longer matches first, then shorter ones.
// try a custom sorter for routes.
func matchRoutes(request *http.Request, proxy *Proxy) bool {
matched := false
for _, route := range Runner.Routes {
Expand Down
22 changes: 21 additions & 1 deletion route.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,27 @@ func (s Routes) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s Routes) Less(i, j int) bool {
return len(s[i].Path) > len(s[j].Path)
pis := strings.Split(s[i].Path, slashS)
if len(pis[0]) == 0 && len(pis) > 1 {
pis = pis[1:]
}
pjs := strings.Split(s[j].Path, slashS)
if len(pjs[0]) == 0 && len(pjs) > 1 {
pjs = pjs[1:]
}

less := false
if (s[i].PathType == exact && s[j].PathType == exact) || (s[i].PathType == prefixS && s[j].PathType == prefixS) {
for pii, pip := range pis {
if pii <= len(pjs)-1 && len(pip) > len(pjs[pii]) {
less = true
break
}
}
} else {
less = s[i].PathType == exact
}
return less
}

// Route maps a Path to an upstream resource
Expand Down
14 changes: 14 additions & 0 deletions route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,20 @@ func TestRoutePathTypesAreValid(t *testing.T) {
}
}

func TestRouteSorting(t *testing.T) {
//the sort order needs to be exact over prefix, then by longest path.

config := new(Config).readYmlFile("./j8acfg.yml")
config = config.compileRoutePaths().validateRoutes()

if config.Routes[0].Path != "/path/med/1st" ||
config.Routes[1].Path != "/path/med/2" ||
config.Routes[2].Path != "/longfirstslug_longfirstslug_longfirstslug_longfirstslug/short" ||
config.Routes[3].Path != "/badremote" {
t.Errorf("sort order wrong %v", config.Routes)
}
}

func BenchmarkRouteMatchingRegex(b *testing.B) {
//suppress noise
zerolog.SetGlobalLevel(zerolog.InfoLevel)
Expand Down

0 comments on commit 0041832

Please sign in to comment.