Skip to content

Added support for index.php in subdirectories #259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 48 additions & 10 deletions local/php/envs.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,58 @@ 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"
}

pathInfo := req.URL.Path
func (p *Server) resolveScriptName(pathInfo string) (string, string) {
if pos := strings.Index(strings.ToLower(pathInfo), ".php"); pos != -1 {
file := pathInfo[:pos+4]
if file == filepath.Clean(file) {
if _, err := os.Stat(filepath.Join(p.documentRoot, file)); err == nil {
return file, pathInfo[pos+4:]
}
}
}
// quick return if it's short or path starts with //
if len(pathInfo) <= 1 || pathInfo[0:2] == "//" {
return p.passthru, pathInfo
}

// removes first slash to make sure we don't loop through it as it always need to be there.
paths := strings.Split(pathInfo[1:], "/")

for n := len(paths); n > 0; n-- {
pathPart := paths[n-1]
if pathPart == "" {
continue
}

// we on purpose don't use filepath join as it resolves the paths. This way if clean filepath is different we break
folder := string(filepath.Separator) + strings.Join(paths[:n], string(filepath.Separator))

if folder != filepath.Clean(folder) {
continue
}

file := filepath.Join(folder, p.passthru)
path := strings.Join(paths[n:], "/")

if _, err := os.Stat(filepath.Join(p.documentRoot, file)); err == nil {
scriptName = file
pathInfo = pathInfo[pos+4:]
// I am not sure how we can get rid of this if statements. It's complete abomination, but it's because subdirectory and subdirectory/ should go to this same file, but have different pathinfo
if path == "" && pathInfo[len(pathInfo)-1:] != "/" {
return file, ""
}
return file, "/" + path
}

}

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")
Expand Down
134 changes: 133 additions & 1 deletion local/php/envs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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/index.php",
"SCRIPT_NAME": "/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{
Expand All @@ -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))
}
}
}
Empty file added local/php/testdata/index.php
Empty file.
Empty file.
Empty file.
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy