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: