caddyfile: Add support for vars and vars_regexp matchers (#3730)

* caddyfile: support vars and vars_regexp matchers in the caddyfile

* caddyfile: matchers: Brian Kernighan said printf is good debugging tool but didn't say keep them around
This commit is contained in:
Mohammed Al Sahaf 2020-09-26 02:50:26 +03:00 committed by GitHub
parent f197cec7f3
commit a33e4b5426
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 109 additions and 0 deletions

View file

@ -9,6 +9,15 @@
@matcher3 not method PUT @matcher3 not method PUT
respond @matcher3 "not put" respond @matcher3 "not put"
@matcher4 vars "{http.request.uri}" "/vars-matcher"
respond @matcher4 "from vars matcher"
@matcher5 vars_regexp static "{http.request.uri}" `\.([a-f0-9]{6})\.(css|js)$`
respond @matcher5 "from vars_regexp matcher with name"
@matcher6 vars_regexp "{http.request.uri}" `\.([a-f0-9]{6})\.(css|js)$`
respond @matcher6 "from vars_regexp matcher without name"
} }
---------- ----------
{ {
@ -68,6 +77,56 @@
"handler": "static_response" "handler": "static_response"
} }
] ]
},
{
"match": [
{
"vars": {
"{http.request.uri}": "/vars-matcher"
}
}
],
"handle": [
{
"body": "from vars matcher",
"handler": "static_response"
}
]
},
{
"match": [
{
"vars_regexp": {
"{http.request.uri}": {
"name": "static",
"pattern": "\\.([a-f0-9]{6})\\.(css|js)$"
}
}
}
],
"handle": [
{
"body": "from vars_regexp matcher with name",
"handler": "static_response"
}
]
},
{
"match": [
{
"vars_regexp": {
"{http.request.uri}": {
"pattern": "\\.([a-f0-9]{6})\\.(css|js)$"
}
}
}
],
"handle": [
{
"body": "from vars_regexp matcher without name",
"handler": "static_response"
}
]
} }
] ]
} }

View file

@ -927,6 +927,8 @@ var (
_ caddyfile.Unmarshaler = (*MatchHeaderRE)(nil) _ caddyfile.Unmarshaler = (*MatchHeaderRE)(nil)
_ caddyfile.Unmarshaler = (*MatchProtocol)(nil) _ caddyfile.Unmarshaler = (*MatchProtocol)(nil)
_ caddyfile.Unmarshaler = (*MatchRemoteIP)(nil) _ caddyfile.Unmarshaler = (*MatchRemoteIP)(nil)
_ caddyfile.Unmarshaler = (*VarsMatcher)(nil)
_ caddyfile.Unmarshaler = (*MatchVarsRE)(nil)
_ json.Marshaler = (*MatchNot)(nil) _ json.Marshaler = (*MatchNot)(nil)
_ json.Unmarshaler = (*MatchNot)(nil) _ json.Unmarshaler = (*MatchNot)(nil)

View file

@ -20,6 +20,7 @@ import (
"net/http" "net/http"
"github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
) )
func init() { func init() {
@ -64,6 +65,24 @@ func (VarsMatcher) CaddyModule() caddy.ModuleInfo {
} }
} }
// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
func (m *VarsMatcher) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
if *m == nil {
*m = make(map[string]string)
}
for d.Next() {
var field, val string
if !d.Args(&field, &val) {
return d.Errf("malformed vars matcher: expected both field and value")
}
(*m)[field] = val
if d.NextBlock(0) {
return d.Err("malformed vars matcher: blocks are not supported")
}
}
return nil
}
// Match matches a request based on variables in the context. // Match matches a request based on variables in the context.
func (m VarsMatcher) Match(r *http.Request) bool { func (m VarsMatcher) Match(r *http.Request) bool {
vars := r.Context().Value(VarsCtxKey).(map[string]interface{}) vars := r.Context().Value(VarsCtxKey).(map[string]interface{})
@ -106,6 +125,35 @@ func (MatchVarsRE) CaddyModule() caddy.ModuleInfo {
} }
} }
// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
func (m *MatchVarsRE) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
if *m == nil {
*m = make(map[string]*MatchRegexp)
}
for d.Next() {
var first, second, third string
if !d.Args(&first, &second) {
return d.ArgErr()
}
var name, field, val string
if d.Args(&third) {
name = first
field = second
val = third
} else {
field = first
val = second
}
(*m)[field] = &MatchRegexp{Pattern: val, Name: name}
if d.NextBlock(0) {
return d.Err("malformed vars_regexp matcher: blocks are not supported")
}
}
return nil
}
// Provision compiles m's regular expressions. // Provision compiles m's regular expressions.
func (m MatchVarsRE) Provision(ctx caddy.Context) error { func (m MatchVarsRE) Provision(ctx caddy.Context) error {
for _, rm := range m { for _, rm := range m {