summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2020-02-25 21:56:43 -0700
committerMatthew Holt <mholt@users.noreply.github.com>2020-02-25 21:56:43 -0700
commitf6b9cb7122c670ae063a9049455ec99edf0dc8be (patch)
treef854376571d1c1ecc07c655da809a207512b3abf
parent78760c0ddcd890702977c876fdb126026e13f937 (diff)
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.
-rw-r--r--caddyconfig/httpcaddyfile/directives.go35
1 files changed, 31 insertions, 4 deletions
diff --git a/caddyconfig/httpcaddyfile/directives.go b/caddyconfig/httpcaddyfile/directives.go
index 3c03d30..f82e2a8 100644
--- a/caddyconfig/httpcaddyfile/directives.go
+++ b/caddyconfig/httpcaddyfile/directives.go
@@ -17,6 +17,7 @@ package httpcaddyfile
import (
"encoding/json"
"sort"
+ "strings"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig"
@@ -298,17 +299,43 @@ func sortRoutes(routes []ConfigValue) {
// and returned.
func parseSegmentAsSubroute(h Helper) (caddyhttp.MiddlewareHandler, error) {
var allResults []ConfigValue
+
for h.Next() {
+ // slice the linear list of tokens into top-level segments
+ var segments []caddyfile.Segment
for nesting := h.Nesting(); h.NextBlock(nesting); {
- dir := h.Val()
+ 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]
if !ok {
return nil, h.Errf("unrecognized directive: %s", dir)
}
subHelper := h
- subHelper.Dispenser = h.NewFromNextSegment()
+ subHelper.Dispenser = caddyfile.NewDispenser(seg)
+ subHelper.matcherDefs = matcherDefs
results, err := dirFunc(subHelper)
if err != nil {
@@ -319,9 +346,9 @@ func parseSegmentAsSubroute(h Helper) (caddyhttp.MiddlewareHandler, error) {
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