Skip to content

Commit

Permalink
map: Bug fixes; null literal with hyphen in Caddyfile
Browse files Browse the repository at this point in the history
  • Loading branch information
mholt committed Oct 2, 2020
1 parent 0fc47e8 commit ef8a372
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 11 deletions.
9 changes: 8 additions & 1 deletion modules/caddyhttp/map/caddyfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
27 changes: 17 additions & 10 deletions modules/caddyhttp/map/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -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)
Expand Down Expand Up @@ -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
}
Expand All @@ -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
}
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit ef8a372

Please sign in to comment.