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: Allow handler order to be customized
Matthew Holt committed
Aug 22, 2019 at 14:26 UTC
e34ff21a7183969afb4150f1f7a1f71b9a1dd0d6
2 files changed
+42
-10
caddyconfig/httpcaddyfile/httptype.go
+19
-10
@@ -66,6 +66,8 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
66
val, err = parseHTTPPort(caddyfile.NewDispenser(segment))
67
case "https_port":
68
val, err = parseHTTPSPort(caddyfile.NewDispenser(segment))
69
+ case "handler_order":
70
+ val, err = parseHandlerOrder(caddyfile.NewDispenser(segment))
71
default:
72
return nil, warnings, fmt.Errorf("unrecognized parameter name: %s", dir)
73
}
@@ -148,7 +150,7 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
150
151
// each pairing of listener addresses to list of server
152
// blocks is basically a server definition
151
- servers, err := st.serversFromPairings(pairings, &warnings)
153
+ servers, err := st.serversFromPairings(pairings, options, &warnings)
154
if err != nil {
155
return nil, warnings, err
156
}
@@ -230,7 +232,11 @@ func (st *ServerType) hostsFromServerBlockKeys(sb caddyfile.ServerBlock) ([]stri
232
233
// serversFromPairings creates the servers for each pairing of addresses
234
// to server blocks. Each pairing is essentially a server definition.
233
-func (st *ServerType) serversFromPairings(pairings []sbAddrAssociation, warnings *[]caddyconfig.Warning) (map[string]*caddyhttp.Server, error) {
235
+func (st *ServerType) serversFromPairings(
236
+ pairings []sbAddrAssociation,
237
+ options map[string]interface{},
238
+ warnings *[]caddyconfig.Warning,
239
+) (map[string]*caddyhttp.Server, error) {
240
servers := make(map[string]*caddyhttp.Server)
241
242
for i, p := range pairings {
@@ -289,16 +295,19 @@ func (st *ServerType) serversFromPairings(pairings []sbAddrAssociation, warnings
295
siteVarSubroute.Routes = append(siteVarSubroute.Routes, cfgVal.Value.(caddyhttp.Route))
296
}
297
292
- // set up each handler directive
298
+ // set up each handler directive - the order of the handlers
299
+ // as they are added to the routes depends on user preference
300
dirRoutes := sblock.pile["route"]
294
- // TODO: The ordering here depends on... if there is a list of
295
- // directives to use, then sort by that, otherwise just use in
296
- // the order they appear in the slice (which is the order they
297
- // appeared in the Caddyfile)
298
- sortByList := true
299
- if sortByList {
301
+ handlerOrder, ok := options["handler_order"].([]string)
302
+ if !ok {
303
+ handlerOrder = defaultDirectiveOrder
304
+ }
305
+ if len(handlerOrder) == 1 && handlerOrder[0] == "appearance" {
306
+ handlerOrder = nil
307
+ }
308
+ if handlerOrder != nil {
309
dirPositions := make(map[string]int)
301
- for i, dir := range defaultDirectiveOrder {
310
+ for i, dir := range handlerOrder {
311
dirPositions[dir] = i
312
}
313
sort.SliceStable(dirRoutes, func(i, j int) bool {
caddyconfig/httpcaddyfile/options.go
renamed
+23
@@ -51,3 +51,26 @@ func parseHTTPSPort(d *caddyfile.Dispenser) (int, error) {
51
}
52
return httpsPort, nil
53
}
54
+
55
+func parseHandlerOrder(d *caddyfile.Dispenser) ([]string, error) {
56
+ if !d.Next() {
57
+ return nil, d.ArgErr()
58
+ }
59
+ order := d.RemainingArgs()
60
+ if len(order) == 1 && order[0] == "appearance" {
61
+ return []string{"appearance"}, nil
62
+ }
63
+ if len(order) > 0 && d.NextBlock() {
64
+ return nil, d.Err("cannot open block if there are arguments")
65
+ }
66
+ for d.NextBlock() {
67
+ order = append(order, d.Val())
68
+ if d.NextArg() {
69
+ return nil, d.ArgErr()
70
+ }
71
+ }
72
+ if len(order) == 0 {
73
+ return nil, d.ArgErr()
74
+ }
75
+ return order, nil
76
+}