httpcaddyfile: keep source order for vars with non-comparable matchers (#8197)

Use i/j swap instead of !sortByPath for vars, so matchers that can't
be compared keep their Caddyfile order. Path matchers still sort with
the more specific one later. Fixes the vars ordering part of #8187.
pull/8201/head
IcyJerry 2026-10-12 18:49:24 +08:00 committed by GitHub
parent f2c20fb810
commit 6ae02b5ccb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 77 additions and 13 deletions

View File

@ -465,6 +465,15 @@ func sortRoutes(routes []ConfigValue, order []string) {
return dirPositions[iDir] < dirPositions[jDir]
}
// some directives involve setting values which can overwrite
// each other, so it makes most sense to reverse the order so
// that the least-specific matcher is first, allowing the last
// matching one to win; we swap i and j instead of using !,
// so matchers that can't be compared keep their order
if iDir == "vars" {
i, j = j, i
}
// 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
@ -535,15 +544,7 @@ func sortRoutes(routes []ConfigValue, order []string) {
return len(iRoute.MatcherSetsRaw) > 0 && len(jRoute.MatcherSetsRaw) == 0
}()
// some directives involve setting values which can overwrite
// each other, so it makes most sense to reverse the order so
// that the least-specific matcher is first, allowing the last
// matching one to win
if iDir == "vars" {
return !sortByPath
}
// everything else is most-specific matcher first
// most-specific matcher first (or last for vars, see above)
return sortByPath
})
}

View File

@ -101,16 +101,16 @@ vars {
],
"source": "{http.request.host}"
},
{
"foo": "bar",
"handler": "vars"
},
{
"abc": true,
"def": 1,
"ghi": 2.3,
"handler": "vars",
"jkl": "mn op"
},
{
"foo": "bar",
"handler": "vars"
}
]
}

View File

@ -0,0 +1,63 @@
:80
@first header X-Test a
@second header X-Test a
@third header X-Other b
vars @first value first
vars @second value second
vars @third value third
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":80"
],
"routes": [
{
"match": [
{
"header": {
"X-Test": [
"a"
]
}
}
],
"handle": [
{
"handler": "vars",
"value": "first"
},
{
"handler": "vars",
"value": "second"
}
]
},
{
"match": [
{
"header": {
"X-Other": [
"b"
]
}
}
],
"handle": [
{
"handler": "vars",
"value": "third"
}
]
}
]
}
}
}
}
}