mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-27 06:03:48 +03:00
httpcaddyfile: Matchers can now be embedded into a nested scope
This is useful in 'handle' and 'route' directives, for instance, if you want to keep your matcher definitions by the directives that use them.
This commit is contained in:
parent
78760c0ddc
commit
f6b9cb7122
1 changed files with 33 additions and 6 deletions
|
@ -17,6 +17,7 @@ package httpcaddyfile
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/caddyserver/caddy/v2"
|
"github.com/caddyserver/caddy/v2"
|
||||||
"github.com/caddyserver/caddy/v2/caddyconfig"
|
"github.com/caddyserver/caddy/v2/caddyconfig"
|
||||||
|
@ -298,17 +299,43 @@ func sortRoutes(routes []ConfigValue) {
|
||||||
// and returned.
|
// and returned.
|
||||||
func parseSegmentAsSubroute(h Helper) (caddyhttp.MiddlewareHandler, error) {
|
func parseSegmentAsSubroute(h Helper) (caddyhttp.MiddlewareHandler, error) {
|
||||||
var allResults []ConfigValue
|
var allResults []ConfigValue
|
||||||
for h.Next() {
|
|
||||||
for nesting := h.Nesting(); h.NextBlock(nesting); {
|
|
||||||
dir := h.Val()
|
|
||||||
|
|
||||||
|
for h.Next() {
|
||||||
|
// slice the linear list of tokens into top-level segments
|
||||||
|
var segments []caddyfile.Segment
|
||||||
|
for nesting := h.Nesting(); h.NextBlock(nesting); {
|
||||||
|
segments = append(segments, h.NextSegment())
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy existing matcher definitions so we can augment
|
||||||
|
// new ones that are defined only in this scope
|
||||||
|
matcherDefs := make(map[string]caddy.ModuleMap, len(h.matcherDefs))
|
||||||
|
for key, val := range h.matcherDefs {
|
||||||
|
matcherDefs[key] = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// find and extract any embedded matcher definitions in this scope
|
||||||
|
for i, seg := range segments {
|
||||||
|
if strings.HasPrefix(seg.Directive(), matcherPrefix) {
|
||||||
|
err := parseMatcherDefinitions(caddyfile.NewDispenser(seg), matcherDefs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
segments = append(segments[:i], segments[i+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// with matchers ready to go, evaluate each directive's segment
|
||||||
|
for _, seg := range segments {
|
||||||
|
dir := seg.Directive()
|
||||||
dirFunc, ok := registeredDirectives[dir]
|
dirFunc, ok := registeredDirectives[dir]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, h.Errf("unrecognized directive: %s", dir)
|
return nil, h.Errf("unrecognized directive: %s", dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
subHelper := h
|
subHelper := h
|
||||||
subHelper.Dispenser = h.NewFromNextSegment()
|
subHelper.Dispenser = caddyfile.NewDispenser(seg)
|
||||||
|
subHelper.matcherDefs = matcherDefs
|
||||||
|
|
||||||
results, err := dirFunc(subHelper)
|
results, err := dirFunc(subHelper)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -319,9 +346,9 @@ func parseSegmentAsSubroute(h Helper) (caddyhttp.MiddlewareHandler, error) {
|
||||||
allResults = append(allResults, result)
|
allResults = append(allResults, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return buildSubroute(allResults, h.groupCounter) // TODO: should we move this outside the loop?
|
|
||||||
}
|
}
|
||||||
return nil, nil
|
|
||||||
|
return buildSubroute(allResults, h.groupCounter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// serverBlock pairs a Caddyfile server block
|
// serverBlock pairs a Caddyfile server block
|
||||||
|
|
Loading…
Reference in a new issue