Skip to content

fix: codeigniter in a subdirectory + indexPage results in 404 #9607

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 15 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
36 changes: 34 additions & 2 deletions system/HTTP/SiteURIFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,40 @@
*/
private function parseRequestURI(): string
{
$appConfig = $this->appConfig;
$baseUrl = $appConfig->baseURL;
$indexPage = $appConfig->indexPage;
$baseUri = false;
$parsedUrl = parse_url($baseUrl);

if (isset($parsedUrl['path'])) { // The path could be empty if the url is just a domain
$baseUri = $parsedUrl['path'];
}
if ($baseUri) {
$baseUriArray = explode('/', $baseUri);
$baseUriArray = array_filter($baseUriArray); // We remove the empty strings from the array
$baseUri = implode('/', $baseUriArray); // We join the array back into a string with slashes
if ($baseUri !== '') {
$baseUri = '/' . $baseUri; // We add a slash at the beginning of the base Uri as implode will not do that
} else {
$baseUri = false;
}
}

$serverRequestUri = $this->superglobals->server('REQUEST_URI'); // We get the request URI from the server superglobals

if (null !== $serverRequestUri) {
if ($baseUri && str_starts_with($serverRequestUri, $baseUri)) {
$serverRequestUri = substr($serverRequestUri, strlen($baseUri));
} // We remove the base Uri from the request URI if it exists, baseUri is the path to the subdirectory
if ($indexPage !== false && str_starts_with($serverRequestUri, '/' . $indexPage)) {

Check failure on line 140 in system/HTTP/SiteURIFactory.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis

Strict comparison using !== between string and false will always evaluate to true.
$serverRequestUri = substr($serverRequestUri, strlen('/' . $indexPage));
} // We remove the index page from the request URI if it exists
$serverRequestUri = '/' . ltrim($serverRequestUri, '/'); // makes sure that the uri starts with a slash
}

if (
$this->superglobals->server('REQUEST_URI') === null
$serverRequestUri === null
|| $this->superglobals->server('SCRIPT_NAME') === null
) {
return '';
Expand All @@ -122,7 +154,7 @@
// string contains a colon followed by a number. So we attach a dummy
// host since REQUEST_URI does not include the host. This allows us to
// parse out the query string and path.
$parts = parse_url('http://dummy' . $this->superglobals->server('REQUEST_URI'));
$parts = parse_url('http://dummy' . $serverRequestUri);
$query = $parts['query'] ?? '';
$path = $parts['path'] ?? '';

Expand Down
49 changes: 49 additions & 0 deletions tests/system/HTTP/SiteURIFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,53 @@
],
];
}

#[DataProvider('provideCreateFromStringWithIndexPageSubDirCombinations')]
public function testCreateFromStringWithIndexPageSubDirCombinations(
string $subDir,
string $indexPage,
): void {
$standardUrl = 'http://localhost:8080';
$standardScriptName = '/public/index.php';

$route = 'controller/method';
$appConfig = new App();
$appConfig->baseURL = $standardUrl . $subDir;
$appConfig->indexPage = $indexPage;

$_SERVER['PATH_INFO'] = '/' . $route;

Check failure on line 188 in tests/system/HTTP/SiteURIFactoryTest.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis

Assigning '/controller/method' directly on offset 'PATH_INFO' of $_SERVER is discouraged.
$_SERVER['REQUEST_URI'] = $subDir . '/' . $indexPage . $_SERVER['PATH_INFO'];

Check failure on line 189 in tests/system/HTTP/SiteURIFactoryTest.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis

Assigning non-falsy-string directly on offset 'REQUEST_URI' of $_SERVER is discouraged.

Check failure on line 189 in tests/system/HTTP/SiteURIFactoryTest.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis

Accessing offset 'PATH_INFO' directly on $_SERVER is discouraged.
$_SERVER['SCRIPT_NAME'] = $subDir . $standardScriptName;

Check failure on line 190 in tests/system/HTTP/SiteURIFactoryTest.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis

Assigning non-falsy-string directly on offset 'SCRIPT_NAME' of $_SERVER is discouraged.
$_SERVER['HTTP_HOST'] = $standardUrl;

Check failure on line 191 in tests/system/HTTP/SiteURIFactoryTest.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis

Assigning 'http://localhost:8080' directly on offset 'HTTP_HOST' of $_SERVER is discouraged.

$factory = $this->createSiteURIFactory($appConfig);
$detectedRoutePath = $factory->detectRoutePath();
$this->assertSame($route, $detectedRoutePath);
}

public static function provideCreateFromStringWithIndexPageSubDirCombinations(): iterable

Check failure on line 198 in tests/system/HTTP/SiteURIFactoryTest.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis

Method CodeIgniter\HTTP\SiteURIFactoryTest::provideCreateFromStringWithIndexPageSubDirCombinations() return type has no value type specified in iterable type iterable.
{
return [
'no subdir and no index' => [
'',
'',
],
'no subdir and index' => [
'',
'index.php',
],
'subdir and no index' => [
'/subdir',
'',
],
'subdir and index' => [
'/subdir',
'index.php',
],
'subdir 2 levels deep string and index' => [
'/subdir/subsubdir',
'index.php',
],
];
}
}
Loading