Skip to content

Commit

Permalink
httpcaddyfile: Rewrite root parsing to allow omitting matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
francislavoie committed Sep 30, 2023
1 parent 58ab3a0 commit 60febe8
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 9 deletions.
45 changes: 36 additions & 9 deletions caddyconfig/httpcaddyfile/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import (
func init() {
RegisterDirective("bind", parseBind)
RegisterDirective("tls", parseTLS)
RegisterHandlerDirective("root", parseRoot)
RegisterDirective("root", parseRoot)
RegisterHandlerDirective("vars", parseVars)
RegisterHandlerDirective("redir", parseRedir)
RegisterHandlerDirective("respond", parseRespond)
Expand Down Expand Up @@ -600,18 +600,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
}

// parseVars parses the vars directive. See its UnmarshalCaddyfile method for syntax.
Expand Down
108 changes: 108 additions & 0 deletions caddytest/integration/caddyfile_adapt/root_directive_permutations.txt
Original file line number Diff line number Diff line change
@@ -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"
}
]
}
]
}
]
}
]
}
}
}
}
}

0 comments on commit 60febe8

Please sign in to comment.