Skip to content

Commit 1a7fa93

Browse files
bug symfony#57917 [HttpKernel] [WebProfileBundle] Fix Routing panel for URLs with a colon (akeylimepie)
This PR was squashed before being merged into the 5.4 branch. Discussion ---------- [HttpKernel] [WebProfileBundle] Fix Routing panel for URLs with a colon | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | see below | License | MIT According to [docs](https://www.php.net/manual/en/function.parse-url.php) the `parse_url` function may not produce the expected result for **relative** URLs. In particular, the function produces incorrect results for a relative URL with a port-like string in any part, such as: ```php parse_url('/foo/bar:123/baz'); // false ``` But such a URL is valid. So if there is a controller with this route for it, Symfony will correctly match it: ```php <?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; class HelloController extends AbstractController { #[Route('/foo/bar:123/baz')] public function world() { return new Response(); } } ``` <img width="1208" alt="match" src="https://github.com/user-attachments/assets/e45fbf13-891e-4373-9e28-5068480e6877"> ---- ### Bug But in the profiler, opening the Routing panel will not work; instead of the panel, we see an exception: <img width="1208" alt="fail" src="https://github.com/user-attachments/assets/c101db2c-dc86-4c39-8598-ac9533bd3725"> This is because `Symfony\Bundle\WebProfilerBundle\Controller::getTraces` method creates a new `Request` from relative path info. And `Request::create` since 6.3 symfony#49376 throws an exception if `parse_url` returns `false`, which is the case here: https://github.com/symfony/symfony/blob/6d6dd4a93abb2c4d724e0bdb3ab89a22dd3062ac/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php#L83 Prior to version 6.3, the routing panel is displayed, but there are no router matches on it. This is why version 5.4 is also affected. ---- ### Solution So instead of a relative path, I suggest using an absolute URI, which is handled by `parse_url` correctly: <img width="1208" alt="success" src="https://github.com/user-attachments/assets/99842b7f-da64-42d8-907f-7856ca7d1c3a"> Commits ------- 079c8df [HttpKernel] [WebProfileBundle] Fix Routing panel for URLs with a colon
2 parents e6337fd + 079c8df commit 1a7fa93

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,10 @@ public function panelAction(string $token): Response
8383
*/
8484
private function getTraces(RequestDataCollector $request, string $method): array
8585
{
86-
$traceRequest = Request::create(
87-
$request->getPathInfo(),
88-
$request->getRequestServer(true)->get('REQUEST_METHOD'),
89-
\in_array($request->getMethod(), ['DELETE', 'PATCH', 'POST', 'PUT'], true) ? $request->getRequestRequest()->all() : $request->getRequestQuery()->all(),
86+
$traceRequest = new Request(
87+
$request->getRequestQuery()->all(),
88+
$request->getRequestRequest()->all(),
89+
$request->getRequestAttributes()->all(),
9090
$request->getRequestCookies(true)->all(),
9191
[],
9292
$request->getRequestServer(true)->all()
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\WebProfilerBundle\Tests\Controller;
13+
14+
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
15+
use Symfony\Bundle\FrameworkBundle\Routing\Router;
16+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
17+
use Symfony\Bundle\WebProfilerBundle\Tests\Functional\WebProfilerBundleKernel;
18+
use Symfony\Component\DomCrawler\Crawler;
19+
use Symfony\Component\Routing\Route;
20+
21+
class RouterControllerTest extends WebTestCase
22+
{
23+
public function testFalseNegativeTrace()
24+
{
25+
$path = '/foo/bar:123/baz';
26+
27+
$kernel = new WebProfilerBundleKernel();
28+
$client = new KernelBrowser($kernel);
29+
$client->disableReboot();
30+
$client->getKernel()->boot();
31+
32+
/** @var Router $router */
33+
$router = $client->getContainer()->get('router');
34+
$router->getRouteCollection()->add('route1', new Route($path));
35+
36+
$client->request('GET', $path);
37+
38+
$crawler = $client->request('GET', '/_profiler/latest?panel=router&type=request');
39+
40+
$matchedRouteCell = $crawler
41+
->filter('#router-logs .status-success td')
42+
->reduce(function (Crawler $td) use ($path): bool {
43+
return $td->text() === $path;
44+
});
45+
46+
$this->assertSame(1, $matchedRouteCell->count());
47+
}
48+
}

0 commit comments

Comments
 (0)