From 3f2c3ecf85b590473030b21fd2b5fc9c8ef88744 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Fri, 17 Sep 2021 10:23:06 -0400 Subject: [PATCH] fastcgi: Implement `try_files` override in Caddyfile directive (#4347) --- .../php_fastcgi_try_files_override.txt | 124 ++++++++++++++++++ .../reverseproxy/fastcgi/caddyfile.go | 42 ++++-- 2 files changed, 155 insertions(+), 11 deletions(-) create mode 100644 caddytest/integration/caddyfile_adapt/php_fastcgi_try_files_override.txt diff --git a/caddytest/integration/caddyfile_adapt/php_fastcgi_try_files_override.txt b/caddytest/integration/caddyfile_adapt/php_fastcgi_try_files_override.txt new file mode 100644 index 00000000..2f4ef767 --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/php_fastcgi_try_files_override.txt @@ -0,0 +1,124 @@ +:8884 + +php_fastcgi localhost:9000 { + # some php_fastcgi-specific subdirectives + split .php .php5 + env VAR1 value1 + env VAR2 value2 + root /var/www + try_files {path} {path}/index.php =404 + dial_timeout 3s + read_timeout 10s + write_timeout 20s + + # passed through to reverse_proxy (directive order doesn't matter!) + lb_policy random +} +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":8884" + ], + "routes": [ + { + "match": [ + { + "file": { + "try_files": [ + "{http.request.uri.path}/index.php" + ] + }, + "not": [ + { + "path": [ + "*/" + ] + } + ] + } + ], + "handle": [ + { + "handler": "static_response", + "headers": { + "Location": [ + "{http.request.uri.path}/" + ] + }, + "status_code": 308 + } + ] + }, + { + "match": [ + { + "file": { + "try_files": [ + "{http.request.uri.path}", + "{http.request.uri.path}/index.php", + "=404" + ], + "split_path": [ + ".php", + ".php5" + ] + } + } + ], + "handle": [ + { + "handler": "rewrite", + "uri": "{http.matchers.file.relative}" + } + ] + }, + { + "match": [ + { + "path": [ + "*.php", + "*.php5" + ] + } + ], + "handle": [ + { + "handler": "reverse_proxy", + "load_balancing": { + "selection_policy": { + "policy": "random" + } + }, + "transport": { + "dial_timeout": 3000000000, + "env": { + "VAR1": "value1", + "VAR2": "value2" + }, + "protocol": "fastcgi", + "read_timeout": 10000000000, + "root": "/var/www", + "split_path": [ + ".php", + ".php5" + ], + "write_timeout": 20000000000 + }, + "upstreams": [ + { + "dial": "localhost:9000" + } + ] + } + ] + } + ] + } + } + } + } +} diff --git a/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go index da1c92d5..1b4cecf4 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go @@ -124,21 +124,22 @@ func (t *Transport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { // // is equivalent to a route consisting of: // +// # Add trailing slash for directory requests // @canonicalPath { -// file { -// try_files {path}/index.php -// } -// not { -// path */ -// } +// file {path}/index.php +// not path */ // } // redir @canonicalPath {path}/ 308 // -// try_files {path} {path}/index.php index.php -// -// @phpFiles { -// path *.php +// # 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 localhost:7777 { // transport fastcgi { // split .php @@ -172,6 +173,9 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error // set the default index file for the try_files rewrites indexFile := "index.php" + // set up for explicitly overriding try_files + tryFiles := []string{} + // if the user specified a matcher token, use that // matcher in a route that wraps both of our routes; // either way, strip the matcher token and pass @@ -237,6 +241,17 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error } indexFile = args[0] + case "try_files": + args := dispenser.RemainingArgs() + dispenser.Delete() + for range args { + dispenser.Delete() + } + if len(args) < 1 { + return nil, dispenser.ArgErr() + } + tryFiles = args + case "resolve_root_symlink": args := dispenser.RemainingArgs() dispenser.Delete() @@ -318,10 +333,15 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error HandlersRaw: []json.RawMessage{caddyconfig.JSONModuleObject(redirHandler, "handler", "static_response", nil)}, } + // if tryFiles wasn't overridden, use a reasonable default + if len(tryFiles) == 0 { + tryFiles = []string{"{http.request.uri.path}", "{http.request.uri.path}/" + indexFile, indexFile} + } + // route to rewrite to PHP index file rewriteMatcherSet := caddy.ModuleMap{ "file": h.JSON(fileserver.MatchFile{ - TryFiles: []string{"{http.request.uri.path}", "{http.request.uri.path}/" + indexFile, indexFile}, + TryFiles: tryFiles, SplitPath: extensions, }), }