From 81ee34e9623c3ac630f46c81a26e7823d0b2bf7b Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Mon, 13 Dec 2021 13:42:08 -0500 Subject: httpcaddyfile: Fix sorting edgecase for nested `handle_path` (#4477) --- caddyconfig/httpcaddyfile/directives.go | 3 + caddyconfig/httpcaddyfile/httptype.go | 21 ++-- .../sort_directives_within_handle.txt | 133 +++++++++++++++++++++ 3 files changed, 150 insertions(+), 7 deletions(-) create mode 100644 caddytest/integration/caddyfile_adapt/sort_directives_within_handle.txt diff --git a/caddyconfig/httpcaddyfile/directives.go b/caddyconfig/httpcaddyfile/directives.go index 9da205e..8d895dd 100644 --- a/caddyconfig/httpcaddyfile/directives.go +++ b/caddyconfig/httpcaddyfile/directives.go @@ -340,6 +340,9 @@ func parseSegmentAsConfig(h Helper) ([]ConfigValue, error) { if err != nil { return nil, h.Errf("parsing caddyfile tokens for '%s': %v", dir, err) } + + dir = normalizeDirectiveName(dir) + for _, result := range results { result.directive = dir allResults = append(allResults, result) diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go index bc01060..3a54c08 100644 --- a/caddyconfig/httpcaddyfile/httptype.go +++ b/caddyconfig/httpcaddyfile/httptype.go @@ -193,13 +193,7 @@ func (st ServerType) Setup(inputServerBlocks []caddyfile.ServerBlock, 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" - } + dir = normalizeDirectiveName(dir) for _, result := range results { result.directive = dir @@ -1061,6 +1055,19 @@ func buildSubroute(routes []ConfigValue, groupCounter counter) (*caddyhttp.Subro return subroute, nil } +// normalizeDirectiveName ensures directives that should be sorted +// at the same level are named the same before sorting happens. +func normalizeDirectiveName(directive string) string { + // 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 directive == "handle_path" { + directive = "handle" + } + return directive +} + // consolidateRoutes combines routes with the same properties // (same matchers, same Terminal and Group settings) for a // cleaner overall output. diff --git a/caddytest/integration/caddyfile_adapt/sort_directives_within_handle.txt b/caddytest/integration/caddyfile_adapt/sort_directives_within_handle.txt new file mode 100644 index 0000000..10ff6da --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/sort_directives_within_handle.txt @@ -0,0 +1,133 @@ +*.example.com { + @foo host foo.example.com + handle @foo { + handle_path /strip* { + respond "this should be first" + } + handle { + respond "this should be second" + } + } + handle { + respond "this should be last" + } +} +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "*.example.com" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "group": "group5", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "rewrite", + "strip_path_prefix": "/strip" + } + ] + }, + { + "handle": [ + { + "body": "this should be first", + "handler": "static_response" + } + ] + } + ] + } + ], + "match": [ + { + "path": [ + "/strip*" + ] + } + ] + }, + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "body": "this should be second", + "handler": "static_response" + } + ] + } + ] + } + ] + } + ] + } + ], + "match": [ + { + "host": [ + "foo.example.com" + ] + } + ] + }, + { + "group": "group5", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "body": "this should be last", + "handler": "static_response" + } + ] + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +} \ No newline at end of file -- cgit v1.2.3