summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancis Lavoie <lavofr@gmail.com>2020-08-05 15:42:29 -0400
committerGitHub <noreply@github.com>2020-08-05 13:42:29 -0600
commit584eba94a4e06af9ce7efc91fb914f84d7a6a48c (patch)
treed01bd6c67e2bf9e8d895982a4b6f246b146b45bf
parent904f149e5b2f0ae9eff09dacb4f1ec41c4a76298 (diff)
httpcaddyfile: Allow named matchers in `route` blocks (#3632)
-rw-r--r--caddyconfig/httpcaddyfile/builtins.go45
-rw-r--r--caddyconfig/httpcaddyfile/directives.go14
-rw-r--r--caddytest/integration/caddyfile_adapt/php_fastcgi_expanded_form.txt132
3 files changed, 161 insertions, 30 deletions
diff --git a/caddyconfig/httpcaddyfile/builtins.go b/caddyconfig/httpcaddyfile/builtins.go
index 5dbb406..520796d 100644
--- a/caddyconfig/httpcaddyfile/builtins.go
+++ b/caddyconfig/httpcaddyfile/builtins.go
@@ -480,36 +480,23 @@ func parseRespond(h Helper) (caddyhttp.MiddlewareHandler, error) {
func parseRoute(h Helper) (caddyhttp.MiddlewareHandler, error) {
sr := new(caddyhttp.Subroute)
- for h.Next() {
- for nesting := h.Nesting(); h.NextBlock(nesting); {
- dir := h.Val()
-
- dirFunc, ok := registeredDirectives[dir]
- if !ok {
- return nil, h.Errf("unrecognized directive: %s", dir)
- }
-
- subHelper := h
- subHelper.Dispenser = h.NewFromNextSegment()
+ allResults, err := parseSegmentAsConfig(h)
+ if err != nil {
+ return nil, err
+ }
- results, err := dirFunc(subHelper)
- if err != nil {
- return nil, h.Errf("parsing caddyfile tokens for '%s': %v", dir, err)
- }
- for _, result := range results {
- switch handler := result.Value.(type) {
- case caddyhttp.Route:
- sr.Routes = append(sr.Routes, handler)
- case caddyhttp.Subroute:
- // directives which return a literal subroute instead of a route
- // means they intend to keep those handlers together without
- // them being reordered; we're doing that anyway since we're in
- // the route directive, so just append its handlers
- sr.Routes = append(sr.Routes, handler.Routes...)
- default:
- return nil, h.Errf("%s directive returned something other than an HTTP route or subroute: %#v (only handler directives can be used in routes)", dir, result.Value)
- }
- }
+ for _, result := range allResults {
+ switch handler := result.Value.(type) {
+ case caddyhttp.Route:
+ sr.Routes = append(sr.Routes, handler)
+ case caddyhttp.Subroute:
+ // directives which return a literal subroute instead of a route
+ // means they intend to keep those handlers together without
+ // them being reordered; we're doing that anyway since we're in
+ // the route directive, so just append its handlers
+ sr.Routes = append(sr.Routes, handler.Routes...)
+ default:
+ return nil, h.Errf("%s directive returned something other than an HTTP route or subroute: %#v (only handler directives can be used in routes)", result.directive, result.Value)
}
}
diff --git a/caddyconfig/httpcaddyfile/directives.go b/caddyconfig/httpcaddyfile/directives.go
index c31bdd3..e93fdd0 100644
--- a/caddyconfig/httpcaddyfile/directives.go
+++ b/caddyconfig/httpcaddyfile/directives.go
@@ -269,6 +269,18 @@ func (h Helper) NewBindAddresses(addrs []string) []ConfigValue {
// are themselves treated as directives, from which a subroute is built
// and returned.
func ParseSegmentAsSubroute(h Helper) (caddyhttp.MiddlewareHandler, error) {
+ allResults, err := parseSegmentAsConfig(h)
+ if err != nil {
+ return nil, err
+ }
+
+ return buildSubroute(allResults, h.groupCounter)
+}
+
+// parseSegmentAsConfig parses the segment such that its subdirectives
+// are themselves treated as directives, including named matcher definitions,
+// and the raw Config structs are returned.
+func parseSegmentAsConfig(h Helper) ([]ConfigValue, error) {
var allResults []ConfigValue
for h.Next() {
@@ -319,7 +331,7 @@ func ParseSegmentAsSubroute(h Helper) (caddyhttp.MiddlewareHandler, error) {
}
}
- return buildSubroute(allResults, h.groupCounter)
+ return allResults, nil
}
// ConfigValue represents a value to be added to the final
diff --git a/caddytest/integration/caddyfile_adapt/php_fastcgi_expanded_form.txt b/caddytest/integration/caddyfile_adapt/php_fastcgi_expanded_form.txt
new file mode 100644
index 0000000..d453128
--- /dev/null
+++ b/caddytest/integration/caddyfile_adapt/php_fastcgi_expanded_form.txt
@@ -0,0 +1,132 @@
+:8886
+
+route {
+ # Add trailing slash for directory requests
+ @canonicalPath {
+ file {
+ try_files {path}/index.php
+ }
+ not path */
+ }
+ redir @canonicalPath {path}/ 308
+
+ # If the requested file does not exist, try index files
+ @indexFiles {
+ file {
+ try_files {path} {path}/index.php index.php
+ split_path .php
+ }
+ }
+ rewrite @indexFiles {http.matchers.file.relative}
+
+ # Proxy PHP files to the FastCGI responder
+ @phpFiles {
+ path *.php
+ }
+ reverse_proxy @phpFiles 127.0.0.1:9000 {
+ transport fastcgi {
+ split .php
+ }
+ }
+}
+----------
+{
+ "apps": {
+ "http": {
+ "servers": {
+ "srv0": {
+ "listen": [
+ ":8886"
+ ],
+ "routes": [
+ {
+ "handle": [
+ {
+ "handler": "subroute",
+ "routes": [
+ {
+ "handle": [
+ {
+ "handler": "static_response",
+ "headers": {
+ "Location": [
+ "{http.request.uri.path}/"
+ ]
+ },
+ "status_code": 308
+ }
+ ],
+ "match": [
+ {
+ "file": {
+ "try_files": [
+ "{http.request.uri.path}/index.php"
+ ]
+ },
+ "not": [
+ {
+ "path": [
+ "*/"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "handle": [
+ {
+ "handler": "rewrite",
+ "uri": "{http.matchers.file.relative}"
+ }
+ ],
+ "match": [
+ {
+ "file": {
+ "split_path": [
+ ".php"
+ ],
+ "try_files": [
+ "{http.request.uri.path}",
+ "{http.request.uri.path}/index.php",
+ "index.php"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "handle": [
+ {
+ "handler": "reverse_proxy",
+ "transport": {
+ "protocol": "fastcgi",
+ "split_path": [
+ ".php"
+ ]
+ },
+ "upstreams": [
+ {
+ "dial": "127.0.0.1:9000"
+ }
+ ]
+ }
+ ],
+ "match": [
+ {
+ "path": [
+ "*.php"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+} \ No newline at end of file