summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/matchers.go
diff options
context:
space:
mode:
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