Fix issue in Router with paths beginning with multiple slashes
This commit is contained in:
parent
a15b5396e9
commit
2c80da2f79
|
|
@ -78,22 +78,21 @@ class Router implements MiddlewareInterface
|
||||||
ResponseInterface $response,
|
ResponseInterface $response,
|
||||||
$next
|
$next
|
||||||
): ResponseInterface {
|
): ResponseInterface {
|
||||||
// Use only the path for routing.
|
$path = $this->getPath($request->getRequestTarget());
|
||||||
$requestTarget = parse_url($request->getRequestTarget(), PHP_URL_PATH);
|
|
||||||
|
|
||||||
$route = $this->getStaticRoute($requestTarget);
|
$route = $this->getStaticRoute($path);
|
||||||
if ($route) {
|
if ($route) {
|
||||||
return $this->dispatch($route, $request, $response, $next);
|
return $this->dispatch($route, $request, $response, $next);
|
||||||
}
|
}
|
||||||
|
|
||||||
$route = $this->getPrefixRoute($requestTarget);
|
$route = $this->getPrefixRoute($path);
|
||||||
if ($route) {
|
if ($route) {
|
||||||
return $this->dispatch($route, $request, $response, $next);
|
return $this->dispatch($route, $request, $response, $next);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try each of the routes.
|
// Try each of the routes.
|
||||||
foreach ($this->patternRoutes as $route) {
|
foreach ($this->patternRoutes as $route) {
|
||||||
if ($route->matchesRequestTarget($requestTarget)) {
|
if ($route->matchesRequestTarget($path)) {
|
||||||
$pathVariables = $route->getPathVariables();
|
$pathVariables = $route->getPathVariables();
|
||||||
if ($this->pathVariablesAttributeName) {
|
if ($this->pathVariablesAttributeName) {
|
||||||
$request = $request->withAttribute($this->pathVariablesAttributeName, $pathVariables);
|
$request = $request->withAttribute($this->pathVariablesAttributeName, $pathVariables);
|
||||||
|
|
@ -113,6 +112,15 @@ class Router implements MiddlewareInterface
|
||||||
return $next($request, $response);
|
return $next($request, $response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getPath(string $requestTarget): string
|
||||||
|
{
|
||||||
|
$queryStart = strpos($requestTarget, '?');
|
||||||
|
if ($queryStart === false) {
|
||||||
|
return $requestTarget;
|
||||||
|
}
|
||||||
|
return substr($requestTarget, 0, $queryStart);
|
||||||
|
}
|
||||||
|
|
||||||
private function dispatch(
|
private function dispatch(
|
||||||
callable $route,
|
callable $route,
|
||||||
ServerRequestInterface $request,
|
ServerRequestInterface $request,
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,8 @@ class RouterTest extends TestCase
|
||||||
|
|
||||||
public function testMatchesPathAgainstRouteWithoutQuery(): void
|
public function testMatchesPathAgainstRouteWithoutQuery(): void
|
||||||
{
|
{
|
||||||
$target = '/my/path?cat=molly&dog=bear';
|
$path = '/my/path';
|
||||||
|
$target = $path . '?cat=molly&dog=bear';
|
||||||
|
|
||||||
$this->request = $this->request->withRequestTarget($target);
|
$this->request = $this->request->withRequestTarget($target);
|
||||||
|
|
||||||
|
|
@ -299,11 +300,28 @@ class RouterTest extends TestCase
|
||||||
$this->route->getType()->willReturn(Route::TYPE_PATTERN);
|
$this->route->getType()->willReturn(Route::TYPE_PATTERN);
|
||||||
$this->route->matchesRequestTarget(Argument::cetera())->willReturn(true);
|
$this->route->matchesRequestTarget(Argument::cetera())->willReturn(true);
|
||||||
|
|
||||||
$this->router->register('GET', $target, 'middleware');
|
$this->router->register('GET', $path, 'middleware');
|
||||||
|
|
||||||
$this->dispatch();
|
$this->dispatch();
|
||||||
|
|
||||||
$this->route->matchesRequestTarget('/my/path')->shouldHaveBeenCalled();
|
$this->route->matchesRequestTarget($path)->shouldHaveBeenCalled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMatchesPathWithDuplicateLeadingSlashes(): void
|
||||||
|
{
|
||||||
|
$path = '//my/path';
|
||||||
|
|
||||||
|
$this->request = $this->request->withRequestTarget($path);
|
||||||
|
|
||||||
|
$this->route->getTarget()->willReturn($path);
|
||||||
|
$this->route->getType()->willReturn(Route::TYPE_PATTERN);
|
||||||
|
$this->route->matchesRequestTarget(Argument::cetera())->willReturn(true);
|
||||||
|
|
||||||
|
$this->router->register('GET', $path, 'middleware');
|
||||||
|
|
||||||
|
$this->dispatch();
|
||||||
|
|
||||||
|
$this->route->matchesRequestTarget($path)->shouldHaveBeenCalled();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue