@marcel91200 / caddy Mirror · read-only / commits / 7c35bfa5
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 14:15 UTC

caddyhttp: Accept placeholders in vars matcher key

Until now, the vars matcher has unintentionally lacked parity with the map directive: the destination placeholders of the map directive would be expressed as placeholders, i.e. {foo}. But the vars matcher would not use { }: vars foo value This looked weird, and was confusing, since it implied that the key could be dynamic, which doesn't seem helpful here. I think this is a proper bug fix, since we're not used to accessing placeholders literally without { } in the Caddyfile.

Matthew Holt committed Sep 1, 2022 at 16:49 UTC 7c35bfa57cb402e82b28118b69c265df3e8c94fd
2 files changed +24 -19
modules/caddyhttp/vars.go
+22 -19
@@ -18,6 +18,7 @@ import (
18 "context"
19 "fmt"
20 "net/http"
21 + "strings"
22
23 "github.com/caddyserver/caddy/v2"
24 "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
@@ -62,11 +63,10 @@ func (m VarsMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next H
63
64 // UnmarshalCaddyfile implements caddyfile.Unmarshaler. Syntax:
65 //
65 -// vars [<name> <val>] {
66 -// <name> <val>
67 -// ...
68 -// }
69 -//
66 +// vars [<name> <val>] {
67 +// <name> <val>
68 +// ...
69 +// }
70 func (m *VarsMiddleware) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
71 if *m == nil {
72 *m = make(VarsMiddleware)
@@ -109,14 +109,17 @@ func (m *VarsMiddleware) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
109 }
110
111 // VarsMatcher is an HTTP request matcher which can match
112 -// requests based on variables in the context. The key is
113 -// the name of the variable, and the values are possible
114 -// values the variable can be in order to match (OR'ed).
112 +// requests based on variables in the context or placeholder
113 +// values. The key is the placeholder or name of the variable,
114 +// and the values are possible values the variable can be in
115 +// order to match (logical OR'ed).
116 +//
117 +// If the key is surrounded by `{ }` it is assumed to be a
118 +// placeholder. Otherwise, it will be considered a variable
119 +// name.
120 //
116 -// As a special case, this matcher can also match on
117 -// placeholders generally. If the key is not an HTTP chain
118 -// variable, it will be checked to see if it is a
119 -// placeholder name, and if so, will compare its value.
121 +// Placeholders in the keys are not expanded, but
122 +// placeholders in the values are.
123 type VarsMatcher map[string][]string
124
125 // CaddyModule returns the Caddy module information.
@@ -160,13 +163,13 @@ func (m VarsMatcher) Match(r *http.Request) bool {
163 repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
164
165 for key, vals := range m {
163 - // look up the comparison value we will check against with this key
164 - matcherVarNameExpanded := repl.ReplaceAll(key, "")
165 - varValue, ok := vars[matcherVarNameExpanded]
166 - if !ok {
167 - // as a special case, if it's not an HTTP variable,
168 - // see if it's a placeholder name
169 - varValue, _ = repl.Get(matcherVarNameExpanded)
166 + var varValue any
167 + if strings.HasPrefix(key, "{") &&
168 + strings.HasSuffix(key, "}") &&
169 + strings.Count(key, "{") == 1 {
170 + varValue, _ = repl.Get(strings.Trim(key, "{}"))
171 + } else {
172 + varValue = vars[key]
173 }
174
175 // see if any of the values given in the matcher match the actual value
replacer.go
+2
@@ -238,6 +238,8 @@ func toString(val any) string {
238 return v
239 case fmt.Stringer:
240 return v.String()
241 + case error:
242 + return v.Error()
243 case byte:
244 return string(v)
245 case []byte: