summaryrefslogtreecommitdiff
path: root/caddyconfig/httpcaddyfile/directives.go
diff options
context:
space:
mode:
Diffstat (limited to 'caddyconfig/httpcaddyfile/directives.go')
-rw-r--r--caddyconfig/httpcaddyfile/directives.go74
1 files changed, 33 insertions, 41 deletions
diff --git a/caddyconfig/httpcaddyfile/directives.go b/caddyconfig/httpcaddyfile/directives.go
index ff248bf..ac401e1 100644
--- a/caddyconfig/httpcaddyfile/directives.go
+++ b/caddyconfig/httpcaddyfile/directives.go
@@ -276,53 +276,45 @@ func sortRoutes(routes []ConfigValue) {
dirPositions[dir] = i
}
- // while we are sorting, we will need to decode a route's path matcher
- // in order to sub-sort by path length; we can amortize this operation
- // for efficiency by storing the decoded matchers in a slice
- decodedMatchers := make([]caddyhttp.MatchPath, len(routes))
-
sort.SliceStable(routes, func(i, j int) bool {
+ // if the directives are different, just use the established directive order
iDir, jDir := routes[i].directive, routes[j].directive
- if iDir == jDir {
- // directives are the same; sub-sort by path matcher length
- // if there's only one matcher set and one path (common case)
- iRoute, ok := routes[i].Value.(caddyhttp.Route)
- if !ok {
- return false
- }
- jRoute, ok := routes[j].Value.(caddyhttp.Route)
- if !ok {
- return false
- }
+ if iDir != jDir {
+ return dirPositions[iDir] < dirPositions[jDir]
+ }
- // use already-decoded matcher, or decode if it's the first time seeing it
- iPM, jPM := decodedMatchers[i], decodedMatchers[j]
- if iPM == nil && len(iRoute.MatcherSetsRaw) == 1 {
- var pathMatcher caddyhttp.MatchPath
- _ = json.Unmarshal(iRoute.MatcherSetsRaw[0]["path"], &pathMatcher)
- decodedMatchers[i] = pathMatcher
- iPM = pathMatcher
- }
- if jPM == nil && len(jRoute.MatcherSetsRaw) == 1 {
- var pathMatcher caddyhttp.MatchPath
- _ = json.Unmarshal(jRoute.MatcherSetsRaw[0]["path"], &pathMatcher)
- decodedMatchers[j] = pathMatcher
- jPM = pathMatcher
- }
+ // directives are the same; sub-sort by path matcher length if there's
+ // only one matcher set and one path (this is a very common case and
+ // usually -- but not always -- helpful/expected, oh well; user can
+ // always take manual control of order using handler or route blocks)
+ iRoute, ok := routes[i].Value.(caddyhttp.Route)
+ if !ok {
+ return false
+ }
+ jRoute, ok := routes[j].Value.(caddyhttp.Route)
+ if !ok {
+ return false
+ }
- // sort by longer path (more specific) first; missing
- // path matchers are treated as zero-length paths
- var iPathLen, jPathLen int
- if iPM != nil {
- iPathLen = len(iPM[0])
- }
- if jPM != nil {
- jPathLen = len(jPM[0])
- }
- return iPathLen > jPathLen
+ // decode the path matchers, if there is just one of them
+ var iPM, jPM caddyhttp.MatchPath
+ if len(iRoute.MatcherSetsRaw) == 1 {
+ _ = json.Unmarshal(iRoute.MatcherSetsRaw[0]["path"], &iPM)
+ }
+ if len(jRoute.MatcherSetsRaw) == 1 {
+ _ = json.Unmarshal(jRoute.MatcherSetsRaw[0]["path"], &jPM)
}
- return dirPositions[iDir] < dirPositions[jDir]
+ // sort by longer path (more specific) first; missing path
+ // matchers or multi-matchers are treated as zero-length paths
+ var iPathLen, jPathLen int
+ if len(iPM) > 0 {
+ iPathLen = len(iPM[0])
+ }
+ if len(jPM) > 0 {
+ jPathLen = len(jPM[0])
+ }
+ return iPathLen > jPathLen
})
}