mirror of
https://github.com/caddyserver/caddy.git
synced 2025-02-18 11:12:44 +08:00
map: Bug fixes; null literal with hyphen in Caddyfile
This commit is contained in:
parent
0fc47e8357
commit
ef8a372a1c
|
@ -35,6 +35,9 @@ func init() {
|
||||||
// If the input value is prefixed with a tilde (~), then the input will be parsed as a
|
// If the input value is prefixed with a tilde (~), then the input will be parsed as a
|
||||||
// regular expression.
|
// 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.
|
// 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
|
// However, for convenience, there may be fewer outputs than destinations and any missing
|
||||||
// outputs will be filled in implicitly.
|
// outputs will be filled in implicitly.
|
||||||
|
@ -72,8 +75,12 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
|
||||||
in := h.Val()
|
in := h.Val()
|
||||||
var outs []interface{}
|
var outs []interface{}
|
||||||
for _, out := range h.RemainingArgs() {
|
for _, out := range h.RemainingArgs() {
|
||||||
|
if out == "-" {
|
||||||
|
outs = append(outs, nil)
|
||||||
|
} else {
|
||||||
outs = append(outs, out)
|
outs = append(outs, out)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// cannot have more outputs than destinations
|
// cannot have more outputs than destinations
|
||||||
if len(outs) > len(handler.Destinations) {
|
if len(outs) > len(handler.Destinations) {
|
||||||
|
|
|
@ -43,7 +43,7 @@ type Handler struct {
|
||||||
Destinations []string `json:"destinations,omitempty"`
|
Destinations []string `json:"destinations,omitempty"`
|
||||||
|
|
||||||
// Mappings from source values (inputs) to destination values (outputs).
|
// 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"`
|
Mappings []Mapping `json:"mappings,omitempty"`
|
||||||
|
|
||||||
// If no mappings match or if the mapped output is null/nil, the associated
|
// 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 == "" {
|
if m.InputRegexp == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if m.Input != "" {
|
|
||||||
return fmt.Errorf("mapping %d has both input and input_regexp fields specified, which is confusing", i)
|
|
||||||
}
|
|
||||||
var err error
|
var err error
|
||||||
h.Mappings[i].re, err = regexp.Compile(m.InputRegexp)
|
h.Mappings[i].re, err = regexp.Compile(m.InputRegexp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -94,11 +91,20 @@ func (h *Handler) Validate() error {
|
||||||
|
|
||||||
seen := make(map[string]int)
|
seen := make(map[string]int)
|
||||||
for i, m := range h.Mappings {
|
for i, m := range h.Mappings {
|
||||||
// prevent duplicate mappings
|
// prevent confusing/ambiguous mappings
|
||||||
if prev, ok := seen[m.Input]; ok {
|
if m.Input != "" && m.InputRegexp != "" {
|
||||||
return fmt.Errorf("mapping %d has a duplicate input '%s' previously used with mapping %d", i, m.Input, prev)
|
return fmt.Errorf("mapping %d has both input and input_regexp fields specified, which is confusing", i)
|
||||||
}
|
}
|
||||||
seen[m.Input] = i
|
|
||||||
|
// prevent duplicate mappings
|
||||||
|
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[input] = i
|
||||||
|
|
||||||
// ensure mappings have 1:1 output-to-destination correspondence
|
// ensure mappings have 1:1 output-to-destination correspondence
|
||||||
nOut := len(m.Outputs)
|
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 != nil {
|
||||||
if m.re.MatchString(input) {
|
if m.re.MatchString(input) {
|
||||||
if output := m.Outputs[destIdx]; output == nil {
|
if output := m.Outputs[destIdx]; output == nil {
|
||||||
break
|
continue
|
||||||
} else {
|
} else {
|
||||||
return output, true
|
return output, true
|
||||||
}
|
}
|
||||||
|
@ -137,7 +143,7 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt
|
||||||
}
|
}
|
||||||
if input == m.Input {
|
if input == m.Input {
|
||||||
if output := m.Outputs[destIdx]; output == nil {
|
if output := m.Outputs[destIdx]; output == nil {
|
||||||
break
|
continue
|
||||||
} else {
|
} else {
|
||||||
return output, true
|
return output, true
|
||||||
}
|
}
|
||||||
|
@ -176,7 +182,8 @@ type Mapping struct {
|
||||||
InputRegexp string `json:"input_regexp,omitempty"`
|
InputRegexp string `json:"input_regexp,omitempty"`
|
||||||
|
|
||||||
// Upon a match with the input, each output is positionally correlated
|
// 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"`
|
Outputs []interface{} `json:"outputs,omitempty"`
|
||||||
|
|
||||||
re *regexp.Regexp
|
re *regexp.Regexp
|
||||||
|
|
Loading…
Reference in New Issue
Block a user