diff --git a/caddytest/integration/map_test.go b/caddytest/integration/map_test.go index dc077ee7..aa535ecd 100644 --- a/caddytest/integration/map_test.go +++ b/caddytest/integration/map_test.go @@ -18,7 +18,7 @@ func TestMap(t *testing.T) { localhost:9080 { map {http.request.method} {dest-1} {dest-2} { - default unknown + default unknown1 unknown2 ~G.T get-called POST post-called foobar } @@ -30,7 +30,7 @@ func TestMap(t *testing.T) { `, "caddyfile") // act and assert - tester.AssertGetResponse("http://localhost:9080/version", 200, "hello from localhost get-called ") + tester.AssertGetResponse("http://localhost:9080/version", 200, "hello from localhost get-called unknown2") tester.AssertPostResponseBody("http://localhost:9080/version", []string{}, bytes.NewBuffer([]byte{}), 200, "hello from localhost post-called foobar") } diff --git a/modules/caddyhttp/map/caddyfile.go b/modules/caddyhttp/map/caddyfile.go index 67c148bd..eb0c5ae3 100644 --- a/modules/caddyhttp/map/caddyfile.go +++ b/modules/caddyhttp/map/caddyfile.go @@ -70,7 +70,10 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) // every other line maps one input to one or more outputs in := h.Val() - outs := h.RemainingArgs() + var outs []interface{} + for _, out := range h.RemainingArgs() { + outs = append(outs, out) + } // cannot have more outputs than destinations if len(outs) > len(handler.Destinations) { @@ -78,9 +81,9 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) } // for convenience, can have fewer outputs than destinations, but the - // underlying handler won't accept that, so we fill in empty values + // underlying handler won't accept that, so we fill in nil values for len(outs) < len(handler.Destinations) { - outs = append(outs, "") + outs = append(outs, nil) } // create the mapping diff --git a/modules/caddyhttp/map/map.go b/modules/caddyhttp/map/map.go index 29aa19f2..ba90e6f5 100644 --- a/modules/caddyhttp/map/map.go +++ b/modules/caddyhttp/map/map.go @@ -16,7 +16,6 @@ package maphandler import ( "fmt" - "log" "net/http" "regexp" "strings" @@ -40,14 +39,15 @@ type Handler struct { // Source is the placeholder from which to get the input value. Source string `json:"source,omitempty"` - // Destinations are the placeholders in which to store the outputs. + // Destinations are the names of placeholders in which to store the outputs. Destinations []string `json:"destinations,omitempty"` // Mappings from source values (inputs) to destination values (outputs). // The first matching mapping will be applied. Mappings []Mapping `json:"mappings,omitempty"` - // If no mappings match, the default value will be applied (optional). + // If no mappings match or if the mapped output is null/nil, the associated + // default output will be applied (optional). Defaults []string } @@ -125,20 +125,26 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt // find the first mapping matching the input and return // the requested destination/output value for _, m := range h.Mappings { - log.Printf("MAPPING: %+v", m) if m.re != nil { if m.re.MatchString(input) { - return m.Outputs[destIdx], true + if output := m.Outputs[destIdx]; output == nil { + break + } else { + return output, true + } } continue } if input == m.Input { - log.Printf("RETURNING: %s", m.Outputs[destIdx]) - return m.Outputs[destIdx], true + if output := m.Outputs[destIdx]; output == nil { + break + } else { + return output, true + } } } - // fall back to default if no match + // fall back to default if no match or if matched nil value if len(h.Defaults) > destIdx { return h.Defaults[destIdx], true } @@ -171,7 +177,7 @@ type Mapping struct { // Upon a match with the input, each output is positionally correlated // with each destination of the parent handler. - Outputs []string `json:"outputs,omitempty"` + Outputs []interface{} `json:"outputs,omitempty"` re *regexp.Regexp }