@marcel91200 / caddy Mirror · read-only / commits / 2466ed14
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

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 }