diff --git a/src/Router.php b/src/Router.php index f5aca1f..2244402 100644 --- a/src/Router.php +++ b/src/Router.php @@ -75,7 +75,7 @@ public function handleRequest(Request $request): Response $method = $request->getMethod(); - $path = \str_ireplace('%2F', '%252F', $request->getUri()->getPath()); + $path = \str_ireplace('%2F', '%252F', $request->getUri()->getPath(), $replaceCount); $path = \rawurldecode($path); $toMatch = "{$method}\0{$path}"; @@ -92,6 +92,11 @@ public function handleRequest(Request $request): Response * @var array $routeArgs */ [, $requestHandler, $routeArgs] = $match; + + if ($replaceCount > 0) { + $routeArgs = \array_map(fn (string $arg) => \str_replace('%2F', '/', $arg), $routeArgs); + } + $request->setAttribute(self::class, $routeArgs); return $requestHandler->handleRequest($request); diff --git a/test/RouterTest.php b/test/RouterTest.php index 26b2142..9c453d2 100644 --- a/test/RouterTest.php +++ b/test/RouterTest.php @@ -209,16 +209,19 @@ public function testMerge(): void public function testPathIsMatchedDecoded(): void { - $requestHandler = new ClosureRequestHandler(function () { + $requestHandler = new ClosureRequestHandler(function (Request $request) { + $routeArgs = $request->getAttribute(Router::class); + self::assertSame(['p1' => 'ba/Ω', 'p2' => '/?'], $routeArgs); + return new Response(HttpStatus::OK); }); $router = new Router($this->server, $this->testLogger, $this->errorHandler); - $router->addRoute("GET", "/fo+%2Fö bar", $requestHandler); + $router->addRoute("GET", "/fo+%2Fö bar/{p1}/{p2}", $requestHandler); $this->server->start($router, $this->errorHandler); - $uri = "/fo+%2F" . \rawurlencode("ö ") . 'bar'; + $uri = "/fo+" . \rawurlencode("/ö ") . 'bar/ba' . \rawurlencode('/Ω') . '/' . \rawurlencode('/?'); $request = new Request($this->createMock(Client::class), "GET", Uri\Http::createFromString($uri)); $response = $router->handleRequest($request);