mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-19 06:02:44 +08:00
caddyhttp: Define MatcherSets and RawMatcherSets types
This commit is contained in:
parent
65c060f56e
commit
6fd28b81dc
|
@ -26,13 +26,13 @@ import (
|
|||
// middlewares, and a responder for handling HTTP
|
||||
// requests.
|
||||
type Route struct {
|
||||
Group string `json:"group,omitempty"`
|
||||
MatcherSetsRaw []map[string]json.RawMessage `json:"match,omitempty"`
|
||||
HandlersRaw []json.RawMessage `json:"handle,omitempty"`
|
||||
Terminal bool `json:"terminal,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
MatcherSetsRaw RawMatcherSets `json:"match,omitempty"`
|
||||
HandlersRaw []json.RawMessage `json:"handle,omitempty"`
|
||||
Terminal bool `json:"terminal,omitempty"`
|
||||
|
||||
// decoded values
|
||||
MatcherSets []MatcherSet `json:"-"`
|
||||
MatcherSets MatcherSets `json:"-"`
|
||||
Handlers []MiddlewareHandler `json:"-"`
|
||||
}
|
||||
|
||||
|
@ -46,32 +46,6 @@ func (r Route) Empty() bool {
|
|||
r.Group == ""
|
||||
}
|
||||
|
||||
func (r Route) anyMatcherSetMatches(req *http.Request) bool {
|
||||
for _, ms := range r.MatcherSets {
|
||||
if ms.Match(req) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// if no matchers, always match
|
||||
return len(r.MatcherSets) == 0
|
||||
}
|
||||
|
||||
// MatcherSet is a set of matchers which
|
||||
// must all match in order for the request
|
||||
// to be matched successfully.
|
||||
type MatcherSet []RequestMatcher
|
||||
|
||||
// Match returns true if the request matches all
|
||||
// matchers in mset.
|
||||
func (mset MatcherSet) Match(r *http.Request) bool {
|
||||
for _, m := range mset {
|
||||
if !m.Match(r) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// RouteList is a list of server routes that can
|
||||
// create a middleware chain.
|
||||
type RouteList []Route
|
||||
|
@ -80,17 +54,11 @@ type RouteList []Route
|
|||
func (routes RouteList) Provision(ctx caddy.Context) error {
|
||||
for i, route := range routes {
|
||||
// matchers
|
||||
for _, matcherSet := range route.MatcherSetsRaw {
|
||||
var matchers MatcherSet
|
||||
for modName, rawMsg := range matcherSet {
|
||||
val, err := ctx.LoadModule("http.matchers."+modName, rawMsg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading matcher module '%s': %v", modName, err)
|
||||
}
|
||||
matchers = append(matchers, val.(RequestMatcher))
|
||||
}
|
||||
routes[i].MatcherSets = append(routes[i].MatcherSets, matchers)
|
||||
matcherSets, err := route.MatcherSetsRaw.Setup(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
routes[i].MatcherSets = matcherSets
|
||||
routes[i].MatcherSetsRaw = nil // allow GC to deallocate
|
||||
|
||||
// handlers
|
||||
|
@ -118,7 +86,7 @@ func (routes RouteList) BuildCompositeRoute(req *http.Request) Handler {
|
|||
|
||||
for _, route := range routes {
|
||||
// route must match at least one of the matcher sets
|
||||
if !route.anyMatcherSetMatches(req) {
|
||||
if !route.MatcherSets.AnyMatch(req) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -181,3 +149,61 @@ func wrapMiddleware(mh MiddlewareHandler) Middleware {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MatcherSet is a set of matchers which
|
||||
// must all match in order for the request
|
||||
// to be matched successfully.
|
||||
type MatcherSet []RequestMatcher
|
||||
|
||||
// Match returns true if the request matches all
|
||||
// matchers in mset.
|
||||
func (mset MatcherSet) Match(r *http.Request) bool {
|
||||
for _, m := range mset {
|
||||
if !m.Match(r) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// RawMatcherSets is a group of matcher sets
|
||||
// in their raw, JSON form.
|
||||
type RawMatcherSets []map[string]json.RawMessage
|
||||
|
||||
// Setup sets up all matcher sets by loading each matcher module
|
||||
// and returning the group of provisioned matcher sets.
|
||||
func (rm RawMatcherSets) Setup(ctx caddy.Context) (MatcherSets, error) {
|
||||
if rm == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var ms MatcherSets
|
||||
for _, matcherSet := range rm {
|
||||
var matchers MatcherSet
|
||||
for modName, rawMsg := range matcherSet {
|
||||
val, err := ctx.LoadModule("http.matchers."+modName, rawMsg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loading matcher module '%s': %v", modName, err)
|
||||
}
|
||||
matchers = append(matchers, val.(RequestMatcher))
|
||||
}
|
||||
ms = append(ms, matchers)
|
||||
}
|
||||
return ms, nil
|
||||
}
|
||||
|
||||
// MatcherSets is a group of matcher sets capable
|
||||
// of checking whether a request matches any of
|
||||
// the sets.
|
||||
type MatcherSets []MatcherSet
|
||||
|
||||
// AnyMatch returns true if req matches any of the
|
||||
// matcher sets in mss or if there are no matchers,
|
||||
// in which case the request always matches.
|
||||
func (mss MatcherSets) AnyMatch(req *http.Request) bool {
|
||||
for _, ms := range mss {
|
||||
if ms.Match(req) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return len(mss) == 0
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user