Skip to content

Commit

Permalink
Support index.php fallback for files in built-in server
Browse files Browse the repository at this point in the history
If no router script is used, the built-in webserver will now look for a fallback
index file recursively in all cases, including URLs with a period.

Fixes GH-12604
Closes GH-12992
  • Loading branch information
iluuu1994 committed Jan 9, 2024
1 parent 8876639 commit d7d0d19
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 20 deletions.
8 changes: 8 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ PHP 8.4 UPGRADE NOTES
1. Backward Incompatible Changes
========================================

- CLI:
. The builtin server looks for an index file recursively by traversing parent
directories in case the specified file cannot be located. This process was
previously skipped if the path looked like it was referring to a file, i.e.
if the last path component contained a period. In that case, a 404 error was
returned. The behavior has been changed to look for an index file in all
cases.

- Core:
. The type of PHP_DEBUG and PHP_ZTS constants changed to bool.

Expand Down
14 changes: 3 additions & 11 deletions sapi/cli/php_cli_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -1437,14 +1437,13 @@ static void php_cli_server_request_dtor(php_cli_server_request *req) /* {{{ */
}
} /* }}} */

static void php_cli_server_request_translate_vpath(php_cli_server_request *request, const char *document_root, size_t document_root_len) /* {{{ */
static void php_cli_server_request_translate_vpath(const php_cli_server *server, php_cli_server_request *request, const char *document_root, size_t document_root_len) /* {{{ */
{
zend_stat_t sb = {0};
static const char *index_files[] = { "index.php", "index.html", NULL };
char *buf = safe_pemalloc(1, request->vpath_len, 1 + document_root_len + 1 + sizeof("index.html"), 1);
char *p = buf, *prev_path = NULL, *q, *vpath;
size_t prev_path_len = 0;
int is_static_file = 0;

memmove(p, document_root, document_root_len);
p += document_root_len;
Expand All @@ -1453,13 +1452,6 @@ static void php_cli_server_request_translate_vpath(php_cli_server_request *reque
if (request->vpath[0] != '/') {
*p++ = DEFAULT_SLASH;
}
q = request->vpath + request->vpath_len;
while (q > request->vpath) {
if (*q-- == '.') {
is_static_file = 1;
break;
}
}
memmove(p, request->vpath, request->vpath_len);
#ifdef PHP_WIN32
q = p + request->vpath_len;
Expand Down Expand Up @@ -1489,7 +1481,7 @@ static void php_cli_server_request_translate_vpath(php_cli_server_request *reque
}
file++;
}
if (!*file || is_static_file) {
if (!*file) {
if (prev_path) {
pefree(prev_path, 1);
}
Expand Down Expand Up @@ -1801,7 +1793,7 @@ static int php_cli_server_client_read_request_on_message_complete(php_http_parse
{
php_cli_server_client *client = parser->data;
client->request.protocol_version = parser->http_major * 100 + parser->http_minor;
php_cli_server_request_translate_vpath(&client->request, client->server->document_root, client->server->document_root_len);
php_cli_server_request_translate_vpath(client->server, &client->request, client->server->document_root, client->server->document_root_len);
if (client->request.vpath) {
const char *vpath = client->request.vpath;
const char *end = vpath + client->request.vpath_len;
Expand Down
19 changes: 17 additions & 2 deletions sapi/cli/tests/php_cli_server.inc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function php_cli_server_start(
$error = null;

// Create dedicated doc root to avoid index.php clashes between tests.
$doc_root = __DIR__ . '/' . basename($_SERVER['PHP_SELF'], '.php');
$doc_root = __DIR__ . DIRECTORY_SEPARATOR . basename($_SERVER['PHP_SELF'], '.php');
@mkdir($doc_root);

if ($code) {
Expand Down Expand Up @@ -103,7 +103,7 @@ function php_cli_server_start(
printf("Server output:\n%s\n", file_get_contents($output_file));
}
@unlink(__DIR__ . "/{$router}");
@rmdir($doc_root);
remove_directory($doc_root);
},
$handle
);
Expand All @@ -126,4 +126,19 @@ function php_cli_server_connect() {
return $fp;
}

function remove_directory($dir) {
if (is_dir($dir) === false) {
return;
}
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $fileinfo) {
$todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
$todo($fileinfo->getRealPath());
}
@rmdir($dir);
}

?>
2 changes: 1 addition & 1 deletion sapi/cli/tests/php_cli_server_009.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,4 @@ X-Powered-By: PHP/%s
Content-type: text/html; charset=UTF-8

string(9) "/foo/bar/"
HTTP/1.0 404 Not Found
HTTP/1.0 200 OK
8 changes: 3 additions & 5 deletions sapi/cli/tests/php_cli_server_014.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,11 @@ X-Powered-By: %s
Content-type: %s

done
HTTP/1.1 404 Not Found
HTTP/1.1 200 OK
Host: %s
Date: %s
Connection: close
X-Powered-By: PHP/%s
Content-Type: %s
Content-Length: %d
Content-type: %s

<!doctype html><html><head><title>404 Not Found</title><style>AAA</style>
</head><body><h1>Not Found</h1><p>The requested resource <code class="url">/main/no-exists.php</code> was not found on this server.</p></body></html>
done
4 changes: 3 additions & 1 deletion sapi/cli/tests/php_cli_server_016.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ include "skipif.inc";
--FILE--
<?php
include "php_cli_server.inc";
php_cli_server_start(<<<'PHP'
$info = php_cli_server_start(null, 'router.php');
file_put_contents($info->docRoot . '/router.php', <<<'PHP'
<?php
if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"]))
return false; // serve the requested resource as-is.
else {
Expand Down

0 comments on commit d7d0d19

Please sign in to comment.