@marcel91200 / caddy Mirror · read-only / commits / ef8a372a
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

map: Bug fixes; null literal with hyphen in Caddyfile

Matthew Holt committed Oct 2, 2020 at 16:08 UTC ef8a372a1ce8ed8630bbe227349783c5a74c69b2
2 files changed +25 -11
modules/caddyhttp/map/caddyfile.go
+8 -1
@@ -35,6 +35,9 @@ func init() {
35 // If the input value is prefixed with a tilde (~), then the input will be parsed as a
36 // regular expression.
37 //
38 +// The Caddyfile adapter treats outputs that are a literal hyphen (-) as a null/nil
39 +// value. This is useful if you want to fall back to default for that particular output.
40 +//
41 // The number of outputs for each mapping must not be more than the number of destinations.
42 // However, for convenience, there may be fewer outputs than destinations and any missing
43 // outputs will be filled in implicitly.
@@ -72,7 +75,11 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
75 in := h.Val()
76 var outs []interface{}
77 for _, out := range h.RemainingArgs() {
75 - outs = append(outs, out)
78 + if out == "-" {
79 + outs = append(outs, nil)
80 + } else {
81 + outs = append(outs, out)
82 + }
83 }
84
85 // cannot have more outputs than destinations
modules/caddyhttp/map/map.go
+17 -10
@@ -43,7 +43,7 @@ type Handler struct {
43 Destinations []string `json:"destinations,omitempty"`
44
45 // Mappings from source values (inputs) to destination values (outputs).
46 - // The first matching mapping will be applied.
46 + // The first matching, non-nil mapping will be applied.
47 Mappings []Mapping `json:"mappings,omitempty"`
48
49 // 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 {
69 if m.InputRegexp == "" {
70 continue
71 }
72 - if m.Input != "" {
73 - return fmt.Errorf("mapping %d has both input and input_regexp fields specified, which is confusing", i)
74 - }
72 var err error
73 h.Mappings[i].re, err = regexp.Compile(m.InputRegexp)
74 if err != nil {
@@ -94,11 +91,20 @@ func (h *Handler) Validate() error {
91
92 seen := make(map[string]int)
93 for i, m := range h.Mappings {
94 + // prevent confusing/ambiguous mappings
95 + if m.Input != "" && m.InputRegexp != "" {
96 + return fmt.Errorf("mapping %d has both input and input_regexp fields specified, which is confusing", i)
97 + }
98 +
99 // prevent duplicate mappings
98 - if prev, ok := seen[m.Input]; ok {
99 - return fmt.Errorf("mapping %d has a duplicate input '%s' previously used with mapping %d", i, m.Input, prev)
100 + input := m.Input
101 + if m.InputRegexp != "" {
102 + input = m.InputRegexp
103 + }
104 + if prev, ok := seen[input]; ok {
105 + return fmt.Errorf("mapping %d has a duplicate input '%s' previously used with mapping %d", i, input, prev)
106 }
101 - seen[m.Input] = i
107 + seen[input] = i
108
109 // ensure mappings have 1:1 output-to-destination correspondence
110 nOut := len(m.Outputs)
@@ -128,7 +134,7 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt
134 if m.re != nil {
135 if m.re.MatchString(input) {
136 if output := m.Outputs[destIdx]; output == nil {
131 - break
137 + continue
138 } else {
139 return output, true
140 }
@@ -137,7 +143,7 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt
143 }
144 if input == m.Input {
145 if output := m.Outputs[destIdx]; output == nil {
140 - break
146 + continue
147 } else {
148 return output, true
149 }
@@ -176,7 +182,8 @@ type Mapping struct {
182 InputRegexp string `json:"input_regexp,omitempty"`
183
184 // Upon a match with the input, each output is positionally correlated
179 - // with each destination of the parent handler.
185 + // with each destination of the parent handler. An output that is null
186 + // (nil) will be treated as if it was not mapped at all.
187 Outputs []interface{} `json:"outputs,omitempty"`
188
189 re *regexp.Regexp