Плейсхолдеры
В Caddy плейсхолдеры обрабатываются каждым отдельным плагином по мере необходимости; они не работают автоматически везде.
Это означает, что если вы хотите, чтобы ваш плагин поддерживал плейсхолдеры, вы должны явно добавить поддержку для них.
Если вы ещё не знакомы с плейсхолдерами, начните с чтения здесь!
Обзор плейсхолдеров
Плейсхолдеры — это строка в формате {foo.bar}, используемая в качестве динамических значений конфигурации, которые позже оцениваются во время выполнения.
Подстановки переменных окружения Caddyfile, начинающиеся с знака доллара, такие как {$FOO}, оцениваются во время разбора Caddyfile и не нуждаются в обработке вашим плагином. Это не плейсхолдеры, несмотря на использование такого же { } синтаксиса.
Поэтому важно понимать, что {env.HOST} (глобальный плейсхолдер) принципиально отличается от {$HOST} (подстановка переменной окружения Caddyfile).
В качестве примера см. следующий Caddyfile:
:8080 {
respond {$HOST} 200
}
:8081 {
respond {env.HOST} 200
}
При адаптации этого Caddyfile к JSON с помощью HOST=example caddy adapt вы получите:
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [":8080"],
"routes": [
{
"handle": [
{
"body": "example",
"handler": "static_response",
"status_code": 200
}
]
}
]
},
"srv1": {
"listen": [":8081"],
"routes": [
{
"handle": [
{
"body": "{env.HOST}",
"handler": "static_response",
"status_code": 200
}
]
}
]
}
}
}
}
}
Обратите особое внимание на поле "body" в обоих srv0 и srv1.
Поскольку srv0 использовал {$HOST} (подстановку переменной окружения Caddyfile), значение стало example, так как оно было обработано во время разбора Caddyfile при генерации конфигурации JSON.
Поскольку srv1 использовал {env.HOST} (глобальный плейсхолдер), он остался неизменным при адаптации к JSON.
Это означает, что пользователи, создающие конфигурацию JSON (не используя Caddyfile), не могут использовать синтаксис {$ENV}. По этой причине важно, чтобы авторы плагинов реализовали поддержку замены плейсхолдеров при подготовке конфигурации. Это описано ниже.
Реализация поддержки плейсхолдеров
Не нужно обрабатывать плейсхолдеры в UnmarshalCaddyfile(). Вместо этого плейсхолдеры должны быть заменены позже, либо на этапе Provision(), либо во время выполнения модуля (например, ServeHTTP() для обработчиков HTTP, Match() для фильтров и т. д.), используя caddy.Replacer.
Примеры
Здесь мы используем новый созданный заменитель для обработки плейсхолдеров. Он имеет доступ к глобальным плейсхолдерам, таким как {env.HOST}, но не к плейсхолдерам HTTP, таким как {http.request.uri}, потому что подготовка происходит при загрузке конфигурации, а не во время запроса.
func (g *Gizmo) Provision(ctx caddy.Context) error {
repl := caddy.NewReplacer()
g.Name = repl.ReplaceAll(g.Name,"")
return nil
}
Здесь мы получаем заменитель из контекста запроса r.Context() во время ServeHTTP. Этот заменитель имеет доступ как к глобальным плейсхолдерам, так и к плейсхолдерам HTTP для каждого запроса, таким как {http.request.uri}.
func (g *Gizmo) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
_, err := w.Write([]byte(repl.ReplaceAll(g.Name,"")))
if err != nil {
return err
}
return next.ServeHTTP(w, r)
}
© 2015-2025 Matthew Holt and The Caddy Authors
Licensed under the Apache License 2.0.
Caddy is a registered trademark of Stack Holdings GmbH.
https://caddyserver.com/docs/extending-caddy/placeholders