From 7c35bfa57cb402e82b28118b69c265df3e8c94fd Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Thu, 1 Sep 2022 16:49:18 -0600 Subject: 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. --- modules/caddyhttp/vars.go | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'modules/caddyhttp/vars.go') diff --git a/modules/caddyhttp/vars.go b/modules/caddyhttp/vars.go index 08f3e70..b4e1d89 100644 --- a/modules/caddyhttp/vars.go +++ b/modules/caddyhttp/vars.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "net/http" + "strings" "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" @@ -62,11 +63,10 @@ func (m VarsMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next H // UnmarshalCaddyfile implements caddyfile.Unmarshaler. Syntax: // -// vars [ ] { -// -// ... -// } -// +// vars [ ] { +// +// ... +// } func (m *VarsMiddleware) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { if *m == nil { *m = make(VarsMiddleware) @@ -109,14 +109,17 @@ func (m *VarsMiddleware) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { } // VarsMatcher is an HTTP request matcher which can match -// requests based on variables in the context. The key is -// the name of the variable, and the values are possible -// values the variable can be in order to match (OR'ed). +// requests based on variables in the context or placeholder +// values. The key is the placeholder or name of the variable, +// and the values are possible values the variable can be in +// order to match (logical OR'ed). +// +// If the key is surrounded by `{ }` it is assumed to be a +// placeholder. Otherwise, it will be considered a variable +// name. // -// As a special case, this matcher can also match on -// placeholders generally. If the key is not an HTTP chain -// variable, it will be checked to see if it is a -// placeholder name, and if so, will compare its value. +// Placeholders in the keys are not expanded, but +// placeholders in the values are. type VarsMatcher map[string][]string // CaddyModule returns the Caddy module information. @@ -160,13 +163,13 @@ func (m VarsMatcher) Match(r *http.Request) bool { repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer) for key, vals := range m { - // look up the comparison value we will check against with this key - matcherVarNameExpanded := repl.ReplaceAll(key, "") - varValue, ok := vars[matcherVarNameExpanded] - if !ok { - // as a special case, if it's not an HTTP variable, - // see if it's a placeholder name - varValue, _ = repl.Get(matcherVarNameExpanded) + var varValue any + if strings.HasPrefix(key, "{") && + strings.HasSuffix(key, "}") && + strings.Count(key, "{") == 1 { + varValue, _ = repl.Get(strings.Trim(key, "{}")) + } else { + varValue = vars[key] } // see if any of the values given in the matcher match the actual value -- cgit v1.2.3