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