From f9cba03d251018c77ce2fa25ce018e2b1b179292 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Thu, 28 Sep 2017 11:41:11 -0600 Subject: [PATCH] redir: Do not count multiple rules with if statements as duplicates This allows you to have multiple redir directives conditioned solely upon if statements, without regard to path. --- caddyhttp/httpserver/condition.go | 6 ++++-- caddyhttp/redirect/setup.go | 9 ++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/caddyhttp/httpserver/condition.go b/caddyhttp/httpserver/condition.go index 5d7550d7..314cee51 100644 --- a/caddyhttp/httpserver/condition.go +++ b/caddyhttp/httpserver/condition.go @@ -40,6 +40,7 @@ func SetupIfMatcher(controller *caddy.Controller) (RequestMatcher, error) { return matcher, err } matcher.ifs = append(matcher.ifs, ifc) + matcher.Enabled = true case "if_op": if !c.NextArg() { return matcher, c.ArgErr() @@ -155,8 +156,9 @@ func (i ifCond) True(r *http.Request) bool { // IfMatcher is a RequestMatcher for 'if' conditions. type IfMatcher struct { - ifs []ifCond // list of If - isOr bool // if true, conditions are 'or' instead of 'and' + Enabled bool // if true, matcher has been configured; otherwise it's no-op + ifs []ifCond // list of If + isOr bool // if true, conditions are 'or' instead of 'and' } // Match satisfies RequestMatcher interface. diff --git a/caddyhttp/redirect/setup.go b/caddyhttp/redirect/setup.go index 8e5ed7d8..7813fe24 100644 --- a/caddyhttp/redirect/setup.go +++ b/caddyhttp/redirect/setup.go @@ -101,9 +101,12 @@ func redirParse(c *caddy.Controller) ([]Rule, error) { return c.Err("'from' and 'to' values of redirect rule cannot be the same") } - for _, otherRule := range redirects { - if otherRule.FromPath == rule.FromPath { - return c.Errf("rule with duplicate 'from' value: %s -> %s", otherRule.FromPath, otherRule.To) + // prevent obvious duplicates (rules with if statements exempt) + if ifm, ok := rule.RequestMatcher.(httpserver.IfMatcher); !ok || !ifm.Enabled { + for _, otherRule := range redirects { + if otherRule.FromPath == rule.FromPath { + return c.Errf("rule with duplicate 'from' value: %s -> %s", otherRule.FromPath, otherRule.To) + } } }