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

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