@marcel91200 / caddy Mirror · read-only / commits / 6fd28b81
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

caddyhttp: Define MatcherSets and RawMatcherSets types

Matthew Holt committed Oct 5, 2019 at 16:20 UTC 6fd28b81dcfa41ea84e376d569d90a08e172e263
1 file changed +68 -42
modules/caddyhttp/routes.go
+68 -42
@@ -26,13 +26,13 @@ import (
26 // middlewares, and a responder for handling HTTP
27 // requests.
28 type Route struct {
29 - Group string `json:"group,omitempty"`
30 - MatcherSetsRaw []map[string]json.RawMessage `json:"match,omitempty"`
31 - HandlersRaw []json.RawMessage `json:"handle,omitempty"`
32 - Terminal bool `json:"terminal,omitempty"`
29 + Group string `json:"group,omitempty"`
30 + MatcherSetsRaw RawMatcherSets `json:"match,omitempty"`
31 + HandlersRaw []json.RawMessage `json:"handle,omitempty"`
32 + Terminal bool `json:"terminal,omitempty"`
33
34 // decoded values
35 - MatcherSets []MatcherSet `json:"-"`
35 + MatcherSets MatcherSets `json:"-"`
36 Handlers []MiddlewareHandler `json:"-"`
37 }
38
@@ -46,32 +46,6 @@ func (r Route) Empty() bool {
46 r.Group == ""
47 }
48
49 -func (r Route) anyMatcherSetMatches(req *http.Request) bool {
50 - for _, ms := range r.MatcherSets {
51 - if ms.Match(req) {
52 - return true
53 - }
54 - }
55 - // if no matchers, always match
56 - return len(r.MatcherSets) == 0
57 -}
58 -
59 -// MatcherSet is a set of matchers which
60 -// must all match in order for the request
61 -// to be matched successfully.
62 -type MatcherSet []RequestMatcher
63 -
64 -// Match returns true if the request matches all
65 -// matchers in mset.
66 -func (mset MatcherSet) Match(r *http.Request) bool {
67 - for _, m := range mset {
68 - if !m.Match(r) {
69 - return false
70 - }
71 - }
72 - return true
73 -}
74 -
49 // RouteList is a list of server routes that can
50 // create a middleware chain.
51 type RouteList []Route
@@ -80,17 +54,11 @@ type RouteList []Route
54 func (routes RouteList) Provision(ctx caddy.Context) error {
55 for i, route := range routes {
56 // matchers
83 - for _, matcherSet := range route.MatcherSetsRaw {
84 - var matchers MatcherSet
85 - for modName, rawMsg := range matcherSet {
86 - val, err := ctx.LoadModule("http.matchers."+modName, rawMsg)
87 - if err != nil {
88 - return fmt.Errorf("loading matcher module '%s': %v", modName, err)
89 - }
90 - matchers = append(matchers, val.(RequestMatcher))
91 - }
92 - routes[i].MatcherSets = append(routes[i].MatcherSets, matchers)
57 + matcherSets, err := route.MatcherSetsRaw.Setup(ctx)
58 + if err != nil {
59 + return err
60 }
61 + routes[i].MatcherSets = matcherSets
62 routes[i].MatcherSetsRaw = nil // allow GC to deallocate
63
64 // handlers
@@ -118,7 +86,7 @@ func (routes RouteList) BuildCompositeRoute(req *http.Request) Handler {
86
87 for _, route := range routes {
88 // route must match at least one of the matcher sets
121 - if !route.anyMatcherSetMatches(req) {
89 + if !route.MatcherSets.AnyMatch(req) {
90 continue
91 }
92
@@ -181,3 +149,61 @@ func wrapMiddleware(mh MiddlewareHandler) Middleware {
149 }
150 }
151 }
152 +
153 +// MatcherSet is a set of matchers which
154 +// must all match in order for the request
155 +// to be matched successfully.
156 +type MatcherSet []RequestMatcher
157 +
158 +// Match returns true if the request matches all
159 +// matchers in mset.
160 +func (mset MatcherSet) Match(r *http.Request) bool {
161 + for _, m := range mset {
162 + if !m.Match(r) {
163 + return false
164 + }
165 + }
166 + return true
167 +}
168 +
169 +// RawMatcherSets is a group of matcher sets
170 +// in their raw, JSON form.
171 +type RawMatcherSets []map[string]json.RawMessage
172 +
173 +// Setup sets up all matcher sets by loading each matcher module
174 +// and returning the group of provisioned matcher sets.
175 +func (rm RawMatcherSets) Setup(ctx caddy.Context) (MatcherSets, error) {
176 + if rm == nil {
177 + return nil, nil
178 + }
179 + var ms MatcherSets
180 + for _, matcherSet := range rm {
181 + var matchers MatcherSet
182 + for modName, rawMsg := range matcherSet {
183 + val, err := ctx.LoadModule("http.matchers."+modName, rawMsg)
184 + if err != nil {
185 + return nil, fmt.Errorf("loading matcher module '%s': %v", modName, err)
186 + }
187 + matchers = append(matchers, val.(RequestMatcher))
188 + }
189 + ms = append(ms, matchers)
190 + }
191 + return ms, nil
192 +}
193 +
194 +// MatcherSets is a group of matcher sets capable
195 +// of checking whether a request matches any of
196 +// the sets.
197 +type MatcherSets []MatcherSet
198 +
199 +// AnyMatch returns true if req matches any of the
200 +// matcher sets in mss or if there are no matchers,
201 +// in which case the request always matches.
202 +func (mss MatcherSets) AnyMatch(req *http.Request) bool {
203 + for _, ms := range mss {
204 + if ms.Match(req) {
205 + return true
206 + }
207 + }
208 + return len(mss) == 0
209 +}