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
httpcaddyfile: Group try_files routes together (#2891)
This ensures that only the first matching route is used.
Matthew Holt committed
Jan 16, 2020 at 11:29 UTC
2466ed148466ee17fb4da6d2d732e1a16f0469a6
3 files changed
+44
-9
caddyconfig/httpcaddyfile/directives.go
+32
-4
@@ -16,6 +16,7 @@ package httpcaddyfile
16
17
import (
18
"encoding/json"
19
+ "fmt"
20
"sort"
21
22
"github.com/caddyserver/caddy/v2"
@@ -93,10 +94,11 @@ func RegisterHandlerDirective(dir string, setupFunc UnmarshalHandlerFunc) {
94
// Caddyfile tokens.
95
type Helper struct {
96
*caddyfile.Dispenser
96
- options map[string]interface{}
97
- warnings *[]caddyconfig.Warning
98
- matcherDefs map[string]caddy.ModuleMap
99
- parentBlock caddyfile.ServerBlock
97
+ options map[string]interface{}
98
+ warnings *[]caddyconfig.Warning
99
+ matcherDefs map[string]caddy.ModuleMap
100
+ parentBlock caddyfile.ServerBlock
101
+ groupCounter *int
102
}
103
104
// Option gets the option keyed by name.
@@ -166,6 +168,32 @@ func (h Helper) NewRoute(matcherSet caddy.ModuleMap,
168
}
169
}
170
171
+func (h Helper) GroupRoutes(vals []ConfigValue) {
172
+ // ensure there's at least two routes; group of one is pointless
173
+ var count int
174
+ for _, v := range vals {
175
+ if _, ok := v.Value.(caddyhttp.Route); ok {
176
+ count++
177
+ if count > 1 {
178
+ break
179
+ }
180
+ }
181
+ }
182
+ if count < 2 {
183
+ return
184
+ }
185
+
186
+ // now that we know the group will have some effect, do it
187
+ groupNum := *h.groupCounter
188
+ for i := 0; i < len(vals); i++ {
189
+ if route, ok := vals[i].Value.(caddyhttp.Route); ok {
190
+ route.Group = fmt.Sprintf("group%d", groupNum)
191
+ vals[i].Value = route
192
+ }
193
+ }
194
+ *h.groupCounter++
195
+}
196
+
197
// NewBindAddresses returns config values relevant to adding
198
// listener bind addresses to the config.
199
func (h Helper) NewBindAddresses(addrs []string) []ConfigValue {
caddyconfig/httpcaddyfile/httptype.go
+7
-5
@@ -41,6 +41,7 @@ type ServerType struct {
41
func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
42
options map[string]interface{}) (*caddy.Config, []caddyconfig.Warning, error) {
43
var warnings []caddyconfig.Warning
44
+ groupCounter := new(int)
45
46
var serverBlocks []serverBlock
47
for _, sblock := range originalServerBlocks {
@@ -140,11 +141,12 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
141
}
142
143
results, err := dirFunc(Helper{
143
- Dispenser: caddyfile.NewDispenser(segment),
144
- options: options,
145
- warnings: &warnings,
146
- matcherDefs: matcherDefs,
147
- parentBlock: sb.block,
144
+ Dispenser: caddyfile.NewDispenser(segment),
145
+ options: options,
146
+ warnings: &warnings,
147
+ matcherDefs: matcherDefs,
148
+ parentBlock: sb.block,
149
+ groupCounter: groupCounter,
150
})
151
if err != nil {
152
return nil, warnings, fmt.Errorf("parsing caddyfile tokens for '%s': %v", dir, err)
modules/caddyhttp/fileserver/caddyfile.go
+5
@@ -163,5 +163,10 @@ func parseTryFiles(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error)
163
result = append(result, makeRoute(try, "")...)
164
}
165
166
+ // ensure that multiple routes (possible if rewrite targets
167
+ // have query strings, for example) are grouped together
168
+ // so only the first matching rewrite is performed (#2891)
169
+ h.GroupRoutes(result)
170
+
171
return result, nil
172
}