summaryrefslogtreecommitdiff
path: root/caddyconfig
diff options
context:
space:
mode:
authorFrancis Lavoie <lavofr@gmail.com>2022-09-01 23:12:37 -0400
committerGitHub <noreply@github.com>2022-09-01 23:12:37 -0400
commit7d5108d132d3bccfd8d83bc3fc2dbc46afde20ae (patch)
treef476b207d820a4dcf64ab9bca1c92af12a384da2 /caddyconfig
parent7c35bfa57cb402e82b28118b69c265df3e8c94fd (diff)
httpcaddyfile: Add shortcut for expression matchers (#4976)
Diffstat (limited to 'caddyconfig')
-rw-r--r--caddyconfig/caddyfile/lexer.go4
-rw-r--r--caddyconfig/httpcaddyfile/httptype.go47
2 files changed, 41 insertions, 10 deletions
diff --git a/caddyconfig/caddyfile/lexer.go b/caddyconfig/caddyfile/lexer.go
index 4a23524..5605a6a 100644
--- a/caddyconfig/caddyfile/lexer.go
+++ b/caddyconfig/caddyfile/lexer.go
@@ -191,3 +191,7 @@ func Tokenize(input []byte, filename string) ([]Token, error) {
}
return tokens, nil
}
+
+func (t Token) Quoted() bool {
+ return t.wasQuoted > 0
+}
diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go
index 8fef131..2182a5b 100644
--- a/caddyconfig/httpcaddyfile/httptype.go
+++ b/caddyconfig/httpcaddyfile/httptype.go
@@ -1201,6 +1201,7 @@ func (st *ServerType) compileEncodedMatcherSets(sblock serverBlock) ([]caddy.Mod
func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.ModuleMap) error {
for d.Next() {
+ // this is the "name" for "named matchers"
definitionName := d.Val()
if _, ok := matchers[definitionName]; ok {
@@ -1208,16 +1209,9 @@ func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.M
}
matchers[definitionName] = make(caddy.ModuleMap)
- // in case there are multiple instances of the same matcher, concatenate
- // their tokens (we expect that UnmarshalCaddyfile should be able to
- // handle more than one segment); otherwise, we'd overwrite other
- // instances of the matcher in this set
- tokensByMatcherName := make(map[string][]caddyfile.Token)
- for nesting := d.Nesting(); d.NextArg() || d.NextBlock(nesting); {
- matcherName := d.Val()
- tokensByMatcherName[matcherName] = append(tokensByMatcherName[matcherName], d.NextSegment()...)
- }
- for matcherName, tokens := range tokensByMatcherName {
+ // given a matcher name and the tokens following it, parse
+ // the tokens as a matcher module and record it
+ makeMatcher := func(matcherName string, tokens []caddyfile.Token) error {
mod, err := caddy.GetModule("http.matchers." + matcherName)
if err != nil {
return fmt.Errorf("getting matcher module '%s': %v", matcherName, err)
@@ -1235,6 +1229,39 @@ func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.M
return fmt.Errorf("matcher module '%s' is not a request matcher", matcherName)
}
matchers[definitionName][matcherName] = caddyconfig.JSON(rm, nil)
+ return nil
+ }
+
+ // if the next token is quoted, we can assume it's not a matcher name
+ // and that it's probably an 'expression' matcher
+ if d.NextArg() {
+ if d.Token().Quoted() {
+ err := makeMatcher("expression", []caddyfile.Token{d.Token()})
+ if err != nil {
+ return err
+ }
+ continue
+ }
+
+ // if it wasn't quoted, then we need to rewind after calling
+ // d.NextArg() so the below properly grabs the matcher name
+ d.Prev()
+ }
+
+ // in case there are multiple instances of the same matcher, concatenate
+ // their tokens (we expect that UnmarshalCaddyfile should be able to
+ // handle more than one segment); otherwise, we'd overwrite other
+ // instances of the matcher in this set
+ tokensByMatcherName := make(map[string][]caddyfile.Token)
+ for nesting := d.Nesting(); d.NextArg() || d.NextBlock(nesting); {
+ matcherName := d.Val()
+ tokensByMatcherName[matcherName] = append(tokensByMatcherName[matcherName], d.NextSegment()...)
+ }
+ for matcherName, tokens := range tokensByMatcherName {
+ err := makeMatcher(matcherName, tokens)
+ if err != nil {
+ return err
+ }
}
}
return nil