From b1480eb52f8e3dd621798e2b74b4e3e47bacc9f5 Mon Sep 17 00:00:00 2001
From: Francis Lavoie <lavofr@gmail.com>
Date: Mon, 22 Jun 2020 13:45:18 -0400
Subject: [PATCH] fastcgi: Fix php_fastcgi matcher regression (#3512)

---
 .../caddyfile_adapt/php_fastcgi_matcher.txt   | 112 ++++++++++++++++++
 .../reverseproxy/fastcgi/caddyfile.go         |  20 ++--
 2 files changed, 122 insertions(+), 10 deletions(-)
 create mode 100644 caddytest/integration/caddyfile_adapt/php_fastcgi_matcher.txt

diff --git a/caddytest/integration/caddyfile_adapt/php_fastcgi_matcher.txt b/caddytest/integration/caddyfile_adapt/php_fastcgi_matcher.txt
new file mode 100644
index 000000000..2f4e6fe5c
--- /dev/null
+++ b/caddytest/integration/caddyfile_adapt/php_fastcgi_matcher.txt
@@ -0,0 +1,112 @@
+:8884
+
+@api host example.com
+php_fastcgi @api localhost:9000
+----------
+{
+	"apps": {
+		"http": {
+			"servers": {
+				"srv0": {
+					"listen": [
+						":8884"
+					],
+					"routes": [
+						{
+							"match": [
+								{
+									"host": [
+										"example.com"
+									]
+								}
+							],
+							"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": "localhost:9000"
+														}
+													]
+												}
+											],
+											"match": [
+												{
+													"path": [
+														"*.php"
+													]
+												}
+											]
+										}
+									]
+								}
+							]
+						}
+					]
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go
index 7c06adcfa..03b7226cf 100644
--- a/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go
+++ b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go
@@ -132,6 +132,16 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
 	// set the default index file for the try_files rewrites
 	indexFile := "index.php"
 
+	// 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
+	// the remaining tokens to the unmarshaler so that
+	// we can gain the rest of the reverse_proxy syntax
+	userMatcherSet, err := h.ExtractMatcherSet()
+	if err != nil {
+		return nil, err
+	}
+
 	// make a new dispenser from the remaining tokens so that we
 	// can reset the dispenser back to this point for the
 	// reverse_proxy unmarshaler to read from it as well
@@ -252,16 +262,6 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
 		"path": h.JSON(pathList),
 	}
 
-	// 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
-	// the remaining tokens to the unmarshaler so that
-	// we can gain the rest of the reverse_proxy syntax
-	userMatcherSet, err := h.ExtractMatcherSet()
-	if err != nil {
-		return nil, err
-	}
-
 	// create the reverse proxy handler which uses our FastCGI transport
 	rpHandler := &reverseproxy.Handler{
 		TransportRaw: caddyconfig.JSONModuleObject(fcgiTransport, "protocol", "fastcgi", nil),