aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFrancis Lavoie <[email protected]>2024-01-15 11:57:08 -0500
committerGitHub <[email protected]>2024-01-15 09:57:08 -0700
commit5e2f1b5ced5e7153f9748477612cf46188470ca7 (patch)
tree2f4dee27a59abd16b750a4b61c77813e5856424c
parentf3e849e49fb82f53ed1491269db5a509f2486168 (diff)
downloadcaddy-5e2f1b5ced5e7153f9748477612cf46188470ca7.tar.gz
caddy-5e2f1b5ced5e7153f9748477612cf46188470ca7.zip
httpcaddyfile: Rewrite `root` and `rewrite` parsing to allow omitting matcher (#5844)
-rw-r--r--caddyconfig/httpcaddyfile/builtins.go45
-rw-r--r--caddytest/integration/caddyfile_adapt/rewrite_directive_permutations.txt112
-rw-r--r--caddytest/integration/caddyfile_adapt/root_directive_permutations.txt108
-rw-r--r--modules/caddyhttp/rewrite/caddyfile.go43
4 files changed, 296 insertions, 12 deletions
diff --git a/caddyconfig/httpcaddyfile/builtins.go b/caddyconfig/httpcaddyfile/builtins.go
index 5bfe434cb..3b56e0739 100644
--- a/caddyconfig/httpcaddyfile/builtins.go
+++ b/caddyconfig/httpcaddyfile/builtins.go
@@ -41,7 +41,7 @@ func init() {
RegisterDirective("bind", parseBind)
RegisterDirective("tls", parseTLS)
RegisterHandlerDirective("fs", parseFilesystem)
- RegisterHandlerDirective("root", parseRoot)
+ RegisterDirective("root", parseRoot)
RegisterHandlerDirective("vars", parseVars)
RegisterHandlerDirective("redir", parseRedir)
RegisterHandlerDirective("respond", parseRespond)
@@ -645,18 +645,45 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
// parseRoot parses the root directive. Syntax:
//
// root [<matcher>] <path>
-func parseRoot(h Helper) (caddyhttp.MiddlewareHandler, error) {
- var root string
- for h.Next() {
+func parseRoot(h Helper) ([]ConfigValue, error) {
+ // consume directive name
+ if !h.NextArg() {
+ return nil, h.ArgErr()
+ }
+
+ // count the tokens to determine what to do
+ argsCount := h.CountRemainingArgs()
+ if argsCount == 0 {
+ return nil, h.Errf("too few arguments; must have at least a root path")
+ }
+ if argsCount > 2 {
+ return nil, h.Errf("too many arguments; should only be a matcher and a path")
+ }
+
+ // with only one arg, assume it's a root path with no matcher token
+ if argsCount == 1 {
if !h.NextArg() {
return nil, h.ArgErr()
}
- root = h.Val()
- if h.NextArg() {
- return nil, h.ArgErr()
- }
+ return h.NewRoute(nil, caddyhttp.VarsMiddleware{"root": h.Val()}), nil
+ }
+
+ // parse the matcher token into a matcher set
+ userMatcherSet, err := h.ExtractMatcherSet()
+ if err != nil {
+ return nil, err
+ }
+
+ // consume directive name, again, because extracting matcher does a reset
+ if !h.NextArg() {
+ return nil, h.ArgErr()
+ }
+ // advance to the root path
+ if !h.NextArg() {
+ return nil, h.ArgErr()
}
- return caddyhttp.VarsMiddleware{"root": root}, nil
+ // make the route with the matcher
+ return h.NewRoute(userMatcherSet, caddyhttp.VarsMiddleware{"root": h.Val()}), nil
}
// parseFilesystem parses the fs directive. Syntax:
diff --git a/caddytest/integration/caddyfile_adapt/rewrite_directive_permutations.txt b/caddytest/integration/caddyfile_adapt/rewrite_directive_permutations.txt
new file mode 100644
index 000000000..870e82afd
--- /dev/null
+++ b/caddytest/integration/caddyfile_adapt/rewrite_directive_permutations.txt
@@ -0,0 +1,112 @@
+:8080
+
+# With explicit wildcard matcher
+route {
+ rewrite * /a
+}
+
+# With path matcher
+route {
+ rewrite /path /b
+}
+
+# With named matcher
+route {
+ @named method GET
+ rewrite @named /c
+}
+
+# With no matcher, assumed to be wildcard
+route {
+ rewrite /d
+}
+----------
+{
+ "apps": {
+ "http": {
+ "servers": {
+ "srv0": {
+ "listen": [
+ ":8080"
+ ],
+ "routes": [
+ {
+ "handle": [
+ {
+ "handler": "subroute",
+ "routes": [
+ {
+ "group": "group0",
+ "handle": [
+ {
+ "handler": "rewrite",
+ "uri": "/a"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "handler": "subroute",
+ "routes": [
+ {
+ "group": "group1",
+ "handle": [
+ {
+ "handler": "rewrite",
+ "uri": "/b"
+ }
+ ],
+ "match": [
+ {
+ "path": [
+ "/path"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "handler": "subroute",
+ "routes": [
+ {
+ "group": "group2",
+ "handle": [
+ {
+ "handler": "rewrite",
+ "uri": "/c"
+ }
+ ],
+ "match": [
+ {
+ "method": [
+ "GET"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "handler": "subroute",
+ "routes": [
+ {
+ "group": "group3",
+ "handle": [
+ {
+ "handler": "rewrite",
+ "uri": "/d"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/caddytest/integration/caddyfile_adapt/root_directive_permutations.txt b/caddytest/integration/caddyfile_adapt/root_directive_permutations.txt
new file mode 100644
index 000000000..b2ef86c45
--- /dev/null
+++ b/caddytest/integration/caddyfile_adapt/root_directive_permutations.txt
@@ -0,0 +1,108 @@
+:8080
+
+# With explicit wildcard matcher
+route {
+ root * /a
+}
+
+# With path matcher
+route {
+ root /path /b
+}
+
+# With named matcher
+route {
+ @named method GET
+ root @named /c
+}
+
+# With no matcher, assumed to be wildcard
+route {
+ root /d
+}
+----------
+{
+ "apps": {
+ "http": {
+ "servers": {
+ "srv0": {
+ "listen": [
+ ":8080"
+ ],
+ "routes": [
+ {
+ "handle": [
+ {
+ "handler": "subroute",
+ "routes": [
+ {
+ "handle": [
+ {
+ "handler": "vars",
+ "root": "/a"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "handler": "subroute",
+ "routes": [
+ {
+ "handle": [
+ {
+ "handler": "vars",
+ "root": "/b"
+ }
+ ],
+ "match": [
+ {
+ "path": [
+ "/path"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "handler": "subroute",
+ "routes": [
+ {
+ "handle": [
+ {
+ "handler": "vars",
+ "root": "/c"
+ }
+ ],
+ "match": [
+ {
+ "method": [
+ "GET"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "handler": "subroute",
+ "routes": [
+ {
+ "handle": [
+ {
+ "handler": "vars",
+ "root": "/d"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/modules/caddyhttp/rewrite/caddyfile.go b/modules/caddyhttp/rewrite/caddyfile.go
index a34c1bb08..5d7bd32e6 100644
--- a/modules/caddyhttp/rewrite/caddyfile.go
+++ b/modules/caddyhttp/rewrite/caddyfile.go
@@ -26,7 +26,7 @@ import (
)
func init() {
- httpcaddyfile.RegisterHandlerDirective("rewrite", parseCaddyfileRewrite)
+ httpcaddyfile.RegisterDirective("rewrite", parseCaddyfileRewrite)
httpcaddyfile.RegisterHandlerDirective("method", parseCaddyfileMethod)
httpcaddyfile.RegisterHandlerDirective("uri", parseCaddyfileURI)
httpcaddyfile.RegisterDirective("handle_path", parseCaddyfileHandlePath)
@@ -38,7 +38,44 @@ func init() {
//
// Only URI components which are given in <to> will be set in the resulting URI.
// See the docs for the rewrite handler for more information.
-func parseCaddyfileRewrite(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
+func parseCaddyfileRewrite(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) {
+ // consume directive name
+ if !h.NextArg() {
+ return nil, h.ArgErr()
+ }
+
+ // count the tokens to determine what to do
+ argsCount := h.CountRemainingArgs()
+ if argsCount == 0 {
+ return nil, h.Errf("too few arguments; must have at least a rewrite URI")
+ }
+ if argsCount > 2 {
+ return nil, h.Errf("too many arguments; should only be a matcher and a URI")
+ }
+
+ // with only one arg, assume it's a rewrite URI with no matcher token
+ if argsCount == 1 {
+ if !h.NextArg() {
+ return nil, h.ArgErr()
+ }
+ return h.NewRoute(nil, Rewrite{URI: h.Val()}), nil
+ }
+
+ // parse the matcher token into a matcher set
+ userMatcherSet, err := h.ExtractMatcherSet()
+ if err != nil {
+ return nil, err
+ }
+
+ // consume directive name, again, because extracting matcher does a reset
+ if !h.NextArg() {
+ return nil, h.ArgErr()
+ }
+ // advance to the rewrite URI
+ if !h.NextArg() {
+ return nil, h.ArgErr()
+ }
+
var rewr Rewrite
for h.Next() {
if !h.NextArg() {
@@ -49,7 +86,7 @@ func parseCaddyfileRewrite(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler,
return nil, h.ArgErr()
}
}
- return rewr, nil
+ return h.NewRoute(userMatcherSet, Rewrite{URI: h.Val()}), nil
}
// parseCaddyfileMethod sets up a basic method rewrite handler from Caddyfile tokens. Syntax: