aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFrancis Lavoie <[email protected]>2024-10-11 18:59:50 -0400
committerFrancis Lavoie <[email protected]>2024-11-04 14:10:51 -0500
commit565ce58feeb4786747cc3ea37429f97ddfda4c27 (patch)
tree98ab5627be912fbed874b4de404ee61911f8ecbf
parent03f463adf2da5a2c740a1c9259a2711a17e30912 (diff)
downloadcaddy-565ce58feeb4786747cc3ea37429f97ddfda4c27.tar.gz
caddy-565ce58feeb4786747cc3ea37429f97ddfda4c27.zip
Looser interface checking to allow fallback
-rw-r--r--caddyconfig/httpcaddyfile/httptype.go20
-rw-r--r--modules/caddyhttp/matchers.go24
-rw-r--r--modules/caddyhttp/routes.go37
3 files changed, 58 insertions, 23 deletions
diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go
index 704424acb..beee2d1a5 100644
--- a/caddyconfig/httpcaddyfile/httptype.go
+++ b/caddyconfig/httpcaddyfile/httptype.go
@@ -1466,9 +1466,9 @@ func (st *ServerType) compileEncodedMatcherSets(sblock serverBlock) ([]caddy.Mod
// iterate each pairing of host and path matchers and
// put them into a map for JSON encoding
- var matcherSets []map[string]caddyhttp.RequestMatcher
+ var matcherSets []map[string]caddyhttp.RequestMatcherWithError
for _, mp := range matcherPairs {
- matcherSet := make(map[string]caddyhttp.RequestMatcher)
+ matcherSet := make(map[string]caddyhttp.RequestMatcherWithError)
if len(mp.hostm) > 0 {
matcherSet["host"] = mp.hostm
}
@@ -1527,12 +1527,16 @@ func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.M
if err != nil {
return err
}
- rm, ok := unm.(caddyhttp.RequestMatcher)
- if !ok {
- return fmt.Errorf("matcher module '%s' is not a request matcher", matcherName)
+
+ if rm, ok := unm.(caddyhttp.RequestMatcherWithError); ok {
+ matchers[definitionName][matcherName] = caddyconfig.JSON(rm, nil)
+ return nil
}
- matchers[definitionName][matcherName] = caddyconfig.JSON(rm, nil)
- return nil
+ if rm, ok := unm.(caddyhttp.RequestMatcher); ok {
+ matchers[definitionName][matcherName] = caddyconfig.JSON(rm, nil)
+ return nil
+ }
+ return fmt.Errorf("matcher module '%s' is not a request matcher", matcherName)
}
// if the next token is quoted, we can assume it's not a matcher name
@@ -1576,7 +1580,7 @@ func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.M
return nil
}
-func encodeMatcherSet(matchers map[string]caddyhttp.RequestMatcher) (caddy.ModuleMap, error) {
+func encodeMatcherSet(matchers map[string]caddyhttp.RequestMatcherWithError) (caddy.ModuleMap, error) {
msEncoded := make(caddy.ModuleMap)
for matcherName, val := range matchers {
jsonBytes, err := json.Marshal(val)
diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go
index 427ecf3c9..2197faa70 100644
--- a/modules/caddyhttp/matchers.go
+++ b/modules/caddyhttp/matchers.go
@@ -1392,7 +1392,15 @@ func (m *MatchNot) Provision(ctx caddy.Context) error {
for _, modMap := range matcherSets.([]map[string]any) {
var ms MatcherSet
for _, modIface := range modMap {
- ms = append(ms, modIface.(RequestMatcher))
+ if mod, ok := modIface.(RequestMatcherWithError); ok {
+ ms = append(ms, mod)
+ continue
+ }
+ if mod, ok := modIface.(RequestMatcher); ok {
+ ms = append(ms, mod)
+ continue
+ }
+ return fmt.Errorf("module is not a request matcher: %T", modIface)
}
m.MatcherSets = append(m.MatcherSets, ms)
}
@@ -1536,7 +1544,7 @@ func (mre *MatchRegexp) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
// ParseCaddyfileNestedMatcher parses the Caddyfile tokens for a nested
// matcher set, and returns its raw module map value.
func ParseCaddyfileNestedMatcherSet(d *caddyfile.Dispenser) (caddy.ModuleMap, error) {
- matcherMap := make(map[string]RequestMatcher)
+ matcherMap := make(map[string]any)
// in case there are multiple instances of the same matcher, concatenate
// their tokens (we expect that UnmarshalCaddyfile should be able to
@@ -1561,11 +1569,15 @@ func ParseCaddyfileNestedMatcherSet(d *caddyfile.Dispenser) (caddy.ModuleMap, er
if err != nil {
return nil, err
}
- rm, ok := unm.(RequestMatcher)
- if !ok {
- return nil, fmt.Errorf("matcher module '%s' is not a request matcher", matcherName)
+ if rm, ok := unm.(RequestMatcherWithError); ok {
+ matcherMap[matcherName] = rm
+ continue
+ }
+ if rm, ok := unm.(RequestMatcher); ok {
+ matcherMap[matcherName] = rm
+ continue
}
- matcherMap[matcherName] = rm
+ return nil, fmt.Errorf("matcher module '%s' is not a request matcher", matcherName)
}
// we should now have a functional matcher, but we also
diff --git a/modules/caddyhttp/routes.go b/modules/caddyhttp/routes.go
index 9576070f6..392555c56 100644
--- a/modules/caddyhttp/routes.go
+++ b/modules/caddyhttp/routes.go
@@ -336,15 +336,26 @@ func wrapMiddleware(ctx caddy.Context, mh MiddlewareHandler, metrics *Metrics) M
// MatcherSet is a set of matchers which
// must all match in order for the request
// to be matched successfully.
-type MatcherSet []RequestMatcher
+type MatcherSet []any
// Match returns true if the request matches all
// matchers in mset or if there are no matchers.
func (mset MatcherSet) Match(r *http.Request) bool {
for _, m := range mset {
- if !m.Match(r) {
- return false
+ if me, ok := m.(RequestMatcherWithError); ok {
+ match, _ := me.MatchWithError(r)
+ if !match {
+ return false
+ }
+ continue
+ }
+ if me, ok := m.(RequestMatcher); ok {
+ if !me.Match(r) {
+ return false
+ }
+ continue
}
+ return false
}
return true
}
@@ -357,8 +368,10 @@ func (mset MatcherSet) MatchWithError(r *http.Request) (bool, error) {
if err != nil || !match {
return match, err
}
- } else {
- if !m.Match(r) {
+ continue
+ }
+ if me, ok := m.(RequestMatcher); ok {
+ if !me.Match(r) {
// for backwards compatibility
err, ok := GetVar(r.Context(), MatcherErrorVarKey).(error)
if ok {
@@ -368,7 +381,9 @@ func (mset MatcherSet) MatchWithError(r *http.Request) (bool, error) {
}
return false, nil
}
+ continue
}
+ return false, fmt.Errorf("matcher is not a RequestMatcher or RequestMatcherWithError: %#v", m)
}
return true, nil
}
@@ -401,11 +416,15 @@ func (ms *MatcherSets) FromInterface(matcherSets any) error {
for _, matcherSetIfaces := range matcherSets.([]map[string]any) {
var matcherSet MatcherSet
for _, matcher := range matcherSetIfaces {
- reqMatcher, ok := matcher.(RequestMatcher)
- if !ok {
- return fmt.Errorf("decoded module is not a RequestMatcher: %#v", matcher)
+ if m, ok := matcher.(RequestMatcherWithError); ok {
+ matcherSet = append(matcherSet, m)
+ continue
+ }
+ if m, ok := matcher.(RequestMatcher); ok {
+ matcherSet = append(matcherSet, m)
+ continue
}
- matcherSet = append(matcherSet, reqMatcher)
+ return fmt.Errorf("decoded module is not a RequestMatcher or RequestMatcherWithError: %#v", matcher)
}
*ms = append(*ms, matcherSet)
}