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
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
Mohammed Al Sahaf committed
Sep 26, 2020 at 02:50 UTC
a33e4b542689cbe7ac711e3cfde1d2a30c0156ae
3 files changed
+109
caddytest/integration/caddyfile_adapt/matcher_syntax.txt
+59
@@ -9,6 +9,15 @@
9
10
@matcher3 not method PUT
11
respond @matcher3 "not put"
12
+
13
+ @matcher4 vars "{http.request.uri}" "/vars-matcher"
14
+ respond @matcher4 "from vars matcher"
15
+
16
+ @matcher5 vars_regexp static "{http.request.uri}" `\.([a-f0-9]{6})\.(css|js)$`
17
+ respond @matcher5 "from vars_regexp matcher with name"
18
+
19
+ @matcher6 vars_regexp "{http.request.uri}" `\.([a-f0-9]{6})\.(css|js)$`
20
+ respond @matcher6 "from vars_regexp matcher without name"
21
}
22
----------
23
{
@@ -68,6 +77,56 @@
77
"handler": "static_response"
78
}
79
]
80
+ },
81
+ {
82
+ "match": [
83
+ {
84
+ "vars": {
85
+ "{http.request.uri}": "/vars-matcher"
86
+ }
87
+ }
88
+ ],
89
+ "handle": [
90
+ {
91
+ "body": "from vars matcher",
92
+ "handler": "static_response"
93
+ }
94
+ ]
95
+ },
96
+ {
97
+ "match": [
98
+ {
99
+ "vars_regexp": {
100
+ "{http.request.uri}": {
101
+ "name": "static",
102
+ "pattern": "\\.([a-f0-9]{6})\\.(css|js)$"
103
+ }
104
+ }
105
+ }
106
+ ],
107
+ "handle": [
108
+ {
109
+ "body": "from vars_regexp matcher with name",
110
+ "handler": "static_response"
111
+ }
112
+ ]
113
+ },
114
+ {
115
+ "match": [
116
+ {
117
+ "vars_regexp": {
118
+ "{http.request.uri}": {
119
+ "pattern": "\\.([a-f0-9]{6})\\.(css|js)$"
120
+ }
121
+ }
122
+ }
123
+ ],
124
+ "handle": [
125
+ {
126
+ "body": "from vars_regexp matcher without name",
127
+ "handler": "static_response"
128
+ }
129
+ ]
130
}
131
]
132
}
modules/caddyhttp/matchers.go
+2
@@ -927,6 +927,8 @@ var (
927
_ caddyfile.Unmarshaler = (*MatchHeaderRE)(nil)
928
_ caddyfile.Unmarshaler = (*MatchProtocol)(nil)
929
_ caddyfile.Unmarshaler = (*MatchRemoteIP)(nil)
930
+ _ caddyfile.Unmarshaler = (*VarsMatcher)(nil)
931
+ _ caddyfile.Unmarshaler = (*MatchVarsRE)(nil)
932
933
_ json.Marshaler = (*MatchNot)(nil)
934
_ json.Unmarshaler = (*MatchNot)(nil)
modules/caddyhttp/vars.go
+48
@@ -20,6 +20,7 @@ import (
20
"net/http"
21
22
"github.com/caddyserver/caddy/v2"
23
+ "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
24
)
25
26
func init() {
@@ -64,6 +65,24 @@ func (VarsMatcher) CaddyModule() caddy.ModuleInfo {
65
}
66
}
67
68
+// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
69
+func (m *VarsMatcher) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
70
+ if *m == nil {
71
+ *m = make(map[string]string)
72
+ }
73
+ for d.Next() {
74
+ var field, val string
75
+ if !d.Args(&field, &val) {
76
+ return d.Errf("malformed vars matcher: expected both field and value")
77
+ }
78
+ (*m)[field] = val
79
+ if d.NextBlock(0) {
80
+ return d.Err("malformed vars matcher: blocks are not supported")
81
+ }
82
+ }
83
+ return nil
84
+}
85
+
86
// Match matches a request based on variables in the context.
87
func (m VarsMatcher) Match(r *http.Request) bool {
88
vars := r.Context().Value(VarsCtxKey).(map[string]interface{})
@@ -106,6 +125,35 @@ func (MatchVarsRE) CaddyModule() caddy.ModuleInfo {
125
}
126
}
127
128
+// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
129
+func (m *MatchVarsRE) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
130
+ if *m == nil {
131
+ *m = make(map[string]*MatchRegexp)
132
+ }
133
+ for d.Next() {
134
+ var first, second, third string
135
+ if !d.Args(&first, &second) {
136
+ return d.ArgErr()
137
+ }
138
+
139
+ var name, field, val string
140
+ if d.Args(&third) {
141
+ name = first
142
+ field = second
143
+ val = third
144
+ } else {
145
+ field = first
146
+ val = second
147
+ }
148
+
149
+ (*m)[field] = &MatchRegexp{Pattern: val, Name: name}
150
+ if d.NextBlock(0) {
151
+ return d.Err("malformed vars_regexp matcher: blocks are not supported")
152
+ }
153
+ }
154
+ return nil
155
+}
156
+
157
// Provision compiles m's regular expressions.
158
func (m MatchVarsRE) Provision(ctx caddy.Context) error {
159
for _, rm := range m {