aboutsummaryrefslogtreecommitdiffhomepage
path: root/caddyconfig/httpcaddyfile/options.go
diff options
context:
space:
mode:
authorMatthew Holt <[email protected]>2020-01-16 12:09:54 -0700
committerMatthew Holt <[email protected]>2020-01-16 12:09:54 -0700
commit21643a007a2d2d90e1636ecd6b49f82560f4c939 (patch)
tree178b8495b693c303be429feb38c7ea4af3f50bde /caddyconfig/httpcaddyfile/options.go
parent2466ed148466ee17fb4da6d2d732e1a16f0469a6 (diff)
downloadcaddy-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.go87
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) {