(d *caddyfile.Dispenser, matchers map[string]caddy.ModuleMap)
| 1535 | } |
| 1536 | |
| 1537 | func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.ModuleMap) error { |
| 1538 | d.Next() // advance to the first token |
| 1539 | |
| 1540 | // this is the "name" for "named matchers" |
| 1541 | definitionName := d.Val() |
| 1542 | |
| 1543 | if _, ok := matchers[definitionName]; ok { |
| 1544 | return fmt.Errorf("matcher is defined more than once: %s", definitionName) |
| 1545 | } |
| 1546 | matchers[definitionName] = make(caddy.ModuleMap) |
| 1547 | |
| 1548 | // given a matcher name and the tokens following it, parse |
| 1549 | // the tokens as a matcher module and record it |
| 1550 | makeMatcher := func(matcherName string, tokens []caddyfile.Token) error { |
| 1551 | // create a new dispenser from the tokens |
| 1552 | dispenser := caddyfile.NewDispenser(tokens) |
| 1553 | |
| 1554 | // set the matcher name (without @) in the dispenser context so |
| 1555 | // that matcher modules can access it to use it as their name |
| 1556 | // (e.g. regexp matchers which use the name for capture groups) |
| 1557 | dispenser.SetContext(caddyfile.MatcherNameCtxKey, definitionName[1:]) |
| 1558 | |
| 1559 | mod, err := caddy.GetModule("http.matchers." + matcherName) |
| 1560 | if err != nil { |
| 1561 | return fmt.Errorf("getting matcher module '%s': %v", matcherName, err) |
| 1562 | } |
| 1563 | unm, ok := mod.New().(caddyfile.Unmarshaler) |
| 1564 | if !ok { |
| 1565 | return fmt.Errorf("matcher module '%s' is not a Caddyfile unmarshaler", matcherName) |
| 1566 | } |
| 1567 | err = unm.UnmarshalCaddyfile(dispenser) |
| 1568 | if err != nil { |
| 1569 | return err |
| 1570 | } |
| 1571 | |
| 1572 | if rm, ok := unm.(caddyhttp.RequestMatcherWithError); ok { |
| 1573 | matchers[definitionName][matcherName] = caddyconfig.JSON(rm, nil) |
| 1574 | return nil |
| 1575 | } |
| 1576 | // nolint:staticcheck |
| 1577 | if rm, ok := unm.(caddyhttp.RequestMatcher); ok { |
| 1578 | matchers[definitionName][matcherName] = caddyconfig.JSON(rm, nil) |
| 1579 | return nil |
| 1580 | } |
| 1581 | return fmt.Errorf("matcher module '%s' is not a request matcher", matcherName) |
| 1582 | } |
| 1583 | |
| 1584 | // if the next token is quoted, we can assume it's not a matcher name |
| 1585 | // and that it's probably an 'expression' matcher |
| 1586 | if d.NextArg() { |
| 1587 | if d.Token().Quoted() { |
| 1588 | // since it was missing the matcher name, we insert a token |
| 1589 | // in front of the expression token itself; we use Clone() to |
| 1590 | // make the new token to keep the same the import location as |
| 1591 | // the next token, if this is within a snippet or imported file. |
| 1592 | // see https://github.com/caddyserver/caddy/issues/6287 |
| 1593 | expressionToken := d.Token().Clone() |
| 1594 | expressionToken.Text = "expression" |
no test coverage detected