Skip to content

Commit bdc0d78

Browse files
committed
Merge branch '6.4' into 7.0
* 6.4: [DependencyInjection] add `#[AutowireLocator]` attribute [HttpFoundation] Fix base URI detection on IIS with UrlRewriteModule
2 parents 75d116a + d05a040 commit bdc0d78

File tree

2 files changed

+83
-3
lines changed

2 files changed

+83
-3
lines changed

Request.php

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ class Request
190190
self::HEADER_X_FORWARDED_PREFIX => 'X_FORWARDED_PREFIX',
191191
];
192192

193+
/** @var bool */
194+
private $isIisRewrite = false;
195+
193196
/**
194197
* @param array $query The GET parameters
195198
* @param array $request The POST parameters
@@ -1657,11 +1660,10 @@ protected function prepareRequestUri(): string
16571660
{
16581661
$requestUri = '';
16591662

1660-
if ('1' == $this->server->get('IIS_WasUrlRewritten') && '' != $this->server->get('UNENCODED_URL')) {
1663+
if ($this->isIisRewrite() && '' != $this->server->get('UNENCODED_URL')) {
16611664
// IIS7 with URL Rewrite: make sure we get the unencoded URL (double slash problem)
16621665
$requestUri = $this->server->get('UNENCODED_URL');
16631666
$this->server->remove('UNENCODED_URL');
1664-
$this->server->remove('IIS_WasUrlRewritten');
16651667
} elseif ($this->server->has('REQUEST_URI')) {
16661668
$requestUri = $this->server->get('REQUEST_URI');
16671669

@@ -1858,7 +1860,13 @@ private function setPhpDefaultLocale(string $locale): void
18581860
*/
18591861
private function getUrlencodedPrefix(string $string, string $prefix): ?string
18601862
{
1861-
if (!str_starts_with(rawurldecode($string), $prefix)) {
1863+
if ($this->isIisRewrite()) {
1864+
// ISS with UrlRewriteModule might report SCRIPT_NAME/PHP_SELF with wrong case
1865+
// see https://github.com/php/php-src/issues/11981
1866+
if (0 !== stripos(rawurldecode($string), $prefix)) {
1867+
return null;
1868+
}
1869+
} elseif (!str_starts_with(rawurldecode($string), $prefix)) {
18621870
return null;
18631871
}
18641872

@@ -1987,4 +1995,20 @@ private function normalizeAndFilterClientIps(array $clientIps, string $ip): arra
19871995
// Now the IP chain contains only untrusted proxies and the client IP
19881996
return $clientIps ? array_reverse($clientIps) : [$firstTrustedIp];
19891997
}
1998+
1999+
/**
2000+
* Is this IIS with UrlRewriteModule?
2001+
*
2002+
* This method consumes, caches and removed the IIS_WasUrlRewritten env var,
2003+
* so we don't inherit it to sub-requests.
2004+
*/
2005+
private function isIisRewrite(): bool
2006+
{
2007+
if (1 === $this->server->getInt('IIS_WasUrlRewritten')) {
2008+
$this->isIisRewrite = true;
2009+
$this->server->remove('IIS_WasUrlRewritten');
2010+
}
2011+
2012+
return $this->isIisRewrite;
2013+
}
19902014
}

Tests/RequestTest.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,6 +1867,62 @@ public static function getBaseUrlData()
18671867
];
18681868
}
18691869

1870+
/**
1871+
* @dataProvider baseUriDetectionOnIisWithRewriteData
1872+
*/
1873+
public function testBaseUriDetectionOnIisWithRewrite(array $server, string $expectedBaseUrl, string $expectedPathInfo)
1874+
{
1875+
$request = new Request([], [], [], [], [], $server);
1876+
1877+
self::assertSame($expectedBaseUrl, $request->getBaseUrl());
1878+
self::assertSame($expectedPathInfo, $request->getPathInfo());
1879+
}
1880+
1881+
public static function baseUriDetectionOnIisWithRewriteData(): \Generator
1882+
{
1883+
yield 'No rewrite' => [
1884+
[
1885+
'PATH_INFO' => '/foo/bar',
1886+
'PHP_SELF' => '/routingtest/index.php/foo/bar',
1887+
'REQUEST_URI' => '/routingtest/index.php/foo/bar',
1888+
'SCRIPT_FILENAME' => 'C:/Users/derrabus/Projects/routing-test/public/index.php',
1889+
'SCRIPT_NAME' => '/routingtest/index.php',
1890+
],
1891+
'/routingtest/index.php',
1892+
'/foo/bar',
1893+
];
1894+
1895+
yield 'Rewrite with correct case' => [
1896+
[
1897+
'IIS_WasUrlRewritten' => '1',
1898+
'PATH_INFO' => '/foo/bar',
1899+
'PHP_SELF' => '/routingtest/index.php/foo/bar',
1900+
'REQUEST_URI' => '/routingtest/foo/bar',
1901+
'SCRIPT_FILENAME' => 'C:/Users/derrabus/Projects/routing-test/public/index.php',
1902+
'SCRIPT_NAME' => '/routingtest/index.php',
1903+
'UNENCODED_URL' => '/routingtest/foo/bar',
1904+
],
1905+
'/routingtest',
1906+
'/foo/bar',
1907+
];
1908+
1909+
// ISS with UrlRewriteModule might report SCRIPT_NAME/PHP_SELF with wrong case
1910+
// see https://github.com/php/php-src/issues/11981
1911+
yield 'Rewrite with case mismatch' => [
1912+
[
1913+
'IIS_WasUrlRewritten' => '1',
1914+
'PATH_INFO' => '/foo/bar',
1915+
'PHP_SELF' => '/routingtest/index.php/foo/bar',
1916+
'REQUEST_URI' => '/RoutingTest/foo/bar',
1917+
'SCRIPT_FILENAME' => 'C:/Users/derrabus/Projects/routing-test/public/index.php',
1918+
'SCRIPT_NAME' => '/routingtest/index.php',
1919+
'UNENCODED_URL' => '/RoutingTest/foo/bar',
1920+
],
1921+
'/RoutingTest',
1922+
'/foo/bar',
1923+
];
1924+
}
1925+
18701926
/**
18711927
* @dataProvider urlencodedStringPrefixData
18721928
*/

0 commit comments

Comments
 (0)