mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-26 13:43:47 +03:00
httpcaddyfile: Allow named matchers in route
blocks (#3632)
This commit is contained in:
parent
904f149e5b
commit
584eba94a4
3 changed files with 161 additions and 30 deletions
|
@ -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()
|
||||
allResults, err := parseSegmentAsConfig(h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dirFunc, ok := registeredDirectives[dir]
|
||||
if !ok {
|
||||
return nil, h.Errf("unrecognized directive: %s", dir)
|
||||
}
|
||||
|
||||
subHelper := h
|
||||
subHelper.Dispenser = h.NewFromNextSegment()
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue