diff --git a/local/php/envs.go b/local/php/envs.go index 1465c552..b1ef160e 100644 --- a/local/php/envs.go +++ b/local/php/envs.go @@ -30,20 +30,46 @@ import ( "github.com/symfony-cli/symfony-cli/envs" ) -func (p *Server) generateEnv(req *http.Request) map[string]string { - scriptName := p.passthru - https := "" - if req.TLS != nil { - https = "On" - } +func (p *Server) resolveScriptName(pathInfo string) (string, string) { + + pathInfo = path.Clean(pathInfo) - pathInfo := req.URL.Path if pos := strings.Index(strings.ToLower(pathInfo), ".php"); pos != -1 { file := path.Clean(pathInfo[:pos+4]) + + if _, err := os.Stat(filepath.Join(p.documentRoot, file)); err == nil { + return file, pathInfo[pos+4:] + } + + } + + if len(pathInfo) <= 1 { + return p.passthru, pathInfo + } + + paths := strings.Split(pathInfo, "/") + + for n := len(paths); n > 0; n-- { + file := filepath.Clean(filepath.Join(paths[:n]...)) if _, err := os.Stat(filepath.Join(p.documentRoot, file)); err == nil { - scriptName = file - pathInfo = pathInfo[pos+4:] + serverPath := path.Join(paths[n:]...) + if serverPath == "" && pathInfo[len(pathInfo)-1:] != "/" { + return file, "" + } + return file, "/" + serverPath } + + } + + return p.passthru, pathInfo +} + +func (p *Server) generateEnv(req *http.Request) map[string]string { + scriptName, pathInfo := p.resolveScriptName(req.URL.Path) + + https := "" + if req.TLS != nil { + https = "On" } remoteAddr := req.Header.Get("X-Client-IP") diff --git a/local/php/envs_test.go b/local/php/envs_test.go index ac9ad28f..8927f4cc 100644 --- a/local/php/envs_test.go +++ b/local/php/envs_test.go @@ -182,6 +182,138 @@ func (s *PHPFPMSuite) TestGenerateEnv(c *C) { "SCRIPT_NAME": "/index.php", }, }, + { + passthru: "/index.php", + uri: "/subdirectory", + expected: map[string]string{ + "PATH_INFO": "", + "REQUEST_URI": "/subdirectory", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/subdirectory/index.php", + "SCRIPT_NAME": "/subdirectory/index.php", + }, + }, + { + passthru: "/index.php", + uri: "/subdirectory/", + expected: map[string]string{ + "PATH_INFO": "/", + "REQUEST_URI": "/subdirectory/", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/subdirectory/index.php", + "SCRIPT_NAME": "/subdirectory/index.php", + }, + }, + { + passthru: "/index.php", + uri: "/subdirectory/unknown.php", + expected: map[string]string{ + "PATH_INFO": "/unknown.php", + "REQUEST_URI": "/subdirectory/unknown.php", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/subdirectory/index.php", + "SCRIPT_NAME": "/subdirectory/index.php", + }, + }, + { + passthru: "/index.php", + uri: "/subdirectory/unknown.php/", + expected: map[string]string{ + "PATH_INFO": "/unknown.php/", + "REQUEST_URI": "/subdirectory/unknown.php/", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/subdirectory/index.php", + "SCRIPT_NAME": "/subdirectory/index.php", + }, + }, + { + passthru: "/index.php", + uri: "/subdirectory/index.php/foo", + expected: map[string]string{ + "PATH_INFO": "/foo", + "REQUEST_URI": "/subdirectory/index.php/foo", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/subdirectory/index.php", + "SCRIPT_NAME": "/subdirectory/index.php", + }, + }, + { + passthru: "/index.php", + uri: "/subdirectory/subdirectory/", + expected: map[string]string{ + "PATH_INFO": "/", + "REQUEST_URI": "/subdirectory/subdirectory/", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/subdirectory/subdirectory/index.php", + "SCRIPT_NAME": "/subdirectory/subdirectory/index.php", + }, + }, + { + passthru: "/index.php", + uri: "///subdirectory", + expected: map[string]string{ + "PATH_INFO": "///subdirectory", + "REQUEST_URI": "///subdirectory", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/index.php", + "SCRIPT_NAME": "/index.php", + }, + }, + { + passthru: "/index.php", + uri: "/subdirectory///subdirectory//foo/", + expected: map[string]string{ + "PATH_INFO": "/subdirectory/foo/", + "REQUEST_URI": "/subdirectory/subdirectory/foo/", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/subdirectory/subdirectory/index.php", + "SCRIPT_NAME": "/subdirectory/subdirectory/index.php", + }, + }, + { + passthru: "/index.php", + uri: "/../index.php", + expected: map[string]string{ + "PATH_INFO": "/../index.php", + "REQUEST_URI": "/../index.php", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/index.php", + "SCRIPT_NAME": "/index.php", + }, + }, + { + passthru: "/index.php", + uri: "/subdirectory/../../index.php", + expected: map[string]string{ + "PATH_INFO": "/../../index.php", + "REQUEST_URI": "/subdirectory/../../index.php", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/subdirectory/index.php", + "SCRIPT_NAME": "/subdirectory/index.php", + }, + }, + { + passthru: "/index.php", + uri: "/subdirectory/subdirectory/foo/subdirectory/bar", + expected: map[string]string{ + "PATH_INFO": "/foo/subdirectory/bar", + "REQUEST_URI": "/subdirectory/subdirectory/foo/subdirectory/bar", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/subdirectory/subdirectory/index.php", + "SCRIPT_NAME": "/subdirectory/subdirectory/index.php", + }, + }, + { + passthru: "/index.php", + uri: "/foo/../update.php", + expected: map[string]string{ + "PATH_INFO": "/foo/../update.php", + "REQUEST_URI": "/foo/../update.php", + "QUERY_STRING": "", + "SCRIPT_FILENAME": testdataDir + "/public/index.php", + "SCRIPT_NAME": "/index.php", + }, + }, } for _, test := range tests { process := &Server{ @@ -197,7 +329,7 @@ func (s *PHPFPMSuite) TestGenerateEnv(c *C) { for k, v := range test.expected { vv, ok := env[k] c.Assert(ok, Equals, true) - c.Assert(vv, DeepEquals, v) + c.Assert(vv, DeepEquals, v, Commentf("#test uri:\"%s\" varName:\"%s\"", test.uri, k)) } } } diff --git a/local/php/testdata/index.php b/local/php/testdata/index.php new file mode 100644 index 00000000..e69de29b diff --git a/local/php/testdata/public/subdirectory/index.php b/local/php/testdata/public/subdirectory/index.php new file mode 100644 index 00000000..e69de29b diff --git a/local/php/testdata/public/subdirectory/subdirectory/index.php b/local/php/testdata/public/subdirectory/subdirectory/index.php new file mode 100644 index 00000000..e69de29b