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
+}