This commit is contained in:
a 2024-07-25 15:40:43 -05:00
parent abdb76f083
commit 2419a71643
No known key found for this signature in database
GPG key ID: 374BC539FE795AF0
3 changed files with 137 additions and 1 deletions

View file

@ -20,4 +20,13 @@ Your first time, you may be prompted for a password. This is so Caddy can serve
You can then load [https://localhost](https://localhost) (or whatever address you configured) in your browser. You can then load [https://localhost](https://localhost) (or whatever address you configured) in your browser.
### Docker
You can run rootless with docker with
```
docker stop caddy-website || true && docker rm caddy-website || true
docker run --name caddy-website -it -p 8443:443 -v ./:/wd caddy sh -c "cd /wd && caddy run"
```
This will allow you to connect to https://localhost:8443

View file

@ -0,0 +1,126 @@
---
title: "Placeholder Support"
---
# Placeholder Parsing Rules
Support for placeholders which do not start with a dollar sign (e.g. `{env.HOST}`) must be handled by the individual plugin, and will not be handled by the Caddyfile parser.
If you wish to use placeholders in your Caddy plugin, you must accept such placeholders as valid configuration values, and parse them at runtime
Placeholders which do start with a dollar sign (`{$HOST}`), are evaulated at Caddyfile parse time, and do not need to be dealt with by your plugin
As an example, see the following caddyfile:
```
:8080 {
respond {$HOST} 200
}
:8081 {
respond {env.HOST} 200
}
```
When you adapt this Caddyfile with `HOST=example caddy adapt` you will get
```
{
"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
}
]
}
]
}
}
}
}
}
```
Importantly, look at the `"body"` field in both `srv0` and `srv1`.
Since `srv0` used `{$ENV}`, the special environmental variable placeholder with `$`, as it is parsed during Caddyfile parse time.
Since `srv1` used `{env.HOST}`, a standard placeholder, it was parsed as a normal string value for "body" field of the respond directive's config.
## Using Placeholders in your Plugin
#### Parsing Placeholders in your Unmarshaler
Placeholders should be parsed as their raw values when parsing caddyfiles, just like any other string value
```go
func (g *Gizmo) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
d.Next()
if !d.Args(&g.Name) {
// not enough args
return d.ArgErr()
}
```
#### Resolving Placeholders at Match/Serve time
In order to correctly read our `g.Name` placeholder, in a plugin matcher or middleware, we must extract the replacer from the context, and use that replacer on our saved placeholder string.
```go
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)
}
```
#### Resolving Placeholers at Provision time
If you only use global placeholders, like `env`, then you may also use the replacer at provision time
```go
func (g *Gizmo) Provision(ctx caddy.Context) error {
repl := caddy.NewReplacer()
g.Name = repl.ReplaceAll(g.Name,"")
return nil
}
func (g *Gizmo) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
// in this case, you don't need to replace at serve-time anymore
_, err := w.Write([]byte(g.Name))
if err != nil {
return err
}
return next.ServeHTTP(w, r)
}
```

View file

@ -38,7 +38,7 @@
<li><a href="/docs/modules/">Modules</a></li> <li><a href="/docs/modules/">Modules</a></li>
<li><a href="/docs/json/">JSON Config Structure</a></li> <li><a href="/docs/json/">JSON Config Structure</a></li>
<li><a href="/docs/automatic-https">Automatic HTTPS</a></li> <li><a href="/docs/automatic-https">Automatic HTTPS</a></li>
<li class="heading">Articles</li> <li class="heading">Articles</li>
<li><a href="/docs/architecture">Caddy Architecture</a></li> <li><a href="/docs/architecture">Caddy Architecture</a></li>
<li><a href="/docs/conventions">Conventions</a></li> <li><a href="/docs/conventions">Conventions</a></li>
@ -56,6 +56,7 @@
<ul> <ul>
<li><a href="/docs/extending-caddy/caddyfile">Caddyfile Support</a></li> <li><a href="/docs/extending-caddy/caddyfile">Caddyfile Support</a></li>
<li><a href="/docs/extending-caddy/config-adapters">Config Adapters</a></li> <li><a href="/docs/extending-caddy/config-adapters">Config Adapters</a></li>
<li><a href="/docs/extending-caddy/placeholders">Placeholders</a></li>
</ul> </ul>
</li> </li>
<li><a href="/docs/extending-caddy/namespaces">Module Namespaces</a></li> <li><a href="/docs/extending-caddy/namespaces">Module Namespaces</a></li>