diff options
author | Matthew Holt <[email protected]> | 2020-01-16 12:09:54 -0700 |
---|---|---|
committer | Matthew Holt <[email protected]> | 2020-01-16 12:09:54 -0700 |
commit | 21643a007a2d2d90e1636ecd6b49f82560f4c939 (patch) | |
tree | 178b8495b693c303be429feb38c7ea4af3f50bde /caddyconfig/httpcaddyfile/options.go | |
parent | 2466ed148466ee17fb4da6d2d732e1a16f0469a6 (diff) | |
download | caddy-21643a007a2d2d90e1636ecd6b49f82560f4c939.tar.gz caddy-21643a007a2d2d90e1636ecd6b49f82560f4c939.zip |
httpcaddyfile: Replace 'handler_order' option with 'order'
This allows individual directives to be ordered relative to others,
where order matters (for example HTTP handlers). Will primarily be
useful when developing new directives, so you don't have to modify the
Caddy source code. Can also be useful if you prefer that redir comes
before rewrite, for example. Note that these are global options. The
route directive can be used to give a specific order to a specific group
of HTTP handler directives.
Diffstat (limited to 'caddyconfig/httpcaddyfile/options.go')
-rw-r--r-- | caddyconfig/httpcaddyfile/options.go | 87 |
1 files changed, 70 insertions, 17 deletions
diff --git a/caddyconfig/httpcaddyfile/options.go b/caddyconfig/httpcaddyfile/options.go index e87b30f84..e81528e10 100644 --- a/caddyconfig/httpcaddyfile/options.go +++ b/caddyconfig/httpcaddyfile/options.go @@ -58,27 +58,80 @@ func parseOptExperimentalHTTP3(d *caddyfile.Dispenser) (bool, error) { return true, nil } -func parseOptHandlerOrder(d *caddyfile.Dispenser) ([]string, error) { - if !d.Next() { - return nil, d.ArgErr() - } - order := d.RemainingArgs() - if len(order) == 1 && order[0] == "appearance" { - return []string{"appearance"}, nil - } - if len(order) > 0 && d.NextBlock(0) { - return nil, d.Err("cannot open block if there are arguments") - } - for d.NextBlock(0) { - order = append(order, d.Val()) +func parseOptOrder(d *caddyfile.Dispenser) ([]string, error) { + newOrder := directiveOrder + + for d.Next() { + // get directive name + if !d.Next() { + return nil, d.ArgErr() + } + dirName := d.Val() + if _, ok := registeredDirectives[dirName]; !ok { + return nil, fmt.Errorf("%s is not a registered directive", dirName) + } + + // get positional token + if !d.Next() { + return nil, d.ArgErr() + } + pos := d.Val() + + // if directive exists, first remove it + for i, d := range newOrder { + if d == dirName { + newOrder = append(newOrder[:i], newOrder[i+1:]...) + break + } + } + + // act on the positional + switch pos { + case "first": + newOrder = append([]string{dirName}, newOrder...) + if d.NextArg() { + return nil, d.ArgErr() + } + directiveOrder = newOrder + return newOrder, nil + case "last": + newOrder = append(newOrder, dirName) + if d.NextArg() { + return nil, d.ArgErr() + } + directiveOrder = newOrder + return newOrder, nil + case "before": + case "after": + default: + return nil, fmt.Errorf("unknown positional '%s'", pos) + } + + // get name of other directive + if !d.NextArg() { + return nil, d.ArgErr() + } + otherDir := d.Val() if d.NextArg() { return nil, d.ArgErr() } + + // insert directive into proper position + for i, d := range newOrder { + if d == otherDir { + if pos == "before" { + newOrder = append(newOrder[:i], append([]string{dirName}, newOrder[i:]...)...) + } else if pos == "after" { + newOrder = append(newOrder[:i+1], append([]string{dirName}, newOrder[i+1:]...)...) + } + break + } + } } - if len(order) == 0 { - return nil, d.ArgErr() - } - return order, nil + + directiveOrder = newOrder + + return newOrder, nil } func parseOptStorage(d *caddyfile.Dispenser) (caddy.StorageConverter, error) { |