diff options
-rw-r--r-- | modules/caddyhttp/map/caddyfile.go | 9 | ||||
-rw-r--r-- | modules/caddyhttp/map/map.go | 27 |
2 files changed, 25 insertions, 11 deletions
diff --git a/modules/caddyhttp/map/caddyfile.go b/modules/caddyhttp/map/caddyfile.go index eb0c5ae..77d4c46 100644 --- a/modules/caddyhttp/map/caddyfile.go +++ b/modules/caddyhttp/map/caddyfile.go @@ -35,6 +35,9 @@ func init() { // If the input value is prefixed with a tilde (~), then the input will be parsed as a // regular expression. // +// The Caddyfile adapter treats outputs that are a literal hyphen (-) as a null/nil +// value. This is useful if you want to fall back to default for that particular output. +// // The number of outputs for each mapping must not be more than the number of destinations. // However, for convenience, there may be fewer outputs than destinations and any missing // outputs will be filled in implicitly. @@ -72,7 +75,11 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) in := h.Val() var outs []interface{} for _, out := range h.RemainingArgs() { - outs = append(outs, out) + if out == "-" { + outs = append(outs, nil) + } else { + outs = append(outs, out) + } } // cannot have more outputs than destinations diff --git a/modules/caddyhttp/map/map.go b/modules/caddyhttp/map/map.go index ba90e6f..bfb2115 100644 --- a/modules/caddyhttp/map/map.go +++ b/modules/caddyhttp/map/map.go @@ -43,7 +43,7 @@ type Handler struct { Destinations []string `json:"destinations,omitempty"` // Mappings from source values (inputs) to destination values (outputs). - // The first matching mapping will be applied. + // The first matching, non-nil mapping will be applied. Mappings []Mapping `json:"mappings,omitempty"` // If no mappings match or if the mapped output is null/nil, the associated @@ -69,9 +69,6 @@ func (h *Handler) Provision(_ caddy.Context) error { if m.InputRegexp == "" { continue } - if m.Input != "" { - return fmt.Errorf("mapping %d has both input and input_regexp fields specified, which is confusing", i) - } var err error h.Mappings[i].re, err = regexp.Compile(m.InputRegexp) if err != nil { @@ -94,11 +91,20 @@ func (h *Handler) Validate() error { seen := make(map[string]int) for i, m := range h.Mappings { + // prevent confusing/ambiguous mappings + if m.Input != "" && m.InputRegexp != "" { + return fmt.Errorf("mapping %d has both input and input_regexp fields specified, which is confusing", i) + } + // prevent duplicate mappings - if prev, ok := seen[m.Input]; ok { - return fmt.Errorf("mapping %d has a duplicate input '%s' previously used with mapping %d", i, m.Input, prev) + input := m.Input + if m.InputRegexp != "" { + input = m.InputRegexp + } + if prev, ok := seen[input]; ok { + return fmt.Errorf("mapping %d has a duplicate input '%s' previously used with mapping %d", i, input, prev) } - seen[m.Input] = i + seen[input] = i // ensure mappings have 1:1 output-to-destination correspondence nOut := len(m.Outputs) @@ -128,7 +134,7 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt if m.re != nil { if m.re.MatchString(input) { if output := m.Outputs[destIdx]; output == nil { - break + continue } else { return output, true } @@ -137,7 +143,7 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt } if input == m.Input { if output := m.Outputs[destIdx]; output == nil { - break + continue } else { return output, true } @@ -176,7 +182,8 @@ type Mapping struct { InputRegexp string `json:"input_regexp,omitempty"` // Upon a match with the input, each output is positionally correlated - // with each destination of the parent handler. + // with each destination of the parent handler. An output that is null + // (nil) will be treated as if it was not mapped at all. Outputs []interface{} `json:"outputs,omitempty"` re *regexp.Regexp |