diff --git a/caddy/caddy_test.go b/caddy/caddy_test.go index 7184a09253..945f1a3d68 100644 --- a/caddy/caddy_test.go +++ b/caddy/caddy_test.go @@ -2062,6 +2062,31 @@ func TestSymlinkWorkerPaths(t *testing.T) { tester.AssertGetResponse("http://localhost:"+testPort+"/index.php", http.StatusOK, "Request: 0\n") }) + + t.Run("PhpServerWorkerWithoutResolveRootSymlink", func(t *testing.T) { + tester := caddytest.NewTester(t) + initServer(t, tester, ` + { + skip_install_trust + admin localhost:2999 + http_port `+testPort+` + } + + localhost:`+testPort+` { + root `+publicDir+` + php_server { + worker { + file `+publicDir+`/index.php + num 1 + } + resolve_root_symlink false + } + } + `, "caddyfile") + + // the readiness probe of initServer falls back to index.php and was request 0 + tester.AssertGetResponse("http://localhost:"+testPort+"/index.php", http.StatusOK, "Request: 1\n") + }) } // TestSymlinkResolveRoot tests the resolve_root_symlink directive behavior diff --git a/options.go b/options.go index 5566ed41cf..40f50a17ee 100644 --- a/options.go +++ b/options.go @@ -44,6 +44,7 @@ type workerOpt struct { name string fileName string + declaredFileName string num int maxThreads int env PreparedEnv diff --git a/server.go b/server.go index 8274f23c54..e757ab37f6 100644 --- a/server.go +++ b/server.go @@ -141,6 +141,8 @@ func (s *Server) addWorker(w *worker) error { return fmt.Errorf("two workers in a server cannot have the same filename: %q", w.fileName) } s.workersByPath[w.fileName] = w + // a document root whose symlinks are kept yields the declared path, not the resolved one + s.workersByPath[w.declaredFileName] = w return nil } diff --git a/worker.go b/worker.go index a94dca945d..8f1fe524f2 100644 --- a/worker.go +++ b/worker.go @@ -22,6 +22,7 @@ type worker struct { name string fileName string + declaredFileName string matchRequest func(*http.Request) bool num int maxThreads int @@ -69,6 +70,7 @@ func initWorkers(opts []workerOpt) error { workersByName[w.name] = w if w.server == nil { globalWorkersByPath[w.fileName] = w + globalWorkersByPath[w.declaredFileName] = w } else if err := w.server.addWorker(w); err != nil { return err } @@ -108,6 +110,11 @@ func initWorkers(opts []workerOpt) error { // This order ensures that FrankenPHP started from inside a symlinked directory will properly resolve any paths. // If it is started from outside a symlinked directory, it is resolved to the same path that we use in the Caddy module. func resolveWorkerFile(o workerOpt) (workerOpt, error) { + declaredFileName, err := fastabs.FastAbs(filepath.FromSlash(o.fileName)) + if err != nil { + return o, fmt.Errorf("worker filename is invalid %q: %w", o.fileName, err) + } + absFileName, err := filepath.EvalSymlinks(filepath.FromSlash(o.fileName)) if err != nil { return o, fmt.Errorf("worker filename is invalid %q: %w", o.fileName, err) @@ -122,6 +129,7 @@ func resolveWorkerFile(o workerOpt) (workerOpt, error) { return o, fmt.Errorf("worker file not found %q: %w", absFileName, err) } + o.declaredFileName = declaredFileName o.fileName = absFileName if o.name == "" { o.name = absFileName @@ -195,6 +203,7 @@ func newWorker(o workerOpt) (*worker, error) { w := &worker{ name: o.name, fileName: absFileName, + declaredFileName: o.declaredFileName, matchRequest: o.matchRequest, requestOptions: o.requestOptions, num: o.num,