diff --git a/caddyconfig/httpcaddyfile/directives.go b/caddyconfig/httpcaddyfile/directives.go index 8bf627b27..4f54c5920 100644 --- a/caddyconfig/httpcaddyfile/directives.go +++ b/caddyconfig/httpcaddyfile/directives.go @@ -228,6 +228,14 @@ func (h Helper) Option(name string) any { return h.options[name] } +// IsNamedRoute returns true if the directive is in a named route. +// Named routes are adapted before the site blocks, with their own +// State, so values a directive keeps in State aren't shared with +// the site blocks. +func (h Helper) IsNamedRoute() bool { + return h.parentBlock.IsNamedRoute +} + // Caddyfiles returns the list of config files from // which tokens in the current server block were loaded. func (h Helper) Caddyfiles() []string { diff --git a/caddyconfig/httpcaddyfile/directives_test.go b/caddyconfig/httpcaddyfile/directives_test.go index 9adf0c041..64ddf5a8f 100644 --- a/caddyconfig/httpcaddyfile/directives_test.go +++ b/caddyconfig/httpcaddyfile/directives_test.go @@ -111,6 +111,36 @@ func init() { return caddyhttp.StaticError{StatusCode: "500"}, nil }) RegisterDirectiveOrder("test_ordered_plugin", Before, "respond") + + RegisterHandlerDirective("test_named_route", func(h Helper) (caddyhttp.MiddlewareHandler, error) { + h.Next() + body := "site" + if h.IsNamedRoute() { + body = "named" + } + return caddyhttp.StaticResponse{Body: body}, nil + }) + RegisterDirectiveOrder("test_named_route", Before, "respond") +} + +func TestHelperIsNamedRoute(t *testing.T) { + adapted := adaptCaddyfile(t, `&(shared) { + handle /nested { + test_named_route + } +} + +:8080 { + test_named_route + invoke shared +} +`) + + for _, body := range []string{`"body":"named"`, `"body":"site"`} { + if !strings.Contains(adapted, body) { + t.Errorf("expected %s in the adapted config: %s", body, adapted) + } + } } // caddyfiles shared by the directive order tests below. the handle block in