From e3324aa6de6c6f8f9fc14757025bb15de4801dde Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Wed, 16 Sep 2020 22:01:22 -0400 Subject: httpcaddyfile: Ensure handle_path is sorted equally to handle (#3676) * httpcaddyfile: Ensure handle_path is sorted as equal to handle * httpcaddyfile: Make mutual exclusivity grouping deterministic (I hope) * httpcaddyfile: Add comment linking to the issue being fixed * httpcaddyfile: Typo fix, comment clarity Co-authored-by: Matt Holt * Update caddyconfig/httpcaddyfile/httptype.go Co-authored-by: Matt Holt --- caddyconfig/httpcaddyfile/httptype.go | 22 ++++- .../caddyfile_adapt/handle_path_sorting.txt | 105 +++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 caddytest/integration/caddyfile_adapt/handle_path_sorting.txt diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go index f2d1568..a19a6fe 100644 --- a/caddyconfig/httpcaddyfile/httptype.go +++ b/caddyconfig/httpcaddyfile/httptype.go @@ -172,6 +172,15 @@ func (st ServerType) Setup(inputServerBlocks []caddyfile.ServerBlock, if err != nil { return nil, warnings, fmt.Errorf("parsing caddyfile tokens for '%s': %v", dir, err) } + + // As a special case, we want "handle_path" to be sorted + // at the same level as "handle", so we force them to use + // the same directive name after their parsing is complete. + // See https://github.com/caddyserver/caddy/issues/3675#issuecomment-678042377 + if dir == "handle_path" { + dir = "handle" + } + for _, result := range results { result.directive = dir sb.pile[result.Class] = append(sb.pile[result.Class], result) @@ -854,7 +863,18 @@ func buildSubroute(routes []ConfigValue, groupCounter counter) (*caddyhttp.Subro // root directives would overwrite previously-matched ones; they should not cascade "root": {}, } - for meDir, info := range mutuallyExclusiveDirs { + + // we need to deterministically loop over each of these directives + // in order to keep the group numbers consistent + keys := make([]string, 0, len(mutuallyExclusiveDirs)) + for k := range mutuallyExclusiveDirs { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, meDir := range keys { + info := mutuallyExclusiveDirs[meDir] + // see how many instances of the directive there are for _, r := range routes { if r.directive == meDir { diff --git a/caddytest/integration/caddyfile_adapt/handle_path_sorting.txt b/caddytest/integration/caddyfile_adapt/handle_path_sorting.txt new file mode 100644 index 0000000..3258dc9 --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/handle_path_sorting.txt @@ -0,0 +1,105 @@ +:80 { + handle /api/* { + respond "api" + } + + handle_path /static/* { + respond "static" + } + + handle { + respond "handle" + } +} +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":80" + ], + "routes": [ + { + "group": "group3", + "match": [ + { + "path": [ + "/static/*" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "rewrite", + "strip_path_prefix": "/static" + } + ] + }, + { + "handle": [ + { + "body": "static", + "handler": "static_response" + } + ] + } + ] + } + ] + }, + { + "group": "group3", + "match": [ + { + "path": [ + "/api/*" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "body": "api", + "handler": "static_response" + } + ] + } + ] + } + ] + }, + { + "group": "group3", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "body": "handle", + "handler": "static_response" + } + ] + } + ] + } + ] + } + ] + } + } + } + } +} \ No newline at end of file -- cgit v1.2.3