Handle symlinking edge cases (#1660)

This one is interesting — though I’m not sure the best way to provide a
test. I will have to look into maybe an integration test because it is a
careful dance between how we resolve paths in the Caddy module vs.
workers. I looked into making a proper change (literally using the same
logic everywhere), but I think it is best to wait until #1646 is merged.

But anyway, this change deals with some interesting edge cases. I will
use gherkin to describe them:

```gherkin
Feature: FrankenPHP symlinked edge cases
  Background: 
    Given a `test` folder
    And a `public` folder linked to `test`
    And a worker script located at `test/index.php`
    And a `test/nested` folder
    And a worker script located at `test/nested/index.php`
  Scenario: neighboring worker script
    Given frankenphp located in the test folder
    When I execute `frankenphp php-server --listen localhost:8080 -w index.php` from `public`
    Then I expect to see the worker script executed successfully
  Scenario: nested worker script
    Given frankenphp located in the test folder
    When I execute `frankenphp --listen localhost:8080 -w nested/index.php` from `public`
    Then I expect to see the worker script executed successfully
  Scenario: outside the symlinked folder
    Given frankenphp located in the root folder
    When I execute `frankenphp --listen localhost:8080 -w public/index.php` from the root folder
    Then I expect to see the worker script executed successfully
  Scenario: specified root directory
    Given frankenphp located in the root folder
    When I execute `frankenphp --listen localhost:8080 -w public/index.php -r public` from the root folder
    Then I expect to see the worker script executed successfully    
```

Trying to write that out in regular English would be more complex IMHO.

These scenarios should all pass now with this PR.

---------

Signed-off-by: Marc <m@pyc.ac>
Co-authored-by: henderkes <m@pyc.ac>
Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>
This commit is contained in:
Rob Landers
2026-01-02 10:23:16 +01:00
committed by GitHub
parent a6b0577c2c
commit e0f01d12d6
8 changed files with 315 additions and 5 deletions

1
testdata/symlinks/public vendored Symbolic link
View File

@@ -0,0 +1 @@
test

View File

@@ -0,0 +1,13 @@
<?php
if (isset($_SERVER['FRANKENPHP_WORKER'])) {
$i = 0;
do {
$ok = frankenphp_handle_request(function () use ($i): void {
echo "DOCUMENT_ROOT=" . $_SERVER['DOCUMENT_ROOT'] . "\n";
});
$i++;
} while ($ok);
} else {
echo "DOCUMENT_ROOT=" . $_SERVER['DOCUMENT_ROOT'] . "\n";
}

13
testdata/symlinks/test/index.php vendored Normal file
View File

@@ -0,0 +1,13 @@
<?php
if (!isset($_SERVER['FRANKENPHP_WORKER'])) {
die("Error: This script must be run in worker mode (FRANKENPHP_WORKER not set to '1')\n");
}
$i = 0;
do {
$ok = frankenphp_handle_request(function () use ($i): void {
echo sprintf("Request: %d\n", $i);
});
$i++;
} while ($ok);

13
testdata/symlinks/test/nested/index.php vendored Normal file
View File

@@ -0,0 +1,13 @@
<?php
if (!isset($_SERVER['FRANKENPHP_WORKER'])) {
die("Error: This script must be run in worker mode (FRANKENPHP_WORKER not set to '1')\n");
}
$i = 0;
do {
$ok = frankenphp_handle_request(function () use ($i): void {
echo sprintf("Nested request: %d\n", $i);
});
$i++;
} while ($ok);