summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/matchers.go
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2019-05-22 13:13:39 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2019-05-22 13:13:39 -0600
commit284fb3a98cae2e6e6ca79327988230a3a916996a (patch)
treeee52b5d7f144cf6510d1689e1ce06887ec213685 /modules/caddyhttp/matchers.go
parentbc00d840e845d42145954839b88f1e836cd51bfd (diff)
Allow multiple matcher sets in routes (OR'ed together)
Also export MatchRegexp in case other matcher modules find it useful. Add comments to the exported matchers.
Diffstat (limited to 'modules/caddyhttp/matchers.go')
-rw-r--r--modules/caddyhttp/matchers.go72
1 files changed, 55 insertions, 17 deletions
diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go
index eb57156..33300da 100644
--- a/modules/caddyhttp/matchers.go
+++ b/modules/caddyhttp/matchers.go
@@ -17,16 +17,35 @@ import (
)
type (
- MatchHost []string
- MatchPath []string
- MatchPathRE struct{ matchRegexp }
- MatchMethod []string
- MatchQuery url.Values
- MatchHeader http.Header
- MatchHeaderRE map[string]*matchRegexp
- MatchProtocol string
+ // MatchHost matches requests by the Host value.
+ MatchHost []string
+
+ // MatchPath matches requests by the URI's path.
+ MatchPath []string
+
+ // MatchPathRE matches requests by a regular expression on the URI's path.
+ MatchPathRE struct{ MatchRegexp }
+
+ // MatchMethod matches requests by the method.
+ MatchMethod []string
+
+ // MatchQuery matches requests by URI's query string.
+ MatchQuery url.Values
+
+ // MatchHeader matches requests by header fields.
+ MatchHeader http.Header
+
+ // MatchHeaderRE matches requests by a regular expression on header fields.
+ MatchHeaderRE map[string]*MatchRegexp
+
+ // MatchProtocol matches requests by protocol.
+ MatchProtocol string
+
+ // MatchStarlarkExpr matches requests by evaluating a Starlark expression.
MatchStarlarkExpr string
- MatchTable string // TODO: finish implementing
+
+ // MatchTable matches requests by values in the table.
+ MatchTable string // TODO: finish implementing
)
func init() {
@@ -68,6 +87,7 @@ func init() {
})
}
+// Match returns true if r matches m.
func (m MatchHost) Match(r *http.Request) bool {
outer:
for _, host := range m {
@@ -93,6 +113,7 @@ outer:
return false
}
+// Match returns true if r matches m.
func (m MatchPath) Match(r *http.Request) bool {
for _, matchPath := range m {
compare := r.URL.Path
@@ -111,11 +132,13 @@ func (m MatchPath) Match(r *http.Request) bool {
return false
}
+// Match returns true if r matches m.
func (m MatchPathRE) Match(r *http.Request) bool {
repl := r.Context().Value(caddy2.ReplacerCtxKey).(caddy2.Replacer)
- return m.match(r.URL.Path, repl, "path_regexp")
+ return m.MatchRegexp.Match(r.URL.Path, repl, "path_regexp")
}
+// Match returns true if r matches m.
func (m MatchMethod) Match(r *http.Request) bool {
for _, method := range m {
if r.Method == method {
@@ -125,6 +148,7 @@ func (m MatchMethod) Match(r *http.Request) bool {
return false
}
+// Match returns true if r matches m.
func (m MatchQuery) Match(r *http.Request) bool {
for param, vals := range m {
paramVal := r.URL.Query().Get(param)
@@ -137,6 +161,7 @@ func (m MatchQuery) Match(r *http.Request) bool {
return false
}
+// Match returns true if r matches m.
func (m MatchHeader) Match(r *http.Request) bool {
for field, allowedFieldVals := range m {
var match bool
@@ -157,10 +182,11 @@ func (m MatchHeader) Match(r *http.Request) bool {
return true
}
+// Match returns true if r matches m.
func (m MatchHeaderRE) Match(r *http.Request) bool {
for field, rm := range m {
repl := r.Context().Value(caddy2.ReplacerCtxKey).(caddy2.Replacer)
- match := rm.match(r.Header.Get(field), repl, "header_regexp")
+ match := rm.Match(r.Header.Get(field), repl, "header_regexp")
if !match {
return false
}
@@ -168,6 +194,7 @@ func (m MatchHeaderRE) Match(r *http.Request) bool {
return true
}
+// Provision compiles m's regular expressions.
func (m MatchHeaderRE) Provision() error {
for _, rm := range m {
err := rm.Provision()
@@ -178,6 +205,7 @@ func (m MatchHeaderRE) Provision() error {
return nil
}
+// Validate validates m's regular expressions.
func (m MatchHeaderRE) Validate() error {
for _, rm := range m {
err := rm.Validate()
@@ -188,6 +216,7 @@ func (m MatchHeaderRE) Validate() error {
return nil
}
+// Match returns true if r matches m.
func (m MatchProtocol) Match(r *http.Request) bool {
switch string(m) {
case "grpc":
@@ -200,6 +229,7 @@ func (m MatchProtocol) Match(r *http.Request) bool {
return false
}
+// Match returns true if r matches m.
func (m MatchStarlarkExpr) Match(r *http.Request) bool {
input := string(m)
thread := new(starlark.Thread)
@@ -213,15 +243,16 @@ func (m MatchStarlarkExpr) Match(r *http.Request) bool {
return val.String() == "True"
}
-// matchRegexp is just the fields common among
-// matchers that can use regular expressions.
-type matchRegexp struct {
+// MatchRegexp is an embeddable type for matching
+// using regular expressions.
+type MatchRegexp struct {
Name string `json:"name"`
Pattern string `json:"pattern"`
compiled *regexp.Regexp
}
-func (mre *matchRegexp) Provision() error {
+// Provision compiles the regular expression.
+func (mre *MatchRegexp) Provision() error {
re, err := regexp.Compile(mre.Pattern)
if err != nil {
return fmt.Errorf("compiling matcher regexp %s: %v", mre.Pattern, err)
@@ -230,14 +261,21 @@ func (mre *matchRegexp) Provision() error {
return nil
}
-func (mre *matchRegexp) Validate() error {
+// Validate ensures mre is set up correctly.
+func (mre *MatchRegexp) Validate() error {
if mre.Name != "" && !wordRE.MatchString(mre.Name) {
return fmt.Errorf("invalid regexp name (must contain only word characters): %s", mre.Name)
}
return nil
}
-func (mre *matchRegexp) match(input string, repl caddy2.Replacer, scope string) bool {
+// Match returns true if input matches the compiled regular
+// expression in mre. It sets values on the replacer repl
+// associated with capture groups, using the given scope
+// (namespace). Capture groups stored to repl will take on
+// the name "http.matchers.<scope>.<mre.Name>.<N>" where
+// <N> is the name or number of the capture group.
+func (mre *MatchRegexp) Match(input string, repl caddy2.Replacer, scope string) bool {
matches := mre.compiled.FindStringSubmatch(input)
if matches == nil {
return false