diff --git a/core/lib/Drupal/Core/Routing/RouteCompiler.php b/core/lib/Drupal/Core/Routing/RouteCompiler.php index 639feff..50627c4 100644 --- a/core/lib/Drupal/Core/Routing/RouteCompiler.php +++ b/core/lib/Drupal/Core/Routing/RouteCompiler.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Routing; +use Drupal\Component\Utility\Unicode; use Symfony\Component\Routing\RouteCompilerInterface; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCompiler as SymfonyRouteCompiler; @@ -67,7 +68,8 @@ public static function compile(Route $route) { * Returns the pattern outline. * * The pattern outline is the path pattern but normalized so that all - * placeholders are equal strings and default values are removed. + * placeholders are equal strings and default values are removed, and the path + * is converted to lowercase. * * @param string $path * The path for which we want the normalized outline. @@ -76,7 +78,7 @@ public static function compile(Route $route) { * The path pattern outline. */ public static function getPatternOutline($path) { - return preg_replace('#\{\w+\}#', '%', $path); + return Unicode::strtolower(preg_replace('#\{\w+\}#', '%', $path)); } /** diff --git a/core/lib/Drupal/Core/Routing/RouteProvider.php b/core/lib/Drupal/Core/Routing/RouteProvider.php index 937cff7..a8dc186 100644 --- a/core/lib/Drupal/Core/Routing/RouteProvider.php +++ b/core/lib/Drupal/Core/Routing/RouteProvider.php @@ -10,6 +10,7 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\CacheTagsInvalidatorInterface; +use Drupal\Component\Utility\Unicode; use Drupal\Core\Path\CurrentPathStack; use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Drupal\Core\State\StateInterface; @@ -147,7 +148,9 @@ public function __construct(Connection $connection, StateInterface $state, Curre */ public function getRouteCollectionForRequest(Request $request) { // Cache both the system path as well as route parameters and matching - // routes. + // routes. We can not yet convert the path to lowercase since wildcard path + // portions may be case sensitive if they contain data like a base64 encoded + // token. $cid = 'route:' . $request->getPathInfo() . ':' . $request->getQueryString(); if ($cached = $this->cache->get($cid)) { $this->currentPath->setPath($cached->data['path'], $request); @@ -155,14 +158,14 @@ public function getRouteCollectionForRequest(Request $request) { return $cached->data['routes']; } else { - // Just trim on the right side. $path = $request->getPathInfo(); - $path = $path === '/' ? $path : rtrim($request->getPathInfo(), '/'); + // Just trim path on the right side. + $path = $path === '/' ? $path : rtrim($path, '/'); $path = $this->pathProcessor->processInbound($path, $request); $this->currentPath->setPath($path, $request); // Incoming path processors may also set query parameters. $query_parameters = $request->query->all(); - $routes = $this->getRoutesByPath(rtrim($path, '/')); + $routes = $this->getRoutesByPath($path); $cache_value = [ 'path' => $path, 'query' => $query_parameters, @@ -317,15 +320,17 @@ public function getRoutesByPattern($pattern) { * Get all routes which match a certain pattern. * * @param string $path - * The route pattern to search for (contains % as placeholders). + * The route pattern to search for. * * @return \Symfony\Component\Routing\RouteCollection * Returns a route collection of matching routes. */ protected function getRoutesByPath($path) { // Split the path up on the slashes, ignoring multiple slashes in a row - // or leading or trailing slashes. - $parts = preg_split('@/+@', $path, NULL, PREG_SPLIT_NO_EMPTY); + // or leading or trailing slashes. Convert to lower case here so we can + // have a case insensitive match from the incoming path to the pattern + // outlines from \Drupal\Core\Routing\RouteCompiler::getPatternOutline() + $parts = preg_split('@/+@', Unicode::strtolower($path), NULL, PREG_SPLIT_NO_EMPTY); $collection = new RouteCollection();